Distributed version-control systems
We're considering switching from Subversion to a DVCS. This page contains our needs, wants, and aversions, and analysis of how each DVCS responds to them.
Also listed here, for the purpose of comparison, is Subversion (with svnmerge.py), the VCS we're using now. Unlike the others listed here, Subversion is a CVCS (centralized version-control system), not a DVCS.
Specification
Needs
- Revision control
- Branches (all DVCSs have cheap branching: just clone the repo)
- Easy merging (no manual change-tracking)
- Simple UI
- Trac integration
- Support for centralized model (One Repo to Rule Them All, from which releases will be built)
- Diffing of binary files (in repositories)
- Diffing of binary files (in patches)
- Support for commit emails (specifically or via a post-commit hook)
- Symbolic links (for frameworks)
- Strong Unicode-fu (especially UTF-8 and UTF-16)
Wants
- Low initial-pull overhead (see Pidgin/Monotone's "download a sqlite db then run pull" issue)
- Fast
- User-friendly (i.e., Adium-developer-friendly) revision identifiers
- Good way to share patches including changes to binary files
- In Yum or some other update system
- Easy to install/reinstall
Aversions
- User-unfriendly revision identifiers (e.g., SHA-1 hashes)
Summary comparison
A better understanding of where we have come from and where we need to be is required here. In order to do that, we need to compare things we have previously used to the newer systems. The following table should help with this task:
| Requirement | CVS | SVN 1.4 | SVN 1.5 | SVN+svnmerge.py | bzr | mercurial | monotone | git | darcs | sv |
| Easy branching | - | x | x | x | x (DVCS) | x (DVCS) | x (DVCS) | x (DVCS) | x (DVCS) | ? |
| Merge tracking | - | - | ? | x | x | x | x | ? | ? | ? |
| Only requires commit bit (no shell) for commit | x | x | x | x | - | x | x | ? | ? | x |
| Post Commit Hook | ? | x | x | x | x | x | x | ? | ? | x |
| Human readable revisions (not MD5 style or SHA-1 style | x | x | x | ? | x | ? | ? | - | ? | ? |
Competitors
Please keep the subsections in alphabetical order.
Bazaar
- Branching: It's a DVCS
- Simple UI: Completely SVN-workalike, except where absolutely necessary
- Patch sharing: bzr send (sends the patch via email)
- Does this include binaries?
- Easily fast enough
- Trac integration: commit command has a --fixes switch that lets you specify a Trac ticket
- Trac plugin available. a public trac using it, another
- Handy tutorial and background
- User-friendly revision identifiers: Monotonic (SVN-style) and dotted (CVS-style) revision numbers
Darcs
- Branching: It's a DVCS
- Easy merging
- Hard merging: Conflict Misery under certain circumstances (reportedly fixed in 2.0 betas)
- Patch sharing: darcs send (sends the patch via email)
- Interactive commit (record) command
- Patches are syntax-highlighted when darcs writes them directly to the terminal
- No diffing of binary files (in repositories): It simply records the entire old file and the entire new file
- No diffing of binary files (in patches): darcs whatsnew simply says “binary file.png”; I don't know what a patch bundle from darcs send would show
- User-friendly revision identifiers: Patch names are user-specified
- However, darcs has weak UTF-8-fu (as of 1.0.9), so characters such as smart quotes get displayed as hex escape sequences. I don't know whether this is only a display problem, or has deeper UI ramifications. —boredzo
- No symbolic links
- Utterly fails at Unicode: Any non-ASCII characters, including those in UTF-8 sequences, get displayed as hex escape sequences in darcs whatsnew output
Git
- Branching: It's a DVCS
- Very fast
- Repositories are quite small (roughly 1.35kB/revision according to http://git.or.cz/gitwiki/GitBenchmarks)
- User-unfriendly revision identifiers (SHA-1 hashes)
- Diffing of binary files (in patches): Git-style diffs can record this information, AFAIK.
- Maybe diffing of binary files (in repositories): ?
- Push-access to repo without a shell account: No, but yes; see git-shell(1)
- Patch management (Guilt)
Mercurial
- Branching: It's a DVCS
- Optimized on-disk repo format reduces disk seeks and improves speed
- Diffing of binary files (in patches): Mercurial supports printing git-style diffs which show this information.
- Doesn't version directories, according to Dave Dribin
- Does this matter? The way we use Subversion, we really only version directories for the svn:ignore property which must be set on every single nib. In hg, we'd set a glob to ignore those files in .hgignore and be done with it. We don't ever store empty directories, and if we wanted to, just do this: touch empty_dir/.bogon ; hg add empty_dir/.bogon ; hg ci; -- durin42
- Patch management (mq)
- Interactive commit (record) plugin based on the darcs command of the same name.
Monotone
- Branching: It's a DVCS
- High initial-pull overhead: Users must download a huge database file first
- It's what Pidgin uses, currently
- User-unfriendly revision identifiers (SHA-1 hashes)
- Committers' public keys cannot have duplicate email addresses, or Monotone throws a fit
- Also means that you can't reuse your email address on a new public key
- Trac integration
- The monotone post-commit hook lets our current "fixes #XXX", "refs #XXX" coments in commit notices work as expected.
- ViewMTN does provide a commit timeline, though it's separate, and allows browsing. The current Pidgin setup doesn't have complete integration.
- A Trac plugin to provide "full" Monotone integration exists (tracmtn). We don't have any experience with it, however.
Subversion + svnmerge.py
- Centralized model
- Branching: Not first-class; copy the /trunk directory to a subdirectory of /branches
- Hard merging: Manual change tracking
- sv could make this easier
- Trac integration: Trac was built for it
- Simple UI: svn is the most svn-like of the VCSs
- User-friendly revision identifiers: Monotonically-increasing integer for the entire repo (including branches and tags)
- No diffing binary files (in patches)
- Weak Unicode-fu
- Commit emails contain octal escape sequences for UTF-8 sequences.
- UTF-8 also gets miscommunicated to Trac (we may have fixed this, but it definitely did not work OOTB).
- svn does not realize that when a previously-existing file has the svn:charset property applied to it, its contents were probably in that charset all along, even though nobody told svn (this affects svn diff output, for example).
sv
- Makes merging easier
- However, it's merely additional commands for svn; it's not a new VCS