What Mother never told you about SVN Branching and Merging

Developers are fond of recounting their disastrous experiences branching and merging in Subversion and CVS.

Yet, thousands upon thousands of teams use SVN. Are they just not branching? What’s going on?

The Usage Model That Will Kill You
Commonly, you create a branch from trunk (at revision 100 for example), and then make a bunch of changes. Meanwhile, the rest of the team makes changes to trunk while you work in your branch. Then, you realize that while you’re not done with your branch yet, you need to get those trunk changes into your branch.

So you merge from trunk into your branch. You do this by taking all the changes in trunk that happened after revision 100 and applying them to your branch. Often, it seems to work. In reality, you are already pretty screwed at this point, you just don’t realize it.

For a couple weeks, maybe, you merge from trunk into your branch. A couple times.

Then comes your trip over the falls in a barrel. You are happy with your branch; you want to commit it to trunk and let the rest of your team in on your brilliance. You do this by taking the changes from your branch and merging them into trunk. This almost never works. All your tree is marked as changed, or files disappear, or changes are scrambled. Conflicts are marked where none should exists, and other changes are just gone.

You cry, you weep, you descend into alcohol and drug use, you watch old Star Trek reruns. You curse SVN forever.

Invariably people around you say “use GIT”; “use Mercurial”; “use Arch”; whatever. Go for it.

But why, oh why, does SVN (and CVS) fail to work? “This should work!” — I’ve heard that from so many developers so many times!

Why doesn’t it work?
Now, I am not going to go through the details as to why it doesn’t work, but there is a simple reason it doesn’t work: time. More specifically, order of changes.

The first time you pull from trunk to your branch, you copy a set of changes. Then second time you do it, depending on how attendant you are to start revisions, you may copy those changes again — this is slightly problematical.

The killer is when you then merge all the changes from you branch to trunk — not only do these include a bunch of changes already made from trunk, your time line is now screwy. Changes that occurred in the past to trunk are now showing up again in the merge, and SVN (and CVS) get very confused. Why? Look at the picture:

SVN Branch Merge Example 1 - Red for Trunk, Cyan for Branch.

SVN Branch Merger Example 1

For this example, assume this shows the sequence of changes to a single file in your repository. T0, T1, T3, and T4 indicate points in time at which your file is edited. That is also the order in which the modifications took place. This is important to SVN (and CVS). Why? Let’s look at what happens when you get to T5 and want to merge your changes into trunk: The sequence looks like: T1 (already was in trunk, and was reapplied to the branch), T0 (from the merge at T2), T4 (because it was already in trunk), then T3. So the order the merge tries to resolve is T1, T0, T4, T3. But it is more awkward than that, because T0 and T4 are already committed to trunk, really it looks like you are applying T0, T4, T1, T3. Or maybe, just T1, T3. But since changes are in terms of the previous state of the file being changed, T3’s modifications knew nothing about T4’s modifications, so you are applying modifications out of order, and things go boom.

Multiply this by a hundred files with hundreds of changes each both in trunk and your branch, and you have a recipe for disaster.

(Oh and file and directory deletions and additions are particularly damaging in this scenario.)

Now, this is an empirical explanation — there was a time where I walked through CVS diff logs to see what was going on but that was ten years ago. But through testing, I know this is reasonable model of SVN’s behavior when it comes to branching and merging. Lacking time to grok all of SVN’s source code, an empirical model is good enough for me to know working this way won’t work.

Bunny Hopping
So what is the solution? A deceptively simple rule shows the way:

All changes that are going to be committed to Trunk, must be applied to all changes already committed to Trunk, before those changes are merged into Trunk.

Hmmm. What does that mean? In the example above, it means that the changes at T1 and T3, even though they took place before the trunk change T4, need to be applied after T4.

How to do that? The secret is Bunny Hopping.

Consider this example:

SVN Branching with Bunny Hops

SVN Branching with Bunny Hops

