What’s so difficult about SVN merges?

Possible Duplicate:
I’m a Subversion geek, why should I consider or not consider Mercurial or Git or any other DVCS?

Every once in a while, you hear someone saying that distributed version control (Git, HG) is inherently better than centralized version control (like SVN) because merging is difficult and painful in SVN. The thing is, I’ve never had any trouble with merging in SVN, and since you only ever hear that claim being made by DVCS advocates, and not by actual SVN users, it tends to remind me of those obnoxious commercials on TV where they try to sell you something you don’t need by having bumbling actors pretend that the thing you already have and works just fine is incredibly difficult to use.

And the use case that’s invariably brought up is re-merging a branch, which again reminds me of those strawman product advertisements; if you know what you’re doing, you shouldn’t (and shouldn’t ever have to) re-merge a branch in the first place. (Of course it’s difficult to do when you’re doing something fundamentally wrong and silly!)

So, discounting the ridiculous strawman use case, what is there in SVN merging that is inherently more difficult than merging in a DVCS system?

21

It’s because svn lacked the proper data structures to accurately determine the latest common ancestor of the two branches. That’s not a big deal for a branch that is only merged once, but can cause a lot of erroneous merge conflicts in situations where several branches are merged multiple times.

I don’t follow svn very closely, but my understanding is those particular technical issues have been fixed in recent versions. However, it wasn’t fixed early enough to dispel the myth, and people who tried DVCS for the merges have stuck with it for other reasons.

0

if you know what you’re doing, you shouldn’t (and shouldn’t ever have to) re-merge a branch in the first place. (Of course it’s difficult to do when you’re doing something fundamentally wrong and silly!)

And therein lies the source of your confusion and the whole problem in general.

You say that merging branches is “fundamentally wrong and silly”. Well, that’s exactly the problem: you’re thinking of branches as things that shouldn’t be merged. Why? Because you’re an SVN user who knows that merging branches is hard. Therefore, you never do it, and you encourage others to not do it. You have been trained to avoid merging; you’ve developed techniques that you use to avoid merging.

I’m a Mercurial user. Even on my own projects, where I’m the only developer, I merge branches all the time. I have a release branch, which I put a fix into. Well, I merge that back into the main-line so that the fix goes there.

If I were using SVN, I would adopt a completely different structure of the codebase. Why? Because SVN makes merges hard, and therefore you develop idioms and techniques to avoid doing complex merges.

DVCS’s make complex merges easy because they are the default state. Everything is a branch, more or less, in a DVCS. So the entire structure of them is built from the ground up to make merging easier. This allows you to develop a workflow that uses merging on a daily basis, rather than the SVN workflow where you never use merging.

The simple fact is this: you should approach a DVCS in a different way than SVN. You should use the proper idioms for these very different kinds of version control systems. In SVN, you adopt idioms that don’t involve merging because merges are hard. In DVCS’s, you adopt idioms that frequently use merges because they’re no big deal.

Right tool for the right job.

The thing is, the merge-focused workflow is a lot nicer and easier to use than the SVN-style workflow where you don’t merge things. It’s easier to see when something from the release branch was brought into the dev branch. It’s easier to see the various interplay between branches. It’s easy to create test branches for things, then clip them off if the test doesn’t work. And so on.

Really, Joel explains this a lot better than I can. You should have a good read of that.

15

There is nothing too difficult about SVN merging… anymore… if you follow the right philosophy

What I see in most other answers seems to come from people who haven’t used SVN in a while. As someone accurately mentions: “it wasn’t fixed early enough to dispel the myth”.

From my current experience of using SVN 1.6 to 1.8 on a legacy project I inherited recently, SVN has gone a long way towards making merging a much easier thing. It is not foolproof, though, and I think it does not easily suffer users deviating from the intended use.

While I knew SVN quite well and had also tried Mercurial for personal projects in the meantime, I had never done a lot of branching in SVN prior to this project. There was quite a bit of trial and error and I got a lot of unexpected merge conflicts when I started.

