Thread (1 message) 1 message, 1 author, 2016-06-15
  • (off-list ancestor, not in this archive)
  • Re: Now What? · Junio C Hamano <hidden> · 2016-06-15

Re: Now What?

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:42:10

Jon Loeliger [off-list ref] writes:
I feel that an explanation of all of the behind-the-scripts-
in-.git communication files is needed.  In particular these:

    FETCH_HEAD
    MERGE_HEAD
    LAST_MERGE
    MERGE_MSG

These need to be mentioned and explained because they
frequently form exactly the critical missing link or
starting point after a failed fetch or merge.
I am not so sure if it would help to know details of the above
four files to answer "Now What" question, but I'll try to
describe them near the end of this message.

Before that, here is a cookbook failed pull/merge resolution
procedure.

	$ git pull some-where
	Gaah ... resolve by hand.

Oops, it failed.  Now what?

First, if your index did not match your HEAD before
pulling/merging, the merge strategies will refuse to merge in
the changes and would fail without touching your working tree
(so you would not even see "resolve by hand" message).  If you
want to proceed, you need to somehow match your HEAD and your
index to retry.  There are two possibilities.

(1) if you were deep in a middle of something, snapshot your
    changes and rewind the current tree.

	$ git commit -a -m 'WIP'
	$ git branch save-wip
        $ git reset --hard HEAD^

    and then retry merge or pull.  Later you would want to
    resurrect what you did from save-wip branch (e.g. "git diff
    save-wip^ save-wip | git apply" after finishing your
    merge).

(2) if you did not have much worth saving, just rewind the
    changes.  Optionally you could save the diff just in case.

	$ git diff HEAD >tmp-wip.diff
        $ git reset --hard

    and then retry merge or pull.

Now that case is out of our way, I'll discuss the case where
your index did match your HEAD from here on.  You pulled from
remote, merge strategy tried to do its work, and did not find a
clean automerge.

At this point, the automerge procedure would have already
updated your index for paths that cleanly merged.  The rest are
left in your working tree, so this diff would show what remains
to be resolved:

        $ git diff

You would most likely see some <<<< ==== >>>> conflict markers.
Resolving them by hand is hopefully something familiar to CVS or
SVN migrants, so "Now what" document may not have to talk about
what these conflict markers mean ("between <<<< and ==== are
your version, between ==== and >>>> are their version", or
something like that --- I may be getting this particular detail
wrong in this sentence, so you should check).

After resolving them by hand, you would want to see what got
changed from _your_ version for sanity checking, because you are
hopefully more familiar with your version than theirs, and
reading diff between theirs might be more difficult.  So check

	$ git diff HEAD

to see what changes this pull brought in, including the conflict
resolution you just did.  On the other hand,

	$ git diff MERGE_HEAD

would show diff from their head, so you would see what you did
to their tree.

After checking the diffs, if things look OK, compiling and
testing is the same procedure as you would normally do before
making any commit.  Then

	$ git commit -a

(as usual, you can drop '-a' if you manually 'git-update-index'
all the necessary paths before this step) would give you the
regular commit message editor, with a reminder "you are
committing a merge", with prepared message "merge from
some-where repository".  Edit it and exit the editor normally to
make the merge commit, and you are done.

Now to the communication files.
    FETCH_HEAD
This file lists refs the git-fetch command (run from git-pull)
retrieved from the remote.  Usually it marks everything but one
as 'not-for-merge'.  The one that is not marked as
'not-for-merge' is the commit you are merging into the current
head.  This is not looked at by the merge machinery, but
git-pull uses it to decide which commits to pass to git-merge.
    MERGE_HEAD
This is present only after a failed automerge, by git-merge, and
lists the commits that you are merging into the current head
(typically only one) -- the same as the ones not marked as
'not-for-merge' in FETCH_HEAD, because this file records the
commits given to git-merge.
    LAST_MERGE
This is more or less historical curiosity and only git-resolve
uses it.  Records almost the same information as MERGE_HEAD.
    MERGE_MSG
This is created by git-pull from FETCH_HEAD to format a human
readable autocommit log.
Finally, a procedure or style question.  Should this
write-up be in the form of a structured FAQ?  A stand-alone
expository document?
One useful thing would be to have a cut&paste ready example that
would cover constructing two branches/repos, pulling a branch
from one to the other and causing an actual conflict, and show
how to resolve it and make a commit, in a section in Tutorial.
I think we already have something like that there.

Another good thing would be, after proofreading this message and
making necessary corrections, send it as a patch form to add it
as a new file under Documentation/howto/.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help