Subversion and Mercurial in the Corporate Environment ----------------------------------------------------- Subversion is also named as SVN; Mercurial is also named as HG. Environment =========== It is supposed that corporate environment has some properties which do not depend on Version Control System deployed. This section describes these properties. A (Central Repository) There exists the Central Repository (CR) -- the repository, where the code is kept. This repository is accessible via user-friendly web-interface and via VCS-specific tools. A task can't be considered as "complete" until the Central Repository gets the full implementation (and documentation) of the task. There may exist other, non-central repositories -- but nobody should be forced to look into them. For every task, the Central Repository should keep enough information to work with. B (hooks) The Central Repository should be able to execute some hooks when data is put into it. The hooks may include bugtracker-related actions, sending mails, etc. C (lock) It should be possible to lock a file in the Central Repository, and all changes of the file should be prohibited while the file is locked. D (must-lock) It should be possible to set up the Central Repository in such a way, that some files can't be changed without lock. E (mirror) It should be possible to easily get a copy of the Central Repository, to avoid any network access when travelling abroad, while still getting access to the full history. F (properties) It is useful to attach some properties to files, and make hooks acting differently depending on certain values of the properties. G (branches) It should be possible to keep multiple branches within one repository. H (ActiveDirectory) It should be possible to use auth tokens from AD to authenticate to the CR. I (bisect) It should be possible to bi-sect the repository and find the guilty revision. J (merge) There should be convinient support for merging between branches. SVN vs HG ========= A (Central Repository) It is the native mode for Subversion; it is one of the allowed modes for Mercurial. B (hooks) Exist for both. With HG, hooks which verify the real data (or the logmessage content) and may veto the changeset, have a number of problems: - such hooks are very unstable. See 10.3 in the Mercurial Book for details. - user must manually synchronize his hooks with the "standard" ones, because it is hard to handle changesets vetoed by CR which are already committed into local repo. C (lock) Native for SVN; may be implemented for HG. D (must-lock) Native for SVN; impossible for HG, because all repositories are really independent. E (mirror) Native for HG. May be implemented for SVN via svnsync. Note: in SVN1.4, there are some issues with svnsync (see, for example, http://subversion.tigris.org/issues/show_bug.cgi?id=3229), but I hope that svn 1.5 does not have these issues. F (properties) Native for SVN, do not exist for HG. G (branches) Native for SVN, less convenient (but possible) for HG. H (ActiveDirectory) As server in both cases can work via Apache, there are no problems on server-side. SVN client is able to send AD auth out-of box; HG can't. However, it should not be very hard to fix HG (or, more precisely, to fix python liburl which is used from HG). I (bisect) HG has a native tool "bisect". For SVN, you can just go through revisions or use svn-bisect tool. J (merge) SVN1.5 and HG are OK. Common Workflows ================ Simple: SVN: update from CR - modify - commit HG: update from CR - modify - commit to local repo - push to CR Merge/conflict: SVN: update from CR - modify - try to commit, but your version is old - update - resolve conflicts - verify - commit HG: update from CR - modify - commit to local repo - try to push to CR, but your version is old - pull from CR - merge/resolve conflicts - verify - commit to local repo - push to CR "version is old" means: SVN: there were changes in the files _you_ modified HG: there were changes in this branch of _repository_ Server-side hook declining user changes: SVN: update from CR - modify - try to commit, but server refuses to accept because of some hooks - fix the problem - commit HG: update from CR - modify - commit to local repo - try to push to CR, but server refuses to accept because of some hooks - backout your local commit - fix the problem - commit to local repo - push to CR (and if refused changeset is not the last, you have additional problems). Caveats & Etc ============= Both SVN & HG have problems with "unix users may commit something, which will break windows users", because on windows "file.txt" and "File.txt" are the same file. With Mercurial, it is easy to "lose" some changes: - open a bug in the bugtracker - do some changes, commit them into local repository - push the changes into CR, fixing the bug in the bugtracker. HG warns: abort: push creates new remote heads! (did you forget to merge? use push -f to force) but user forces push instead of doing pull/merge. - as a result, the bugfix is in the CR, bugtracker knows that and thinks that the bug is fixed. However, the fix is in a separate "branch", not in the main code. With Mercurial, I've found following problem: - merge the changes A - merge the changes B - find that changeset A was incomplete, and merge changes A1. Now, I need a tag with A+A1 changes (without B). I've failed to create such a branch. Well, I can do it manaully (branch from A and manually apply A1), but merge functionaliry in mercurial does not help.