Subversion (svn) is a truly great replacement for CVS. I've never really been able to get branching to work in CVS, even after reading the documentation on it I have limited success. I know that the Python developers were able to make it do the right thing, but I always seemed to run into problems where CVS just wouldn't let me commit something on a branch I made.
I've found that it's much easier to convert a CVS repository from CVS to Subversion and do a branch in svn, than to deal with branches in CVS. That's the big reason for me to convert from CVS to svn. I lasted a long time without branches because CVS made it so painful. However, now that svn makes branching so easy, I've been using them and have found that there's another significant pain-point that's come up that makes svn branching unusable for me.
I've been switching to darcs over the weekend…
The problem is that there's no really good way to have changes from one branch flow to other branches. I ended up just manually building patches that describe each branch and applying them to the other branches where I'd do another commit. In some simple cases I could just “svn rm” files or directories in the destination and then “svn cp” from the modified branch to the new branch. That requires that the changes to one branch be entirely independent (on a file level) from what is happening on the other branch.
I have two use-cases for branches. One is where I've gone on to do significant development on some code, but have to go back and make an emergency patch to a release. I can't just make the fix to the head, because I have significantly untested code in there. Another way to deal with this is to have a “trunk” and then a “development branch”. This solves the same problem, where experimental or significant changes are done in the “devel” branch, or a branch created for this particular work.
In subversion, this works great if I create a new branch, do the development and complete it, with no changes made to the other branch. You can merge back into the other branch/trunk by just doing “svn rm” and then “svn cp” of the top-level directory of the branch. If changes are made to both, it then becomes problematic to merge them.
I had experimented with saving off a copy of the revision created when I did the branch, and then doing a “svn diff” from that revision to create a patch I could apply to the other tree. However, that doesn't solve the problem of propagating in changes from the other branch. If I change the trunk, I probably want to pull those changes into the development tree ASAP.
Darcs is a distributed version control system, which manages patches between the branches itself. By distributed, I mean that if you do a check out you have a full copy of the archive (unless you are pulling from a “partial” repository). You can make local changes and commit them, without needing commit privileges being granted on the source repository. This can also be done without network connectivity.
When you have changes you want to share with another repository, you can either “push” them to that repository (using SSH, for example), or you can “send” them via e-mail. The latter should be great for for public repositories, because others can pull the repository, work on changes, and then send e-mail that the project maintainer can easily integrate.
On the down side, this does mean that if you are working with a central repository and other developers, a commit will always be a two-step process. First you do “darcs record” which builds a patch of the changes you have made locally. Then you “darcs push” to send patches since the last push. The equivalent of “svn update” is “darcs pull”.
Also note that “darcs push” and “darcs pull” by default will ask you to very every patch that you push or pull, so it can require some thinking. However, this means that “cherry picking” of changes is the default in darcs – you don't have to accept all patches. If you have trusted developers, you can probably always just accept all the patches.
One thing that bugs me about darcs is that it doesn't yell about conflicts. Unless you're paying pretty close attention, reading all the output that a set of “darcs pull” commands generate, it's fairly easy to miss that there are conflicts that need resolution. I would prefer that it yelled about it, preferably surrounded with lines of Nathan Hales around it.
I've been using darcs since Thursday or Friday, and so far it's been working quite nicely. My largest pain-point has been fully resolved. I'll write more about that shortly.comments powered by Disqus