Tagging in SVN

So we decided to use SVN because it’s cooler and more modern. It’s not so bad, especially for webapps. We like the atomic commits, webdav, yadda yadda. You know why it’s better than CVS we aren’t going to regurgitate that to you.

But when deploying we ran into some issues with SVN merge. If you always do updates in a batch and never have an “oh crap update this now” update then you’re fine. But as we all know, stuff happens. So when we have tried to merge the entire tree after merging single files manually we’ve had some interesting results — conflicts in certain places and an overall headache.

The typical way of tagging is using an svn cp and placing a snapshot of a particular trunk revision into the tags directory. This SVN tagging approach using svn merge was supposed to be analogous to our previous way of tagging prod checkouts with CVS.

However, as clouserw put it, “the recommended strategy is only useful when merging the complete trunk to a tag, and when individual revisions/files are involved, svn eats itself”. So to avoid the merge issues with SVN that we found using svn merge we have come up with a new method that uses SVN externals instead.

Both methods have weaknesses. SVN merge has the “eating itself” problem that presents a lot of conflicts and makes merging painful because of all the manual conflict resolution. When merging the entire tree, though, it is desirable because it doesn’t have the weaknesses below. Using SVN externals, you run into some interesting issues but you don’t get the SVN eating itself problem:

  • Any locally modified files not in SVN (even when ignored) will kill a prod update in the event where an external must be updated (you get stuff like “svn: Failed to add directory ‘site/app/tests’: object of the same name already exists”)
  • SVN externals cannot be a single file (they must be a directory so SVN can store info in an explicit .svn directory related to that checkout)

Aside from those two issues, just remembering the trunk revision we want in prod has been working for us. We’d like to find a good middle ground that doesn’t have us taking extra steps to update production when deploying trunk changes to the lives site.

So, if you guys have any input please let us know. We’re always open to suggestions.

Categories: AMO

6 responses

  1. morgamic wrote on :

    *waits for the “use ____ instead” comments*

  2. Rudi Gens wrote on :

    We use SVN for our software development now for quite a while. We created a couple of branches whenever it was necessary and merged things back into the trunk once the branches were tested, approved for release and therefore obsolete.

    From our experience I can only say: Try to merge often. It certainly reduces the number of conflicts you run into. Obviously, new development most often causes less trouble than bug fixes. With time you will get a better feeling how much and what you want to have in one merge.

  3. preed wrote on :

    *waits for the “use ____ instead” comments*

    Here it comes… what exactly do you mean by “SVN eats itself?” You say “So when we have tried to merge the entire tree after merging single files manually we’ve had some interesting results — conflicts in certain places and an overall headache.” Are these conflicts generated by things you’ve already merged, or things you perhaps don’t care about (but are required to merge anyway?)

    The interesting thing is that if I read it correctly, externals are merely labels, but at the directory level. It’s not entirely clear to me that that’s actually what you wanted. It sounds like you want sane merging algorithms when adding to your testing/production tagging directories/areas.

    Am I reading that right, or am I misreading?

  4. morgamic wrote on :

    Yes, I would prefer a sane merging algorithm that did not require me to merge everything in order to be able to painlessly merge a couple of “oh crap” fixes first.

    Say in the instance where I have to push out a config adjustment or a serious bug in a single file, I don’t want to have that single change depending on a whole array of other trunk updates sitting around in the queue — which usually aren’t completely baked yet.

    We ending up doing an svn merge _for that file_ between the trunk revision and the current prod revision. That got our fix in, we updated the site, etc. Later, when trying to merge the rest of the trunk changes onto the prod tag, we ran into issues where 10-12 files were in conflict when a) they had not branched at all b) the revision args in the merge command were correct.

    So something about SVN and its atomic commits might be futzing with how it does merges — I’m not sure — but it didn’t work for us in this case. I suppose we should spend a bit more time retracing our steps — I will try to put together a follow-up post.

  5. preed wrote on :

    So something about SVN and its atomic commits might be futzing with how it does merges — I’m not sure — but it didn’t work for us in this case. I suppose we should spend a bit more time retracing our steps — I will try to put together a follow-up post.

    Yeah, that’d be good to know what causes this state.

    I’m curious to see if there’s another solution to this problem, since externals seem to have some pretty onerous requirements.

    If you can reproduce, you might also take a look at using svnmerge.py to do your merges; the tool tracks some extra metadata properties, and may help address issues like these (it tracks merges in time, so you don’t have to reperform them; I think this may be the problem you’re running into).

    Let me know if can help out.

    — Your friend build engineer 😉

  6. Narty Atomic wrote on :

    The interesting thing is that if I read it correctly, externals are merely labels, but at the directory level. It’s not entirely clear to me that that’s actually what you wanted. It sounds like you want sane merging algorithms when adding to your testing/production tagging directories/areas.