Ultimately, though, I realized that everytime I got one (or some other issue), it was because I hadn’t done things properly (aka “the SVN way” — arguably, the proper version control way). I believe this is where the difficulty lies: you cannot do whatever you want in an unorganized way and expect SVN to work perfectly, especially with merges. Merges require rigorous discipline from the user(s) before they show their true power.

Here are things I’ve noticed are strong recommendations, if not requirements, for a clean use of merges:

  • Use a recent version of SVN (1.6 and up in my opinion). More and more automation and checks are done for you.
  • Use the default “trunk, branches, tags” structure and apply its philosophy (don’t commit to tags). SVN won’t check anything for you. If you use a tag as a branch (that’s the state I found that project repository in), it can still work, but you need to be consistent.
  • Know what branches are and when to create them. Same with tags.
  • Keep side branches up-to-date with their source branch (usually trunk, but you can branch out from any branch technically). This is mandatory IF you want SVN to do auto-merges. SVN 1.8 actually prevents you from auto-merging if things are not up-to-date, and also if you have pending modifications in your working copy (this behavior seems to have disappeared again in 1.8.5).
  • Do “proper” commits. They should only contain modifications on a very specific concept. As much as possible, they should contain a small amount of change. You do not want to have a single commit contain modifications about two independant bugs for example. If you have already fixed both and they’re in the same file, you should store away the changes of one bug so you can commit just the changes of the other first, then commit the second set of changes. Note that TortoiseSVN allows this easily through “Restore after commit”.
    • Doing so makes it possible to revert a specific independant set of changes AND makes it possible to only merge such a set into another branch. Yes, SVN allows you to merge cherry-picked revisions.
  • If you ever use sub-branches (branching off trunk, then branching off that new branch), respect the hierarchy. If you update the sub-branch with the trunk or vice versa, you’re in for some pain. Merges should be cascaded down or up the hierarchy.
    • After a few months of experimenting, I can vouch that this might be the most important part. Tried creating two sub-branches from the same trunk and then merging bits between the sub-branches, or sometimes between sub-sub-branches from either side. This can trip up SVN (or the user). It can work OK if you’re merging specific revisions. Auto-merge may have trouble with it.
    • I have had trouble specifically when synchronizing sub-branch A with trunk, and then trying to merge something from sub-branch A into sub-branch B. SVN seems to think the “synchronize from trunk” revision should legitimately be merged into sub-branch B and this leads to a mass of conflicts.
  • As much as possible, merge from the root of the branch. Otherwise, SVN will only keep track of the merges done for the sub-folder and when you do try to auto-merge from the root, you may get warnings about missing unmerged revisions. It’s fixable by simply merging these from the root, but best avoid the confusion.
  • Be careful which branch you commit to. If you use Switch to have your working copy point to various branches through time, be sure where you’re committing to.
    • It’s especially bad if you really didn’t want the change in that branch. I’m still not clear on that one, but depending on how you get rid of it / transfer it into the right branch (reverting, merging), you can get something messy. It’s fixable, but you’ll either have to merge revision by revision to avoid or immediately solve potential conflicts, or you’ll have to fix a possibly more complex conflict after the auto-merge.
  • Do not keep branches untouched for too long. Actually, it’s not a matter of time but of how many revisions were committed to the branch and the trunk and how much changed in these. Merges between two branches, 3-way merges, always get compared to most recent common revision between the branches. The more changes in-between, the more change the automatic merging will fail. This is, of course, much worse if you changed the structure of your code in the meantime (moved or renamed files).

If you don’t follow the above, you’re quite likely to get conflicts. They’re always solvable, but not terribly fun to spend time on.

Oh, one more thing about merging where, from all I’ve read and tried, SVN really sucks: deleted/moved/renamed files/folders. Apparently, SVN still cannot deal with a file being renamed, deleted or moved in one branch, and its original version modified in another branch… and then merging these together. It just won’t know where the file went in one way, and will “forget” the changes in the other way. One change is obviously unsolvable (you either delete or change the file, can’t do both), but applying changes to moved/renamed files should work and it doesn’t. Hopefully this gets fixed soon.