What’s going on here? First of all, instead of one branch, we have three. You may have twenty. Branching in SVN is fast enough not to care (in CVS though, ouch). Let’s look at the temporal sequence again:

  1. You branch.
  2. Someone else changed T0 on trunk. Sequence in trunk: T0
  3. You make the change T1 on your first branch. Sequence in Branch: T1
  4. You create a new branch from trunk at T2; it contains change T0. Then you merge your changes from your prior branch (the yellow arc — a Bunny Hop) into your new branch. This brings change T1 into your second branch after change T0. Sequence in your branch: T0, T1
  5. You make change T3 in your branch. Sequence in your second branch: T0, T1, T3
  6. Someone else makes change T4 in trunk. They committed to trunk first; they win. Sequence in trunk T0, T4
  7. You make your third branch, at time T5. It includes changes T0, T4 in that order. You merge all your changes from the previous branch — this means you have to do the merging necessary to make changes T1 and T3 blend in correctly after T0, T4. But you get to do this in a workspace, off of a branch, nicely isolated from trunk. It is usually pretty easy. Sequence in the branch is now T0, T4, T1, T3
  8. With no other overlapping changes between when you cut this branch and now (between T5 and T6), you merge your branch into trunk. Because all of the changes in this branch take place after the already committed changes in trunk, the merge goes smoothly.

When I am working, I number these sub-branches; if I am working on caching, I’ll end up with caching-1, caching-2, caching-3, etc. until I finish working on caching. It works well, mainly because branches are low-overhead, low-cost objects in SVN.

This methodology was discovered by a colleague of mine (Go Steve!) who grew so frustrated with our team’s inability to work productively in branches that he (and several of us) spent time in play repositories just trying different things. That was pre-IDE for me; we used Emacs and men were men.

We eventually evolved a neat little Python tool to manage the bunny hopping automatically for us — that was really cool. I’ve often wished I had the time to write a Subversive extension to do the same thing in Eclipse. But even manually, it is so ingrained in me as a work habit that I barely notice I do it. And I branch and merge, successfully, all the time.


Bunny hopping. What Mother never told you about Branching and Merging.

Explore posts in the same categories: Tech

Tags: , , ,

You can comment below, or link to this permanent URL from your own site.

