git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: More Beginning Git Questions

From
Junio C Hamano <gitster@pobox.com>
Date
Sep 23, 2011, 18:47 UTC
Message-ID
<7vipojumd0.fsf@alter.siamese.dyndns.org>
In-Reply-To
<4E7C9AAD.7060209@gmail.com>
Jon Forrest <nobozo@gmail.com> writes:
Show 9 quoted lines
> "Note that in general, Alice would want her local changes committed
> before initiating this "pull"."
>
> This is an interesting statement. I'll come back to it shortly.
>
> "If Bob’s work conflicts with what Alice did since their histories forked,"
>
> Does this include both changes that Alice has checked in to her
> repository and uncommitted changes in her working tree?

We do not consider uncommitted changes part of _any_ history. You can think of them as floating on top of the history of the branch that is currently checked out [*1*].

Show 9 quoted lines
> "Alice will use her working tree and the index to resolve conflicts,"
>
> How does Alice use her working tree and index? Does this mean
> she makes changes to her working tree so that the conflicts
> no longer exist? How does the index play a part in this?
>
> I thought that the index gets populated only when a
> "git add" is done. Does Alice need to do "git add" as part
> of the conflict resolution process?

If you start from a clean working tree (i.e. no local changes), then after any "mergy" operation (not just "git pull" and "git merge" but things like "cherry-pick", "checkout -m", "rebase" and "am -3" that can stop due to conflicts), one of the three things will happen to each of the paths in the project:

 1. If the result of the operation can be mechanically known, and if that
    is the same as your current state (i.e. HEAD or "ours"), nothing
    happens.
 2. If the result of the operation can be mechanically known, and if that
    is different from your current state (i.e. HEAD or "ours"), the index
    entry for that path records the result, and the path in the working
    tree is updated to match that result.
 3. If the result of the operation cannot be mechanically known
    (i.e. merge conflict), the index entry for that path will record up to
    3 "stages", stage #1 representing the contents the conflicting sides
    diverged from (i.e. common ancestor), stage #2 representing the
    contents of your current state (i.e. HEAD or "ours") and stage #3
    representing the contents of the other branch (i.e. MERGE_HEAD or
    "theirs"), and the path in the working tree is updated to represent it
    with conflict markers.
You conclude the "mergy" operation by resolving conflicts in the working
tree for paths in the category 3, tell Git that you are done with these
paths using "git add $path" (but paths in no other categories!!!).
Because cleanly merged paths are already updated in the index (see
2. above), that is all needed to bring the index to the state that
represents the desired result of the "mergy" operation.

Even if you have local changes in your working tree, as long as your index exactly matches HEAD when you start your "mergy" operation, thanks to the rule for "result matches the current HEAD" case (see 1. above), the result of your "mergy" operation recorded by the procedure in the previous paragraph will not be contaminated with your local changes.

The precondition for all of the above to work is that you start from a clean index, and that is why "git merge" refuses to start if your index already has changes relative to HEAD.

Also, for cases 2. and 3., updating the files in the working tree to match the auto-merge result (case 2.) or to show the conflicted state (case 3.) requires Git to overwrite the file, which is bad if you have local changes to the files in the working tree. To prevent lossage, "mergy" operations will notice if paths in categories 2. and 3. have local changes in the working tree, and refuses to work if that is the case.

[Footnote]

*1* This incidentally is important to have in your mental model to understand how to use "git checkout $branch" to switch branches.

Previous: Jakub Narebski
Message 24 of 24 in “More Beginning Git Questions”
  1. Jon ForrestSep 23, 2011
  2. Matthieu MoySep 23, 2011
  3. Jakub NarebskiSep 23, 2011
  4. Jon ForrestSep 23, 2011
  5. Mihamina RakotomandimbySep 23, 2011
  6. Jakub NarebskiSep 23, 2011
  7. tacticalSep 24, 2011
  8. Frans KlaverSep 24, 2011
  9. tacticalSep 24, 2011
  10. Seth RobertsonSep 24, 2011
  11. tacticalSep 25, 2011
  12. Jakub NarebskiSep 25, 2011
  13. tacticalSep 25, 2011
  14. Jakub NarebskiSep 25, 2011
  15. tacticalSep 25, 2011
  16. Konstantin KhomoutovSep 26, 2011
  17. tacticalSep 26, 2011
  18. Andrew ArdillSep 26, 2011
  19. tacticalSep 26, 2011
  20. Jakub NarebskiSep 26, 2011
  21. Jakub NarebskiSep 24, 2011
  22. tacticalSep 24, 2011
  23. Jakub NarebskiSep 25, 2011
  24. Junio C HamanoSep 23, 2011

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.