Ok, so I’ve posted my initial feelings about tinkering with Mercurial and Git, and that seems to have generated some interest. It’s time to get a bit more formal about how I’m going to evaluate them against each other, to decide which one I like to use most in real, practical scenarios. So, I decided to come up with a list of use cases for the things that I typically have to deal with when managing the repositories for a software project (open source and otherwise), so that I can methodically test them out and see how I feel about each system. I’ve tried to deliberately include use cases for things that you can’treally do on a centralised system, but that I’d want to make use of, as well as the usual nonsense that happens day-to-day on a typical project ๐
I’ve presented my work-in-progress list below, feel free to suggest more use cases I can test. I really want to see what these things are like in practice in the kinds of situations I encounter in real projects, without actually risking a real project in the process! Like a backup / restore strategy, it’s no good doing it for the first time when the sh*t has already hit the fan.
Oh, and for fun, allegedly Git is MacGyver and Mercurial is James Bond . ๐
This list will be periodically updated as I think of new things, and as other things are suggested by commenters.
Due to the nature of a DVCS, all these use cases must be tested both in isolation, andย after pushing those changes to another potentially ‘superset’ repository.
- General
- Commit a few changes to local repository ‘A’ but don’t push to central yet. Push a number of different changes to the central repository from a different repository ‘B’. Then, pull ‘B’s changes from the central repos to local repository ‘A’ย to bring it up to date, again without pushing A’s outstanding changes yet. This is equivalent to doing an ‘svn update’ while you have local uncommitted changes in Subversion, but while using the local commit features of the DVCS. How does this work in practice? [Suggested by Arseny Kapoulkine]
- Branching
- Create a new public, official branch (stable branch)
- Create a new long-term feature branch which is intended for public consumption / collaboration
- Create lots of short-term development branches (or equivalent structures) intended for local consumption only
- What are the size overheads? (Git claims superiority here)
- Does this excessively clutter the public repository when pushed?
- Is there a better way of handling multiple local changesets which you may or may not decide to push individually, such as testing many patches (Mercurial queues seem very interesting, Git equivalent?)
- . Rename a branch? (optional)
- Merging
- Merge changes unidirectionally from one branch to another, without having to manually pick revisions. Make more changes in the source branch and repeat.
- Bidirectional merge - a feature branch which is not yet ready to be merged into the trunk wants to resynchronise from the trunk and continue branched development. Merge of this branch into the trunk must be tested later after further changes
- Tagging
- Create a tag against a specific branch; probably at the HEAD but look for the option to specify a revision
- Correct / modify / move a tag following a mistake or last-minute revision (pre-release) without having to make duplicate commits or other such spurious activity
- Firefighting
- Screw-up: developer commits change to trunk instead of stable branch. Merge / move it to the stable instead - change can be left in the trunk or can be removed for re-merging, so long as the procedure is clear.
- Screw-up: developer commits change to stable branch that is interface-breaking, must be removed and moved to the trunk. Must be removed from the stable branch and moved.
- Screw-up: Revert a single change from the repository, that is not at the HEAD
- External patch submission tests:
- Patch file from same branch, no conflicts
- Patch file from same branch, with conflicts
- Patch file generated on a different branch to the one we want to apply it to (include conflicts)
- Pull from third-party repository, entire branch
- Pull from third-party respository, specific changes
- Patch file generated from non-repository source copy
- Backup multiple work-in-progress changes on a local machine that are not ready for public consumption; approaches:
- Store a patch per local branch (this is how it’s done with SVN, but too much hassle if you use lightweight local branching, DVCSs can do better)
- Push to a backup repository on another machine across existing protocols - ssh, https, Samba share (Git can’t do the latter?)
- Push to a backup respository on a USB stick (Git can’t do this?)
- Binary files
- Revise a binary file over a few versions, test storage efficiency
- Binary file conflict resolution
- Conversion from Subversion
- Import retaining history
- Import multiple branches
- Import tags
- Integration
- Mailing list / RSS notifications of commits on official repository
- Bugtrackers
- CIA.vc et al?
- Good free & open source GUI clients for all platforms
- Line ending conversions between platforms