67 Comments on “What Mother never told you about SVN Branching and Merging”


  1. Hello Chris,
    Thank you for sharing your knowledge about this topic. I think all of us are running some day into the troubles you described in the article above. Hopefully with your solution this won’t happen again!

    Daniel

    • designbygravity Says:

      It’s astonishing how many devs use SVN but won’t use branching because of the problems of merging. Really big fail for SVN/CVS.

      • ElectroLund Says:

        +1! Count me as one of those devs! I’m botched so many merges because of cryptic error messages that I find myself manually merging as best I can outside of SVN, thereby subverting the whole point of the revision control system. Bork.


  2. Hy Chris,
    It’s me again. We were discussing internally in our team your article. The question that came up is the following: Couldn’t this merging problem be solved by reintegrating all changes on the trunk for example every day into your branch? Then your branch to trunk delta would never be that big and you wouldn’t fail merging…

    Daniel

    • Fernando Says:

      Hi,
      Recently in my team has started working the way Daniel says. We merge from trunk every week to our branch. We’ve did several tries and seems to work relative well.
      When we want to merge to trunk from a branch, always do before a merge from trunk.
      Anyone else work this way?

      Fernando

    • designbygravity Says:

      You could try and do that, but you aren’t solving the problem, just making it less likely to happen. If you have co-mingled changes between branch and trunk, you can still end up in deep water.

      Frequent merges from trunk to your branch helps ameliorate the problem, but won’t complete solve it — it will depend on how rapid trunk changes if you get away with it and how long/involved your branch changes are.

    • Starr Says:

      A prvtvcaoioe insight! Just what we need!


    • comentou em 28 de julho de 2010 às 20:45. Na verdade não gosto de passar o dia montada. ntão desmonto sem dó. Meu cabelo sempre cresceu muito. Mas segundo minha médica tem muito a ver com uma alimentação bem variada e equilibrada.BJsss!!!

  3. Rajneesh Says:

    This is a very sound practice and is very common where clearcase is being used. It is generally used in conjunction with bug management tool to coordinate creation of branch for each bug or issue

  4. Woody Folsom Says:

    I had to read this article twice before I ‘got it’ because I always assumed this was how SVN was supposed to be used! However, I don’t like the idea of having each developer track changes to trunk and create a series of sequential branches. Instead, I find that the simplest way to use SVN is:

    1) Each dev makes changes in his or her personal branch – NEVER in trunk – however, the reason for this is not relevant to this topic.

    2) Before merging changes to trunk, a dev MUST merge from trunk into his or her personal branch. However, only the holder of the Monster Drink, beer bottle or other semaphore/token object of your choice may merge in the other direction, from branch into trunk.

    3) If you don’t hold a lock on the token, then you must get it from the current holder before you can merge your changes.

    This strategy ensures that every dev gets the other coders’ changes in the correct order and is allowed to commit his or her changes prior to anyone else clobbering trunk again. Development velocity is limited only by the rate at which programmers can resolve conflicts and pass the lock object.


  5. Great article!
    I am interested in the Python bunny hopping utility you evolved. Can you give any more details?

    • designbygravity Says:

      Sadly, ‘fid’ or ‘fib’ (I have no idea what the name meant) is long gone. It was integrates with the bug tracking, so you could do ‘fib new 123 fix problem in code’ to create a branch, ‘fib co 123’ to check it out, ‘fib synch’ to bunny hop and merge, and ‘fib publish’ to push the branch to trunk. It was sweet.


  6. […] What Mother never told you about SVN Branching and Merging […]

  7. Pablo Lima Says:

    I adopted this same approach some time ago, when I realized that the secret to avoid it is never let the branch gets old. But never thought of such a smart name 🙂

  8. alberlau Says:

    I want to ask about Example 1. What if you merge from trunk to branch after change T4, right before merging from branch to trunk?

  9. Jaran Nilsen Says:

    Great article! Hope you write a follow-up if the python script should ever emerge 🙂

  10. Mark Harris Says:

    Thank you for the article. Unfortunately, my mother would be hopelessly confused by section three of this well-formed, but somewhat misguided rant.

    She’s well aware, you see, that SVN 1.5 includes automatic merge tracking. An example of a typical months workflow for her follows:

    Week 1: Branch created at r90
    Week 2: Trunk merged into branch at r100.
    Week 3: Trunk merged into branch at r107. SVN notices from the file that r90-r100 have already been merged in, so only merges r101-r107 into the branch.
    Week 4: Finished in the branch. Merge r108-r120 into the branch, then merge the branch back into the trunk.

    Simple.

    Further details can be found in the SVN book’s chapter on merging (http://svnbook.red-bean.com/en/1.5/svn.branchmerge.basicmerging.html#svn.branchemerge.basicmerging.stayinsync). She would recommend taking the time to read the book to get the most this powerful, but complicated tool.

    In the dark days before 1.5, she found a manual system (similar to what SVN now does automatically) involving entering the revision set numbers in the commit message for the merge worked passingly well. Though she didn’t come up with a cool name like “Bunny Hopping” for it. 🙂

  11. sedwards Says:

    Thanks for the shout-out (“fib” was a Tcl/Expect script, by the way, not Python).

    However, after recently examining this issue again for a client, I think it is based not on a real problem with the tool itself, but on a very common misconception that we had with the pre-1.5 versions of Subversion.

    We tend to think of merging (say, branch to trunk) as a process in which SVN applies each of the revisions in our branch, one at a time in sequence, to the trunk. While sometimes a convenient mental model, this is not how it actually works.

    In your first example, the implication is that when you perform your merge to trunk, you are doing it like so:

    “Apply all branch changes in order to current trunk.”

    But that isn’t what happens. Yes, it’s the way we think of it. In our heads, this means: take all the changes in “mybranch” that occurred between “start” and “now” and apply them sequentially to “trunk.” But we’re wrong about that.

    What SVN actually does is to literally “diff” the contents of “mybranch@now” with the contents of “mybranch@start.” Meaning, it ignores everything that might have happened on the branch between “start” and “now.” It only compares the two static states, as if they were one big file. It then takes those resulting differences and applies them to the trunk.

    Yes, in our usage model, this is totally broken, because that “diff” is going to include changes that were already made on the trunk. But that’s our fault, not Subversion’s. So what to do?

    If you think in terms of “diff” and not “applying revisions,” the answer is clear:

    (mybranch@now – trunk) –> trunk

    Meaning, compute the differences between “mybranch” as it stands right now and “trunk”, then push those changes into “trunk.”

    Since the intermediate revisions are ignored (actually, that’s not quite true, but assume it’s true for now), it doesn’t matter when, for example, T0 and T1 actually made it into the branch. Subversion will see, when it does the compare between your branch and trunk, that the T0 changes appear in both, so it won’t show up in the diff. Hence, it won’t try to apply those changes again to trunk. Problem solved.

    Why the confusion? I blame both the documentation and the “svn” command syntax. Even though the authors talk about not supporting proper “changesets,” it was difficult to see the implications of this without having used an SCM tool that did have them. In fact, the docs do talk about the use of intermediate revisions during a merge. But they are only used to figure out whether two files with the same name actually refer to the same thing, and whether they need to be taken into account when doing the diff.

    This whole discussion may now be moot, however. I’ve been using git recently (client-driven decision) so I haven’t been keeping up, but see that Subversion is now up to 1.6, which includes proper support for changesets. So it’s possible that things now work in a less surprising way. I think it’s time to “re-learn” Subversion before closing the book on this.

    Note that the preceding discussion totally sidesteps any mention of the “librarian/gatekeeper” functionality of the “fib” script; that merits its own post… 🙂

    • designbygravity Says:

      It’s true that it works that way (after 1.5 SVN), but the *clients* don’t really present it that way. I recently ran a test with 1.5 SVN and Subversive via Eclipse, and I could easily get it to decide that a file was *completely* different, because of co-mingled changes in the same file out of order.

      Now, the visual merge stuff is not, strictly speaking, SVN. Rather, it is an Eclipse/Subversive creation (Eclipse does the same for CVS in synchronize). And you have god’s own time getting it to respond well to branches which have been merged back and forth with trunk, with competing changes.

      Classic bunny hopping has not failed yet.

      Much as I am interested in git, the eclipse tools are not there yet. Sadly.

  12. Ray Says:

    Interestingly enough if you just apply times the order of the changes would have been correct: T0, T1, T3, and T4.

  13. digitaljoel Says:

    I believe if you follow the branching/merging guidelines in the svn redbook you will MOSTLY be in the clear, especially in the case you specify in this post.

    The workflow should be that you create your branch. Every so often (daily, weekly, depends on the volatility of your trunk), you merge from the trunk to your branch. This keeps you in sync with all changes in the trunk, and if you do it often enough each merge will be relatively painless. As you make changes to your branch you commit them to your branch. Everything should be committed to the branch before you try to merge from trunk to branch.

    When your work is finally done and you are ready to move your changes into the trunk you do one more merge from trunk to branch. This ensures you are up to date with the current trunk and have already taken care of any conflicts in your merge, and done so in your own little sandbox (the branch.) Finally, you perform the merge from branch to trunk. Make sure you use the –reintegrate flag on the merge. This will essentially get you what sedwards is referring to ((mybranch@now – trunk) –> trunk) and those changes that were merged from the trunk into your branch will be handled properly without looking like changes to the trunk again.

    Here is a link to the redbook section that talks about –reintegrate
    http://svnbook.red-bean.com/en/1.5/svn-book.html#svn.branchemerge.basicmerging.stayinsync

    The method of merging from trunk into your branch occasionally basically does what you are talking about with your bunny hopping, but without creating extra branches where a single branch should suffice.

    That said, I can’t claim that all of my merges have gone without a hitch, but I _believe_ (not 100% verified) that each issue has been with people that have previously not merged correctly and then messed up the svn:mergeinfo property. I’ve had to learn more about svn merging than I should in order to use it, but I think bunny hopping would only compound the issue, not solve it.

  14. Andreas Krey Says:

    No, the merges as indicated in the first picture only don’t work when you a) use cvs, b) use svn pre-1.5, or c) you have an actual conflict between changes. (Or have bugs in svn, which is not that improbable.)

    The main reason is: Once you have the latest changes from the trunk merged into the branch, the backmerge into the trunk must result exactly in the current state of the branch (since all changes are there already), and you have resolved all conflicts already.

    Small further (nonconflicting) changes should affect the backmerge either. But because the VCS needs to know about all the merges and not only the branch point to do this, cvs and svn<1.5 can't do this because they don't record the merge arrows.

    However (and what I expected) in svn once you merged the branch back into the trunk, the mergeinfo is also garbled beyond recognition and the branch has become unusable. (Read about –reintegrate.) This is what I expected to be mentioned here.

    (And why the hell does one need eclipse integration for git? Just because you never want to see a command line or another gui tool?)

    • designbygravity Says:

      But: “or you have an actual conflict between changes” happens all the time. At least on our codebase with 7 developers.

      Against SVN 1.5 and Eclipse/Subversive.

      Feel free to deride the gui, but I am used to, and comfortable with, the integrated visual synchronize in Eclipse.

      • Andreas Krey Says:

        Unfortunately the ‘actual conflicts’ will be there no matter what your VCS can do; this is a matter of communication between team members not to hammer on the same thing at the same time too hard.

        The ‘bunny hopping’ is just a way to cope with VCSes that have no proper merge tracking; VCSes that do automatically do the same.

        I do actually use eclipse and find it near being addictive; anyway I’d rather use a good VCS without eclipse integration than an integrated but broken one.


  15. […] What Mother never told you about SVN Branching and Merging « Design By Gravity a few seconds ago from bti […]

  16. orip Says:

    Nice article, but the solutions I went for are much different:

    In Subversion 1.4 and under, svnmerge.py (http://www.orcaware.com/svn/wiki/Svnmerge.py) handles the case of branches tracking other branches very well

    In Subersion 1.5 and above, svn itself does that.

    Before those 2 solutions, it was a pain.

  17. Gaurav Says:

    I wish you had written this 2 months ago when I was banging my head on the wall. SVN acting the way it did makes a lot more sense now. Thanks for the clear explanation.

    • designbygravity Says:

      Thanks for the kind words. The range of responses here was interesting; some folks clearly never encounter merge madness, while others just give up on SVN. To each his own!

  18. sedwards Says:

    OK, it’s official: we are old and behind the times. Since Subversion 1.5, this whole problem is moot. The changeset feature essentially duplicates the functionality of our “fib” script (which, by they way might just be in the source tree of the newly open-sourced Forge).

    When working in your branch, you can just repeatedly issue

    svn merge ^/trunk

    And this will correctly pull into your branch anything from trunk that you are missing. It keeps track of what you have already merged (in a property, ala fib) so you don’t get duplicates.

    Then in a trunk working copy, you can merge your branch with

    svn merge --reintegrate ^/branches/my-branch

    and that does all the dirty work on that end. See ch. 4 of the latest SVN book for details.

    So there is no longer any reason to keep feeding the bunny.

    • designbygravity Says:

      Yeah, with SVN 1.5+ it works pretty well. We just moved to 1.5 about 6 months ago and it is much better, working most of the time, although I have seen sporadic screwups. ‘reintegrate’ was what was missing all along.

      On the other hand, I still interact with SVN 1.4 servers pretty regularly, and people do use CVS, so…


  19. […] What Mother never told you about SVN Branching and Merging […]

  20. Ian Lim Says:

    Great article. Will try to share with my teams and just as a reminder for them 🙂


  21. […] seen a lot of confusion about this last step. What your not trying to do is merge each of your feature work changesets into […]

  22. arisoft31 Says:

    This is a very sound practice and is very common where clearcase is being used. It is generally used in conjunction with bug management tool to coordinate creation of branch for each bug or issue

  23. onaclov Says:

    For some reason the images aren’t showing up for me, I would really like to see the visualizations of the bunny hopping and whatnot.

    I’m really new with SVN and am just learning it, I am familiar with the IBM Rational toolset, but there are some differences so far.

    Thank you,
    onaclov
    (tyson)

    • designbygravity Says:

      I’d be happy to email them to you; feel free to email me.

      I have no idea why you can’t see them — everywhere I’ve tested seems to be fine.

  24. Eduardo Says:

    Thanks a lot.

    Now I know what has really happened in that screwed up merge!

  25. Alex Conrad Says:

    Don’t do bunny-hopping if you use svn >= 1.5. You can follow this model, it just works:

    – svn cp http://…/trunk http://…/branches/mybranch
    – svn switch http://…/branches/mybranch
    – svn commit, svn commit, svn commit (work on branch)
    – svn merge http://…/trunk (stay in sync w/ trunk)
    – svn commit -m “merge trunk”
    – svn commit, svn commit, svn commit (work on branch)
    – svn merge http://…/trunk (stay in sync w/ trunk)
    – svn commit -m “merge trunk”
    – svn commit, svn commit, svn commit (work on branch)
    – svn merge http://…/trunk (prepare branch merge to trunk)
    – svn commit -m “merge trunk”
    – svn switch http://…/trunk
    – svn merge –reintegrate http://…/branches/mybranch

    All should go smoothly when merging the branch back down to trunk.


  26. […] assumption (the one with the serious implications) is that the complex, elaborate and grotesque workaround procedures necessary with CVS or Subversion to get serious work done – don’t exist because their […]

  27. rolfen Says:

    Isn’t that a case for cherry-picking? Look it up, SVN can do it and it should solve this problem.

  28. The problem is far more simple than you realise Says:

    I think I found the real problem and a much neater solution.

    “Meanwhile, the rest of the team makes changes to trunk while you work in your branch.”

    Your team are cretins, educate them.

    Trunk is stable release, all work in per project or per developer branches, test cases to prove the work before merging said branch into trunk (which only 1 person should have permissions to do).

    • stingyjack Says:

      Eh, have to disagree with you there. ‘Trunk’ is going to be whatever it is supposed to be in that environment. Most non-simple branch patterns will have the trunk being the main unstable development branch (there may be other dev branches). Branches that are then taken off of that to actually build the release-able packages. Those branches represent the deployed code and get fixes, etc applied to them.

  29. salvin18 Says:

    This is a really amazing tutorial, I am glad i stumbled across this…

  30. bz Says:

    what version of the svn server are you using? I believe this was fixed in 1.6. The add merge info. To see the list of change sets that have been applied to you branch

    svn propget svn:mergeinfo myBranch


  31. […] What Mother never told you about SVN Branching and Merging « Design By Gravity – May 8th ( tags: svn subversion branches branching merging tips tricks tutorial guide bunny hopping versioncontrol ) May 10th, 2012, @ 10:00 am | Tags: links | Category: delicious links | Comments are closed | Trackback this Post | 0 views […]

  32. foo Says:

    Best… article… ever!

    Thank you so much.

  33. Lokesh Says:

    Hi,

    Thanks for this great article. I am new to SVN and have couple of questions for you.

    1. Can we add more files to an existing tag?
    2. Can we modify a file which is tagged?

    One more question on Branching. My project has a dev and a trunk branches. When a project is being released it is merged from dev to trunk and the trunk is freezed and no new changes are suppose to happen. This creates unnecessary waiting period for other projects which are ready to be merged to trunk.

    We need to reduce the freeze period in the trunk so that it does not effect other projects in pipeline.

    Could you please suggest me a good branching and merging strategy to reduce the freeze period in the trunk?

    I will be waiting for you reply.

    Thanks,
    Lokesh

  34. Sebastien Says:

    PLEASE DO NOT DO WHAT IS RECOMMENDED.

    This is not how it supposed to work !

    This is completely obsolete. If you are using subversion I believe 1.6 and for sure 1.7. the mergeinfo property tracks all the required info.

    To avoid issue, you need to merge the changes from the the trunk to your branch before re-merging back to the trunk. That way svn knows the history of changes.

    I use TortoiseSVN so I am not quite sure of the underlying command .
    But here is the workflow

    1) Create a branch from trunk
    … looping trough 2 & 3
    2) Make some changes and a few commits
    3) Merge change from the trunk
    … when done with your changes
    4) Last merge from trunk to your branch
    5) commit branch
    6) merge your changes to the trunk
    7) commit trunk

    You will not get any issues as described in the article.

    • Andreas Krey Says:

      I had a remark on this, but wordpress login process forced me to lose it. 😦 [The auto-filling of the name/email fields also sucks.]

      Anyway, svn is broken wrt to merges, and not just in the repeated-merges case. Any rename/edit in different branches is bound to get one in trouble.

      • Sebastien Says:

        There are actually quite a few comments that are saying this does not apply anymore.

        Please provide me with an example that would fail. I can always get the merging to work on subversion 1.7 as expected even when renaming files.

        Thanks.

        • Andreas Krey Says:

          It’s ‘rename a file that is modified in another branch’:

          repo=`pwd`/tmp
          rm -rf tmp wt wb
          svnadmin create tmp
          svn mkdir file://$repo/t -m trnk
          svn checkout file://$repo/t wt
          cd wt
          date >A
          svn add A
          svn commit -m ‘add A’
          cd ..
          svn cp file://$repo/t file://$repo/b -m brnch
          svn checkout file://$repo/b wb
          cd wt
          date >>A
          svn commit -m ‘update A’
          cd ..
          cd wb
          svn mv A B
          svn commit -m ‘rename A’
          svn up
          svn merge file://$repo/t
          svn status

          leaves you with a fine

          + svn merge file:///Users/andreaskrey/svn-cc-test/tmp/t
          — Merging r3 through r5 into ‘.’:
          C A
          — Recording mergeinfo for merge of r3 through r5 into ‘.’:
          U .
          Summary of conflicts:
          Tree conflicts: 1
          + svn status
          M .
          ! C A
          > local missing, incoming edit upon merge
          Summary of conflicts:
          Tree conflicts: 1

          (I hope newlines will be preserved.)


  35. Hi there I am so happy I found your blog page, I really found you by error, while I was
    searching on Bing for something else, Regardless I am here now and would just like to
    say cheers for a marvelous post and a all round entertaining blog (I also love
    the theme/design), I don’t have time to browse it all at
    the moment but I have bookmarked it and also added in your
    RSS feeds, so when I have time I will be back to read much more,
    Please do keep up the superb work.

  36. more info Says:

    more info

    What Mother never told you about SVN Branching and Merging | Design By Gravity

  37. Robert Says:

    I struggle understanding the change sequence that you describe:

    “Let’s look at what happens when you get to T5 and want to merge your changes into trunk: The sequence looks like: T1 (already was in trunk, and was reapplied to the branch), T0 (from the merge at T2), T4 (because it was already in trunk), then T3.”

    T1 was never in trunk before T5. So my brain chokes already at the first bracket.

    Then, on the branch changes are T1, T0 (via T2), T3. On trunk changes are T0, T4. I can’t get to match that to the description above.

    And then, of course there is the description that has been shared already: http://svnbook.red-bean.com/en/1.8/svn.branchmerge.basicmerging.html

    Is the whole information in this blog post still current?

    • Como Says:

      Yeah, I also read that part and it doesn’t make any sense to me either.
      I wonder if any of the other guys that commented have even read the post…

  38. excellent Says:

    For one reason or another, I can’t see all of this content, the text keeps hiding? Are you using something crazy?


  39. There’s a new name for the “Bunny Hopping” technique – it’s called GIT Rebase. It’s interesting how old tried’n’proven concepts reemerge after a while under a new name 🙂

  40. Shibichakkaravarthy Ramaiyan Says:

    Hi,

    Instead of bunny hoping, cant we just do a rebase after T4 before merging it to trunk(fig 1) in your actual scenario.

  41. Hugo Says:

    Actually, the correct way how to branch can be found in Subversion book – and some people have already asked about it:

    1. Branch
    2. Develop in your branch
    3. Do a weekly update of your branch from trunk!
    This way you not only get relevant changes from trunk, but also ensure that you are not implementing against a very old version of the software.
    If you need changes more often, do this update more frequently.
    4. Before merging back to trunk, make a final update of your branch from trunk.
    5. Merge back by defining the correct change set using “merge different trees”:
    Merge from: trunk, revision of last update, to: branch, current version.
    This is like your bunny hopping, but only 1 branch is needed and no conflicts will appear when you merge into trunk.

    Of course, if you update your branch from trunk, moved/deleted directories or files always can cause trouble. Large changes of this kind should only be authorized when the time is right (e.g. every developer was able to merge his branches into trunk.), smaller changes of this kind can be resolved by discussing the changes with its author…


Leave a reply to designbygravity Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.