Subversion is a gateway drug (to darcs) (tummy.com, ltd. Journal Entry)
tummy.com: we do linux

Monday January 02, 2006 at 18:04
Subject: Subversion is a gateway drug (to darcs)
Keywords: Subversion, Technical
Posted by: Sean Reifschneider

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.
(Post Reply)

Comment
Martin v. Loewis
Subject: What's wrong with "svn merge"?
You don't mention "svn merge" when trying to integrate changes into a branch.

After creating branches/ssize_t, I do

  cd ssize_t
  svn merge -r41942:41964 svn+ssh://pythondev@svn.python.org/python/trunk

and that merges me all changes between these two revisions into the trunk.

Now, where do I get the numbers from? The right number is simply the current repository revision. The left number is the number of the previous branch.

You could find that number in the commit message, or you can store it in a property. Before committing the merge result, I do

  svn pe py:lastmerged .

and replace 41942 with 41964. Then, before the next merge, I do

  svn pg py:lastmerged .

to find out when the last merge was, and use that as the starting revision for the merge.

Comment
Author: Sean Reifschneider
Subject: That's a pretty good trick.
I had originally tried that just by saving a file that contained the last revision I had merged from. Later I thought about storing that information in the repository so that multiple people would have access to it, that would be doable as well. Your trick looks pretty good, I think that should work. I'll have to give it a try. The darcs method I'm using now works pretty well, but is potentially of a similar number of steps as tracking the merge-points in SVN. Sean
Comment
Joakim Harsman
Subject: darcs can break horribly
You should be aware that darcs can get into certain cases where it will take exponential time trying to solve conflicts, and theres no good way to solve this once it happens other than tedious manual work.

This can happen fairly easily if you have a stable branch and an unstable branch for some large feature, and a patch you're trying to pull from stable conflicts with changes you've made in unstable. See http://darcs.net/DarcsWiki/ConflictMisery

I would really love to use darcs since it's so easy to use and elegant, but it just isn't stable enough yet.

Comment
Dave Newton
Subject: Another SVN merge trick
Another SVN merge trick that I use for large bug fixes or code changes:

svn copy -m "foo" svn://.../trunk svn://.../branches/big-bugfix/trunk
svn copy -m "bar" svn://.../branches/big-bugfix/PRE
# Do lots of hairy work until you're done
svn copy -m "baz" svn://.../branches/big-bugfix/POST

Now go in to your trunk directory and:

svn merge -R PRE:POST svn://.../branches/big-bugfix/trunk

So in essence you're tagging the branch before and after you've worked on it and can refer to things symbolically.

That said, I like the previous poster's property trick and am going to have to look at that to see if I like it more--it looks like I might.

You are still left with the problem of merging changes from trunk (or anywhere else) into your branches; since I am very liberal with my branches I will need to look in to this. DARCS is definitely catching on in many communities I hang out in, so I'll be checking it out.

Dave

Comment
Author: Sean Reifschneider
Subject: Yeah, I've had problems also.
My big project that required the features of Darcs for branching management has had problems. I ended up with a repository that I couldn't push or pull from. It would just hang, I let it run for up to 8 hours. I had contacted #darcs on freenode, and also looked at the wiki, but couldn't get it resolved.

I finally just gave up and went back to svn with svnmerge, and that's been working well for me. Though just last night I found a change in one branch that was missing from a branch I would have merged it from. Not sure what the story is there.

I'm playing around with git right now, but haven't had much opportunity to actually use it, particularly use it hard.

Sean