Jon Forrest <nobozo@xxxxxxxxx> writes: > "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*]. > "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. -- 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