So, all in all, is SVN merging easy? I guess not. Not in a carefree way, for sure. Is it bad? I don’t think so. It only spits back in your face when you use it the wrong way and don’t think enough about what you’re doing.

Based on this, I can see why people might prefer Mercurial (for example) as it’s a little more lenient about these things from my experience and had everything automated from the get-go (at least from the early versions I started with). SVN has caught up quite a bit, though, so it’s not worthy of so much bashing anymore.

4

The internal data models are fundamentally different.

Fundamentally, in SVN, when you look at the history of a branch, you only see what has happened in that branch. So when you merge from branch B to branch A, the history of branch A will contain one large commit containing all the changes made explicitly to B since it was branched.

In the first versions of SVN, if you had to merge branch B into branch A once more, you had to manually specify which revision range of branch B you wanted to merge in order to avoid merging the same revisions twice. The clever developer would of course use a commit message like ‘Merged in B:1234’.

SVN 1.5 “fixed” this. But it did not change how merges are applied fundamentally. It merely added some extra metadata to branch A, letting SVN know that revision 1234 had been merged in, allowing SVN to automatically choose the correct revision range.

But this solution is basically a workaround for a data model that fundamentally doesn’t support track what has been merged.

Merging two branches is a relatively simple example. But imaging this more complex scenario

  1. Create branch A from trunk, and make a few commits here
  2. Create branch B from A and make a few commits here
  3. Make a few commits in trunk and A
  4. Merge B into trunk
  5. Merge A into B
  6. Merge A into trunk
  7. Merge B into trunk (this shouldn’t actually do anything)

Handling this correctly using the metadata model becomes extremely complex (I don’t know if SVN does indeed handle this scenario correctly, and I don’t feel inclined to test it out).

Handling this scenario in git is extremely simple.

In git, every time you commit, the internal object representing that commit contains a reference to the previous head. When you merge in a branch, the commit contains references to the previous head of all the branches being merged (you can merge more than one branch at a time in git)

Therefore, when you examine the history of a single commit in git, you can see all history, you can see when it was branched, when it was merged, and you can see the history of both branches between the branching and the merging.

Thus when merging in a branch that has been partly merged, it is extremely simple to determine what has been merged already, and what has not.

I have no experience with Mercurial, but I suspect that its internal workings are similar to git.

So fundamentally, for SVN, it was a design goal to make branching cheap. But in git, it was a design goal to make merging cheap.

Lastly, last time I used SVN, it was not able to handle merges, where a file was renamed in one branch, and modified in another.

I’ve done a fair bit of SVN merging — including having long running development and release branches. By and large I survived. Merging is always tricky, but with DCVS the downside is not horribly bad — everything is local so just update to a known good revision and keep going. Whereas with SVN alot happened on the server side so recovery was ugly — usually it involved wiping out the local copy then checking out a new clean branch to try it again. Wasn’t bad in my case — a gigabit connection to the SVN box helps. But we had some contractors who had lots of trouble with this as they were on slow connections so anything took forever, including merges.

1

Yes, I do that too. I currently have 12 VMs for different versions
(branches) of the project I’m part of at work. When I have to fix a
bug in an older version, I fix the bug, then merge that commit into
the branches for newer versions. But that’s now re-merging an entire
branch, which is what I’m talking about here.

Here lies one of the very nice things about git. It’s not inherit about DVCS, it’s just something git excels at. You can merge specific revisions from any branch into another branch. It basically just takes the diff and applies it to the other branch, but does tracking and is much more automatic.

So, if you have branch 2.0 and branch 3.0 and discover a bug in 2.0, you can then fix it in 2.0 and take the set of revisions which resolve it and merge only those revisions into the 3.0 branch. I don’t believe SVN has any way to do this other than manually taking the diffs for each revision and applying them

Of course, the auto-merge algorithm also appears to work a lot smoother and git was built from the ground up on the “make a branch for all the things” model, so branching is just really smooth and easy in it. It just seems natural to branch often with how lightweight it’s branches are

6

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật