Subject: Re: Command-line interface thoughts

From: Jay Soffian <[email-masked]>
Date: Thu, 9 Jun 2011 13:15:38 -0400

On Thu, Jun 9, 2011 at 12:18 PM, Jeff King <[email-masked]> wrote:
> On Thu, Jun 09, 2011 at 11:06:56AM +0200, Michael Haggerty wrote:
>
>> My naive understanding is that in the case of a merge commit, the index
>> contains information equivalent to *multiple* trees:
>>
>> NEXT -- HEAD plus the files that have been resolved
>> BASE -- the contents of the common ancestor
>> OURS -- equivalent to the tree from HEAD
>> THEIRS -- equivalent to the tree from MERGE_HEAD
>
> Almost. Remember that as part of the merge resolution process,
> higher-level stages will collapse down to 0. So the "theirs" stage of
> the index is equivalent to MERGE_HEAD only if you have a conflict in
> every file and have resolved nothing. Otherwise, any resolved entries
> will not have a "theirs" entry at all.
>
> So when I do "git diff", we will see for resolved entries that the
> working tree matches stage 0 in the index, and show nothing. Whereas
> unresolved entries will have their diff shown. But with "git diff
> MERGE_HEAD", we will see differences from the other branch, even if
> those differences are simply resolutions or even changes made on the
> "ours" branch.
>
> So the index is not quite simply a set of four trees. The presence of
> various stages for each entry tells us the progress of resolution.

However, it would be useful I think to expose it as four separate
trees. During conflict resolution, I often want to look at the
conflicted files in these various states, and end up using various
incantations that are somewhat baroque.

e.g.:

  $ git diff ...MERGE_HEAD -- /path/to/file

is probably less clear than:

  $ git diff BASE THEIRS -- /path/to/file

In fact, my first step after a conflicted merge is:

  $ git tag -f ours HEAD
  $ git tag -f theirs MERGE_HEAD
  $ git tag -f base $(git merge-base HEAD MERGE_HEAD)

j.