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:
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:
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:
- You branch.
- Someone else changed T0 on trunk. Sequence in trunk: T0
- You make the change T1 on your first branch. Sequence in Branch: T1
- 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
- You make change T3 in your branch. Sequence in your second branch: T0, T1, T3
- Someone else makes change T4 in trunk. They committed to trunk first; they win. Sequence in trunk T0, T4
- 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
- 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.
Tags: CVS, Design By Gravity, Software Development, svn
You can comment below, or link to this permanent URL from your own site.
October 19, 2009 at 3:21 pm
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
October 19, 2009 at 3:29 pm
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.
April 7, 2014 at 11:19 am
+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.
October 20, 2009 at 3:34 am
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
October 20, 2009 at 9:50 am
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
October 20, 2009 at 10:53 pm
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.
March 10, 2017 at 7:26 am
A prvtvcaoioe insight! Just what we need!
August 29, 2017 at 4:13 am
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!!!
October 20, 2009 at 9:07 am
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
October 20, 2009 at 10:02 am
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.
October 20, 2009 at 1:56 pm
Great article!
I am interested in the Python bunny hopping utility you evolved. Can you give any more details?
October 20, 2009 at 10:55 pm
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.
October 21, 2009 at 10:14 am
Thanks anyway!
October 20, 2009 at 4:24 pm
[…] What Mother never told you about SVN Branching and Merging […]
October 20, 2009 at 9:02 pm
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 🙂
October 21, 2009 at 2:21 am
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?
October 21, 2009 at 3:35 am
Great article! Hope you write a follow-up if the python script should ever emerge 🙂
March 10, 2017 at 5:28 am
I actually found this more enrnntaieitg than James Joyce.
October 21, 2009 at 5:42 am
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. 🙂
October 21, 2009 at 11:05 am
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… 🙂
October 21, 2009 at 10:21 pm
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.
October 21, 2009 at 11:29 am
Interestingly enough if you just apply times the order of the changes would have been correct: T0, T1, T3, and T4.
October 21, 2009 at 7:13 pm
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.
October 22, 2009 at 5:34 am
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?)
October 22, 2009 at 9:51 pm
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.
October 23, 2009 at 4:29 am
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.
October 23, 2009 at 11:57 am
[…] What Mother never told you about SVN Branching and Merging « Design By Gravity a few seconds ago from bti […]
October 25, 2009 at 3:56 am
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.
October 26, 2009 at 10:47 am
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.
October 27, 2009 at 12:35 pm
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!
October 29, 2009 at 5:26 am
[…] Read more: Design by gravity […]
November 6, 2009 at 10:51 am
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.
November 8, 2009 at 11:06 pm
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…
November 12, 2009 at 10:50 am
[…] What Mother never told you about SVN Branching and Merging […]
November 15, 2009 at 12:17 pm
Great article. Will try to share with my teams and just as a reminder for them 🙂
November 24, 2009 at 5:02 am
[…] seen a lot of confusion about this last step. What your not trying to do is merge each of your feature work changesets into […]
December 14, 2009 at 6:41 am
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
December 20, 2009 at 12:29 pm
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)
December 21, 2009 at 9:08 pm
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.
April 7, 2010 at 8:21 am
Thanks a lot.
Now I know what has really happened in that screwed up merge!
August 6, 2010 at 11:35 am
Great points! And now, what about answering why merging is good? http://codicesoftware.blogspot.com/2010/08/branch-per-task-workflow-explained.html
April 26, 2011 at 1:36 pm
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.
October 5, 2011 at 4:13 pm
[…] 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 […]
October 22, 2011 at 10:48 am
Isn’t that a case for cherry-picking? Look it up, SVN can do it and it should solve this problem.
April 20, 2012 at 4:39 am
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).
May 11, 2012 at 8:21 am
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.
April 27, 2012 at 5:53 am
This is a really amazing tutorial, I am glad i stumbled across this…
May 1, 2012 at 5:02 pm
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
May 10, 2012 at 10:00 am
[…] 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 […]
May 11, 2012 at 12:45 pm
Best… article… ever!
Thank you so much.
June 1, 2012 at 10:07 pm
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
June 11, 2012 at 4:31 pm
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.
June 12, 2012 at 2:00 am
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.
June 12, 2012 at 9:12 am
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.
June 12, 2012 at 12:24 pm
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.)
July 19, 2012 at 10:37 pm
[…] branch: newBranch" 2. very good site http://www.abbeyworkshop.com/howto/misc/svn01/ useful paper: https://designbygravity.wordpress.com/2009/10/19/what-mother-never-told-you-about-svn-branching-and-m… Like this:LikeBe the first to like […]
May 11, 2013 at 9:31 pm
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.
February 11, 2015 at 3:44 am
more info
What Mother never told you about SVN Branching and Merging | Design By Gravity
April 1, 2015 at 10:29 am
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?
December 22, 2015 at 1:10 pm
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…
April 19, 2015 at 2:30 am
For one reason or another, I can’t see all of this content, the text keeps hiding? Are you using something crazy?
June 20, 2015 at 1:28 pm
[…] See more about this article by clicking the link here: https://designbygravity.wordpress.com/2009/10/19/what-mother-never-told-you-about-svn-branching-and-… […]
March 13, 2016 at 5:21 am
[…] http://svn.apache.org/repos/asf/subversion/trunk/doc/user/svn-best-practices.html https://designbygravity.wordpress.com/2009/10/19/what-mother-never-told-you-about-svn-branching-and-m… […]
September 27, 2016 at 8:38 am
[…] Quelle:https://designbygravity.wordpress.com/2009/10/19/what-mother-never-told-you-about-svn-branching-and-… […]
December 15, 2016 at 7:30 am
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 🙂
January 9, 2017 at 11:46 pm
Hi,
Instead of bunny hoping, cant we just do a rebase after T4 before merging it to trunk(fig 1) in your actual scenario.
December 5, 2017 at 10:36 am
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…