From: Jay Soffian Date: Thu, 17 Mar 2011 05:21:19 GMT Subject: Re: Sharing a massive distributed merge Message-ID: In-Reply-To: <4D8119BE.2090208@workspacewhiz.com> On Wed, Mar 16, 2011 at 4:12 PM, Joshua Jensen wrote: > We have two codelines that diverged quite a while back, and we are now > bringing them back together.  More than 800 files are in conflict, but it is > very possible that the automatic non-conflicting merge is not correcting. >  This means thousands of files need to be examined. Have you considered breaking this up into multiple merges, so that each merge deals with only a subset of the conflicts? This may mean more work overall, but makes reviewing each individual merge much more tenable. IOW, given a history like: a--b--c--d--e...z \ 1--2--3--4...25 Instead of trying to merge z into 25, first merge b, then c, etc. I'd try a divide and conquer approach - merge half way back to the common ancestor, it that's too big, go half way back again, etc. This obviously doesn't parallelize the effort. > Git doesn't support distribution of a merge (although that would be > extraordinarily cool), so the next best thing seemed to be force adding all > files with conflict markers and then committing the merge.  We then publish > the conflicting branch and have each person fix their files.  Given that the > conflict markers are already in place, they can't use their favorite > graphical merge tool. Well, this is awful, but you could do something like: for x in conflicted_files: git show :1:$x > $x.base git show :3:$x > $x.theirs git checkout --ours $x git add $x.base $x.theirs $x Commit that, then folks can use their favorite merge tools, commit the result, and remove the .base and .theirs. Notes: - I'd do all this work on its own branch. When all the files have been resolved, then do a real merge, but consult the branch for the conflict resolution, e.g. "git merge ...; git checkout merge_resolution -- ." - See git-mergetool.sh for how to use checkout-index instead of "show ::..." - This only handles modify/modify conflicts. - You might want to use "merge.conflictstyle diff3" and commit that file too so that there's a reference file with the conflict markers -- I find the diff3 style very helpful in addition to GUI mergetools, for which I've not found one that does a good presentation of theirs, ours, base, and resolved. > What I want to be able to do is have each person perform the merge locally, > stage only the files they care about in that session, reset all other files, > and commit as a regular commit, not a merge commit.  The user can take > advantage of whatever tools they want in the in progress merge.  When > everyone has finished this process, we run git merge and keep our local > changes. $ git merge --squash other_branch # resolve foo $ git commit -m "resolved foo" -- foo $ git reset --hard Though I think the "awful" solution above might prove less error prone and do a better job of keeping track of the remaining work. j.