Version Control Wish

A lot of smart people have thought much harder than I have about version control systems, and I am by no means an expert on them. That said, this is what I want from a VCS, beyond the obvious: I want to be able to name a patch. I want to be able to easily transfer that patch from one branch to another. I want to be able to add chunks to the patch, and modify existing chunks. If I earlier transferred the patch to another branch, I want to be able to easily move the modifications I made.

Clearly there is a sense in which a patch is a branch. But it isn’t a branch in the usual sense. I may have several active patches which live on my development branch. When I update my development branch–sync it to the master sources, or in general to other repositories–I want my patches to update also. When I want to move a patch to a release branch, I want the VCS to roll the patch back to the current merge point of the development branch and the release branch, and to apply that modified patch to the release branch.

For example, let’s say that patch P was started on the development branch at version Rd. Let’s say that release branch B was branched off of the development branch at version Rb. I do some work on P, and then I update the development branch to version Re, and then I do some more work on P. Now I’m happy with patch P and I want to put it on the release branch. I want the VCS to get P out of the development branch. I want it to reverse apply the diffs from Re back to Rb. I want it to take the resulting diff and apply it to the release branch.

Then i want to work on patch P some more, and then move it over to the release branch again. Now I want the VCS to pick up the changes since I last moved it over and only apply those changes–after, of course, removing any changes I dragged in from other people.

I want P to have a name, not a revision number, and I want these operations to be simple VCS commands, not complicated scripts.

Naturally merge conflicts are possible at several different stages here, and the final output may have to include several different bits of source code for each conflict. Or perhaps the VCS could ask me what to do as it goes along, that would be OK.

These are the sorts of operations I find myself doing fairly regularly. Obviously I can do them with any VCS, by using manual bookkeeping and attention to detail. I have yet to find any VCS which makes them simple.


  1. rskrishnan said,

    July 24, 2008 @ 10:12 pm

    Nice summary of “what I want from a VCS” !! Now if some of the vcs vendors would read, and more importantly _take this to heart_ life would be much better.

    I’m yet to see a VCS that will move a patch backwards that is on Re –> Rd (i.e. “backporting” a patch). Neither git, nor perforce, and surely never ClearCase seem to be able to deal with this sort of request well (specially if the delta between Rd and Re is non-trivial). With ClearCase ranking high on the “yuck” factor.
    I like git mostly for it’s speed and “everything is local” mentality – makes disconnected operation much more pleasant.

  2. Ian Lance Taylor said,

    July 25, 2008 @ 6:43 am

    The two systems I’ve been hearing recommendations for are git and Mercurial.

  3. adis said,

    July 25, 2008 @ 7:20 pm

    Maybe you can (ab)use Mercurial Queues for some of your wishes? With some proper commit hygiene, backporting patches should be fairly easy as well.

    Darcs “Theory of patches” is also an interesting read:

  4. ncm said,

    July 26, 2008 @ 1:11 am

    You might get what you want from Monotone — particularly if you provide patches yourself. Civility and rigor seem more characteristic of that project than some others, under Nathaniel Smith’s leadership.

  5. Ian Lance Taylor said,

    July 28, 2008 @ 10:07 pm

    adis: As far as I can tell, Mercurial Queues are quilt for Mercurial. That’s useful, but it’s not what I’m after. That requires me to do a lot of the bookkeeping myself.

    ncm: I am skeptical that monotone can handle the gcc repository efficiently. I’d be happy to hear otherwise.

  6. Spudd86 said,

    April 12, 2009 @ 7:41 am

    You could try using git in the following way:

    for each patch you have a branch.

    forward porting a patch to your head can then be done like this (if your working copy has no uncommited changes)
    git checkout
    git rebase

    and git cherrypick is exactly transferring changesets from one branch to another

    there is also a way to add chunks from your working copy interactivly (that is you can choose which bits of the diff commit)

    so if you write some shell scripts you could make git do pretty much everything you describe by itself (and without them you can do it by hand)

    git pull will only change the one branch… but you can then rebase all your patch branches onto master to update them (assuming you pulled into master)

    git rebase also has an interactive mode where you can muck about with the patches as they are re-applyed, (change order, drop some, I think you may be able split them up as well)

    So for example if you wanted to automatically pull and rebase all your patch branches you could write a shell script to do that (possibly you follow some sort of naming convention your patch branches so the script can determine which they are automatically, something like -patch-)

  7. Ian Lance Taylor said,

    July 14, 2009 @ 4:09 pm

    Thanks for the note. I’m not quite convinced that this is making it simple. I am able to do what I want using any modern VCS. What I’m looking for is something that makes it simple. Ideally I want to have several patches which live together, but which I can manipulate independently. And do git rebase or git cherrypick really do the right thing for moving a patch from the development branch to a release branch?

RSS feed for comments on this post · TrackBack URI

You must be logged in to post a comment.