Is git
's merge conflict resolution inherently more efficient than other SCMs (CVS,Subversion,etc.), and also standalone merge tools? If so, why?
Clarification: here I'm more interested in the algorithm itself - is it any different from a plain diff3 method?
Some tools claim to be smarter in that(e.g. Guiffy), is it worth plugging one in as a git merge tool? Is git any smarter in figuring out pieces of text moved within or across files ? (rather than reporting noisy conflicts.. I had a vague impression of that from Linus' talk).Background: just did a huge merge using git-svn
which resulted in half the conflicts than I got with plain svn merge
(first merge with no tracking) .. so I'd like to understand why.
The are similar Qs/As around but they are more about the big picture of the process, and how merging fits in that more naturally. To that end, git
being 'optimised for merges' (as opposed to only branching), does it actually mean:
- less manual conflicts -- better auto-resolution algorithms (eg. renaming is handled nicely)
- safer opera开发者_如何转开发tion -- auto-resolution leaves more/only real conflicts and less false alerts
- faster operation -- say, due to the lean & mean object model
- better tooling -- which makes the experience less painful, e.g. DAG-based merge tracking, mergetool, history query/visualisation, stash, rebase,etc...
- something else
- a combination of the above
? Now, I'm mostly interested in 1 & 2.
I would love to be proven wrong on this answer but... coming from perforce... this area of git is a bit under developed.
Auto merging in git is non-existant. The latest version has basic support for performing a merge using your changes or their changes but that's it. Basically if you edit a portion of a file and someone else edits the same portion of a file... you're on your own for merge resolution. The diff3 format is available (3-way merge) but I believe a unified diff format is the standard. I actually use araxis as the merge tool and have it setup to use 3 way merge when running "git mergetool". Coming from perforce though... I feel like git is way behind in this area.
N/A
Update RE: comments
I haven't dug deep enough into exactly what git thinks is a conflict and exactly what p4 thinks is a conflict but here's what I've experienced in both.
- Git does not ignore white space when doing a merge... although there is talk about this in the future for git. p4 can do this now. Not ignoring white space is a major pain unless everyone on the team agrees on using spaces or tabs and if you'd like to change the indention of a file... (e.g. adding an xml node around other nodes) then this gets old fast.
- I feel like when I come across merge conflicts in a file... the parts that git says are in conflict using it's unified diff format are larger. When it's only a portion of one line that's changed it will mark larger portions as modified and you need to visually hunt down the changes between the two areas of of the unified diff output. You can kind of get around this using a mergetool though. p4 is able to auto resolve conflicts even if editing the same line.
- If you're merging long lived topic branches then you're in for a real treat. Without rerere turned on (which is off by default) git will forget that you've already merged that file that was in conflict a week ago and will ask you to merge it again. p4 does this with ease
My answers here are a bit subjective... but I do sorely miss the merging that I had with perforce.
In addition, this more recent thread (2012) details the notion of "auto-resolution" with Git:
My definition for "auto-resolve":
"During a merge, the working tree files are updated to reflect the result of the merge... When both sides made changes to different areas of the same file, git picks both sides automatically, and leaves its up to you to make sure you review those merge results for correctness after git has made the merge commit."IOW, an "auto-resolve" specifically means that both sides (ours and theirs) made changes to
file(a)
since the common-ancestor version offile(a)
, and git picked both sides without raising a merge-conflict.
(The reason I came up with the term "auto-resolve" is because in thegit-merge
output the term "Auto-merging" can also indicate that only one side (theirs) changedfile(a)
since the common-ancestor and that git is just "fast-forwarding" theirsfile(a)
on top of common-ancestorfile(a)
.)
Junio C Hamano raises in answer an important point:
- know git is stupid and errs on the safe side, punting anything remotely complex;
- know that textual non-conflicts that occur in the same file have the same risk of having semantic conflict across different files, so singling out "touched the same file but did not conflict" any special is pointless, but in either case, the chance of having such a conflict is small enough that completing the merge (and other merges) first and then checking the overall result is more efficient use of your time, because you have to eyeball the result at least once anyway before pushing it out.
Update 5 and a half years later, May 2018 (Git 2.18, Q2 2018)
"git mergetools
" learned talking to guiffy.
See commit 6ceb658 (05 Apr 2018) by Bill Ritcher (``).
(Merged by Junio C Hamano -- gitster
-- in commit da36be5, 25 Apr 2018)
mergetools: add support for
guiffy
Add
guiffy
asdifftool
andmergetool
.
guiffy
is available on Windows, Linux, and MacOS
精彩评论