Re: Sharing a massive distributed merge

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Mar 17, 2011 at 01:21:19AM -0400, Jay Soffian wrote:

> > 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.

I don't think you need to do anything so drastic. You can just have
everybody do the partial merge, commit, and then push their result.  And
then as you suggest below, one person does the real merge, uses checkout
to install the desired result state from each person's partial tree, and
then everybody throws away their partial merges.

The trick is that each person will resolve some conflicts and commit,
but you need to know which ones they resolved. They can't leave things
unmerged in the final commit. So they would have to provide such a list
to you; one way is in the commit message[1].

So let's say you have three devs, Alice, Bob, and Charlie, and one
integrator, Matt, who will do the merge. Each of the developers does:

  git checkout -b partial-merge
  git merge old-topic
  git mergetool ;# or manually resolve and git add

Eventually they get tired of the conflicts and give up. So they record
the list of resolved paths, either manually or with something like[2]:

  {
    echo 'partial merge result'
    echo

    git status --porcelain | perl -ne '
      next if /^U|\?/;
      s/^\S+\s+//;
      print;
    '

  } >msg

And then they stage the rest of it (knowing it will be ignored by Matt)
and commit:

  git add -u
  git commit -F msg
  git push wherever partial-merge

Then Matt does the actual merge:

  git merge old-topic

which of course results in lots of conflicts. So he pulls resolved
versions from each person's tree:

  for i in alice bob charlie; do
    git fetch $i
    git checkout $i/partial-merge -- \
      `git log -1 --format:%b $i/partial-merge`
  done

And then fixes up whatever's left manually or with git-mergetool, and
commits the end result.

Take all of my scripting there as illustrative of the concept, but not
necessarily a good idea. In particular, it doesn't handle quoting of
filenames at all, and it probably doesn't handle files whose resolution
was to be deleted (since the checkout will fail).

-Peff

[1] I also considered that instead of noting the resolved files in the
commit message, the developers could just remove anything they didn't
resolve. After all, their tree is going to be thrown away eventually.
Then Matt could just script around "git ls-tree" to pull their files
out. The downside is that there is no way for the developers to say "the
resolution is to delete this file", since it just looks like something
they didn't resolve.

[2] It really seems like the right command to get the list of resolved
files would be "git diff-index" with either a diff-filter, or grepping
the output of --name-status. But I couldn't convince it to show me
unmerged files; the unmerged entries always just appeared as
modifications (actually, deletions in --raw), which made them
indistinguishable from modified resolutions.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]