Re: Sharing a massive distributed merge
- From
Jay Soffian <jaysoffian@gmail.com>
- Date
- Mar 17, 2011, 05:21 UTC
- Message-ID
- <AANLkTim0TL5X8rKoBceK3nLA4JrtuftqkJDkRi0Lok0A@mail.gmail.com>
- In-Reply-To
- <4D8119BE.2090208@workspacewhiz.com>
On Wed, Mar 16, 2011 at 4:12 PM, Joshua Jensen <jjensen@workspacewhiz.com> 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.
Show 6 quoted lines
> 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 :<stage>:..."
- 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.
Show 6 quoted lines
> 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.