Git Merge Conflict Resolution: From Unmerged Paths to a Resolved Index
Resolve real Git merge conflicts by choosing intended content, staging each resolved path, inspecting the index, and proving the distinction between resolution and merge completion.
Intermediate
Resolution changes the index state, not just the file
V438 established how Git represents an unresolved merge: the working tree can contain conflict markers and the index can contain unmerged stages. This lesson owns the next state transition. A conflict is resolved when the learner has chosen the intended result for a path and Git records that result as an ordinary index entry. Editing the working-tree file is necessary for a normal text resolution, but editing alone does not clear the unmerged index state. `git add <path>` records the resolved content in the index and removes the unmerged stages for that path.
git merge topic
# edit conflict.txt until its contents are the intended result
git add conflict.txt
git ls-files --unmerged
git status --shortQuick check
After editing a conflicted file but before `git add`, what remains true?
A conflicting merge has produced stage 1/2/3 entries for conflict.txt.The file text can be changed while conflict.txt is still unmerged in the index.
Choose the intended result in the working tree
Git does not decide the semantic answer to a conflict for you. For a text conflict, inspect the competing content and edit the working-tree file to the exact result you want the merged snapshot to contain. The result may keep material from either side, combine both sides, or introduce a deliberate new result. The important boundary is that the working tree must contain the content you intend to record; conflict markers are not themselves a resolution.
cat conflict.txt
# edit conflict.txt
cat conflict.txtQuick check
What must the working-tree file contain before it is staged as the resolution?
The file contains conflict markers and competing sections.The file contains one deliberate result with no unresolved conflict markers.
`git add` converts an unmerged path into a staged result
`git add <path>` adds the current working-tree contents to the index. During conflict resolution, this replaces the path's unmerged index representation with the resolved content. That is why `git add` is a state transition here, not merely a generic 'save' command: it tells Git which content should become the index entry for the path. The command does not create the merge commit.
git add conflict.txt
git ls-files --unmerged
git status --short
git diff --cached -- conflict.txtQuick check
What is the decisive effect of `git add conflict.txt` after you resolve the file?
conflict.txt is still unmerged after the file has been edited.conflict.txt is staged as a resolved path; `git ls-files --unmerged` no longer lists it.
Verify the index, not only the file
A reliable resolution check verifies the index explicitly. `git ls-files --unmerged` should no longer report the resolved path. `git diff --cached` shows what the index now proposes for the eventual commit, while the working tree shows the file currently on disk. These observations prevent a common mistake: seeing clean-looking text and assuming Git has recorded the resolution when the index still contains unmerged stages.
git ls-files --unmerged
git diff --cached -- conflict.txt
git status --short --branchQuick check
Which observation directly proves that conflict.txt is no longer represented by unmerged index stages?
conflict.txt has been edited but has not yet been staged.After `git add conflict.txt`, no unmerged entry remains for that path.
Resolve paths independently
A merge can have more than one conflicting path. Resolution is path-specific: staging one resolved path does not silently resolve another path. This makes `git ls-files --unmerged` useful throughout the process: it tells you which paths still require a resolution decision. Do not infer completion from one path becoming staged.
git ls-files --unmerged
# resolve one path
git add first.txt
git ls-files --unmergedQuick check
If two paths are unmerged and you run `git add first.txt` after resolving only that file, what should you expect?
first.txt and second.txt are both unmerged.first.txt is resolved and staged; second.txt remains unmerged.
Resolution is not merge completion
After all conflicting paths are resolved and staged, the merge can be completed, but it has not yet become a merge commit merely because the index is clean of unmerged entries. During this intermediate state, `HEAD` remains at the receiving branch tip and `MERGE_HEAD` still identifies the incoming commit. V440 will own the commands that continue the merge and create or abort the resulting history transition.
git ls-files --unmerged
git rev-parse HEAD
git rev-parse MERGE_HEAD
git status --short --branch
git rev-list --parents -n 1 HEADQuick check
After every conflict is resolved and staged, which statement is most precise?
All conflicting paths have been staged as resolved.No unmerged paths remain, but HEAD and MERGE_HEAD still describe the in-progress merge.
Do not confuse resolution with choosing a side
A resolution can be produced by manually combining content, by intentionally taking one side for a path, or by another Git-supported workflow. The curriculum will treat side-selection commands only as resolution mechanisms whose result must still be inspected and recorded. In particular, `ours` and `theirs` are contextual terms; they should never be memorized as universal synonyms for 'my work' and 'the other person's work' across every Git operation. The core invariant remains the same: the index must contain one intentional result for each resolved path.
# after choosing the intended content for conflict.txt
git add conflict.txt
git ls-files --unmerged
git diff --cached -- conflict.txtQuick check
What invariant matters regardless of how you produced the resolved content?
A conflict path is being resolved by a chosen method.The chosen content is staged and the path has no unmerged stages.
Practice what you learned
Use the dedicated Git code-completion exercise for this lesson.
Official-source boundary
This lesson uses only official Git documentation. The primary command source for the resolution transition is `git-add`; `git-status`, `git-ls-files`, and `git-merge` define the surrounding repository state. The current official documentation baseline is Git 2.56.0. The local verifier is Git 2.47.3, and all execution claims in the verification suite are observations from that executable. Final merge completion and abort workflows remain V440 ownership.
Thanks for your feedback.
Mark this learning resource complete to track your learning progress.