Ian Bicking: the old part of his blog

Branching Practices

Bill de hÓra has a good post on Subversion branching practices.

So here's a Python-specific quandary: how should tagging happen exactly?

Into the buildutils svtag command I've built this process:

It ends up being three commits, which is a little annoying. And, technically, I'm editing a tag, even if it is a very minor edit.

Another issue -- do people have any particular tricks for keeping their checkouts up to date? I just have a shell script that does an svn up for each directory, and another for doing svn stat -u on all my "active" projects. But I don't use the scripts as regularly as I should, nor do I keep the list of active projects up to date. And it's all kind of vague anyway -- I run lots of things from svn checkouts even if I am not necessarily tracking every development on the project.

I'm also curious about tools built on Subversion for handling branches better. One of the commenters points to Subclipse, which uses a property to track tags. But it doesn't seem to describe what exactly it is doing and what that tag means. svk also uses a special property for tracking merges, which is probably better documented. I'm curious how half-heartedly I can use svk (this page isn't actually that helpful) -- can I just use it as a better frontend to Subversion? Will it work okay if other developers aren't using svk?

Indexing of repositories and general tracking also remains relevent, both locally (what do I track?) and globally (what versions of things exist out there?)

Incidentally, I would be very interested to hear how exactly people are using svn (or svk) on their machines. Like, the play-by-play of every non-obvious command they use, script they have, or whatever.

Created 14 Feb '06
Modified 14 Feb '06


A while ago I wrote a entry called Subversion is a gateway drug. In general, my version control needs were fairly modest, and I tried to keep them that way. However, for some recent projects we have 2 to 3 people modifying code, and have the code in a few different versions. I had to do some branching to fold in changes to the stable version while doing development changes as well.

I found that, in general, even with cvs2svn doing the wrong thing with non-text files, it was easier to convert from CVS to SVN and branch, than to branch the CVS. I always ended up running problems with "branch is not a sticy tag" that I couldn't get resolved...

However, once I had branches, I started wanting to use them, and found that merging between branches was quite painful. I really have to have at least two branches, with all changes from one being merged into the other, and sometimes going the other direction when changes are ready. Really I want a tree of branches where changes at a higher level flow down to a lower level. That would be ideal.

I was looking at other systems, and finally with the help of Jeremy Hinegardner and Duncan McGreggor, I switched to darcs, and have been liking it.

Basically, with darcs, you can check out one working tree into another. Each of these is a self-sufficient repository. The repositories can be local or remote. So, I can have a parent repository and then children can "darcs pull" from their parents. I can also cherry-pick patches to push back up-stream. For me, that's a much less frequent thing, so that can be much more difficult. It's keeping the children up with the parents that happens frequently.

I like that I have a full local copy of the repository. It makes doing releases insanely easy and fast, plus I can do commits and tags without needing net access.

However, pushing and pulling from a remote repository can be real slow. Slower than svn at least.

I should try svk at some point. Really all I'd like to see is good branch merging support. I know you can do tricks to follow branches, but those seem like they require remembering much more and are more prone to errors.


# Sean Reifschneider

svk works fine as an svn frontend. You don't even need to use the local mirroring stuff if you don't want to (though it is handy). Merge tracking (via smerge) is a godsend. I've found it's pretty smart about doing the right thing even when the other committers are using straight SVN.

The thing to keep in mind is that it's not a substitue for good repo practices. You still want branches, etc (treating your local mirror like a private branch just isn't a good idea).

I wonder if you could avoid the need to edit tags via clever use of SVN keywords & a little python string transformation?

# Peter Fein

I use svk exactly for that: a better branch merger. I usually keep local mirrors and merge between those (I keep my own branches in my own SVN repositories for upstream stuff, so that I can easily keep local modifications). So svk is a real godsend for any way of forking, even if it is just for your own convenience. Actually I _only_ do the merging and fork-handling in svk, everything else is done with standard svn - that's mostly because svk is dog-slow on my OS X machines.

# hugo

I tried using svk as a front-end to Python's svn repository (as recommended by Fredrik Lundh on his blog), but after bizarre error messages (it's not that often that I see Perl tracebacks) I decided that whilst tools like bazaar are also badly documented, at least they manage to complete operations in the advertised "how to" documents without crashing inexplicably.

Personally, I wish that the developers of "next generation" revision control systems would spend some time writing documentation, rather than leaving it to others to write terse command sequences that "worked for them", or just referring everyone to the tool that inspired the latest effort.

# Paul Boddie

You can reduce this process to two commits (and not have to edit the tag) by including the version bump during the branch copy. Check out a clean version of trunk, modify the version number locally and make your src '.' while doing an svn copy. You'll get a clean commit like this: http://www.hellanzb.com/trac/hellanzb/changeset/551

# Philip Jenvey

Thanks, that would save the need for a checkout of the tag as well.

In theory it should be doable with one commit, but I don't know how to actually do that without having an actual checkout of the tags directory, which is not really feasible.

# Ian Bicking

The technique I've used most is to have a 'make-release' script that takes the repository path or tag, picks the version out of the path or tag, exports the project, inserts the version into the right places (setup.py here), and creates the release tarball and whatnot. I have an older version of the script (my pre-Python days!) with a CVS mini-HOWTO with the whole release process, http://bitsko.slc.ut.us/~ken/make-rel/

# Ken MacLeod

buildutils has several of these features, though I haven't used them all (I use setuptools' PyPI uploading, and don't bother with the announce feature in buildutils either).

I actually want the checkout to be usable -- which means a proper version (which becomes much more important with setuptools and python setup.py develop), so the version fixup has to happen in the repository, not just at build time. There's still versions in the documentation, though. Some of these are unresolveable by any automated process (e.g., NEWS).

Anyway, with buildutils it's a pretty clean release process:

python setup.py svntag --version=0.4.1 --next-version=0.4.2
cd ../Package-0.4.1
python setup.py register
python setup.py sdist upload
# Then the documentation:
python setup.py pudge publish
# Ian Bicking