问题
After reading How and/or why is merging in Git better than in SVN? I still don't get it. Let's say I have multiple versions I'm maintaining (I need to maintain them all, all in production):
- v1.0
- v1.1
- v1.2
- v1.3
- v1.4
Now I commit a bugfix to v1.0 (and I need this bug fix in all next versions).
Now in both git and svn I have to perform the following logical operations
- x=1
- merge into next branch v1.(x)
- check everything is ok (tests, build) for v1.(x)
- x++ goto (2) until at last branch
What is the major benefit of using git for that (or gerrit)? The logical operations of merge into next branch, commit, test are the same! So what is different? (If it's just minor merge algorithm improvements, it does not matter to me too much. I have a rather nice automatic merge resolve conflicts in Subversion. Also I don't mind checking out branch v1.1 to do the merge in subversion because I have some utility that does that for me so I invest no time in it).
回答1:
Because git doesn't store deltas like other version control systems do, it stores the full content of each file in each commit (in a very compressed and efficient way, but to keep the things simple, just keep in mind that It doesn't store deltas, sorry to repeat but this is why most professionals new to git get so confused).
And when it has to merge, makes a three way merge between last state/snapshot of each branch and a common base ancestor instead of trying to apply the deltas/diffs (with changed contexts) of the last 100 commits of one branch into another.
Way simpler approach, and it's way more effective, it doesn't leave the user with 100 conflicts.
回答2:
I think this point can be demonstrated when comparing the blame feature of SVN and Git. My company uses SVN (and I'm disgruntled about it). Our developers do not do their own merging so code is always merged by a different person. I'm often asked "Who changed that line and why?". So I perform an svn blame. If that line came in through a merge from another branch, the commit shown is that of the merge not of who edited the line. So I have to find that branch and attempt a blame on it. In the example above, if you started tracking at v1.4, you could waste half a day getting all the way back to v1.0 to find the change.
Git blame always gives you the commit of the person who made the change as that's what we're trying to find out. This is much better for accountability.
I think that is what's meant above by "svn has no concept of merges and branches". It only sees the commit made when the merge happened and can't trace the history back further than that in order to do a proper blame.
回答3:
Although what you do looks same, the difference is that git is able to natively track what you're merging where for all of such steps. So when you update "v1.4", your can see that the bugfix was originally done against v1.0, then merged to v1.1 (and by whom and how), then to v1.2, v1.3, and finally v1.4.
svn has no concept of merges and branches by itself, the final product in v1.4 would be simply another tree revision that happens to change contents "branches/v1.4" directory. Recent svn releases have tried to address this problem by somehow tracking that a given revision actually merges changes from another branch, but that is something built into it later and it does not work very well.
The other important difference is that when I measured how long the process you've mentioned takes with one simple changes in two branches we had (they were quite different by that time) it took half an hour with svn/svnmerge and 11 minutes with git*. A lot of this probably has to do with the fact that svn needs to fetch all history information from remote server, and git has everything in local and native (=efficient) data structures.
(*This was the whole workflow w/ running tests etc. By itself, the time difference of svn merge and git merge commands was 1.5 minutes vs. <1 sec.)
来源:https://stackoverflow.com/questions/10340544/how-is-git-merge-better-than-svn-merge-if-you-still-have-to-go-through-the-same