CodeRigor

FREE LESSON

Merges, conflicts & deliberate resolution

Read a three-way merge, resolve the index, and complete or abort the intended operation.

A merge combines histories. When the current branch can simply advance to the incoming tip, Git can fast-forward without creating a merge commit. When both branches have unique commits, Git normally compares their tips with a merge base and records a result with two parents. The resulting tree is your integration decision; a clean textual merge is not proof that the program's behavior is correct.

Three-way merge inputs
start / 4
Commit arrows point to parents. R retains both M and F as parents.
Three-way merge inputs
Commit arrows point to parents. R retains both M and F as parents.

A conflict is an unresolved decision

If both branches change overlapping content incompatibly, Git pauses. git status describes the operation and unresolved paths. The index can hold base, ours and theirs entries for a path rather than a single resolved version. Conflict markers in the working file are a presentation of that situation; deleting the markers alone does not tell Git the index has been resolved.

Inspect git diff and git ls-files --unmerged. For a normal merge into main, ours is the current main side and theirs is the incoming branch side. You may edit a combined resolution, or choose a complete side only when the requirements justify doing so. git checkout --theirs -- config.txt chooses the incoming version in the working tree; follow with git add config.txt to stage the resolution. git restore --source=feature --staged --worktree -- config.txt explicitly selects a named tree and both destinations.

Resolving a path
start / 4
Resolving a path
Git commands
git status
git restore --source=feature --staged --worktree -- config.txt
git diff --cached
git commit -m "Merge the agreed feature configuration"
git log --graph --decorate --oneline -6

Finish the operation you started

When every path is resolved, committing completes the pending merge; git merge --continue is another way to continue it. Check the result, not only the disappearance of the markers. A real merge commit has both parent lines in history. Copying the desired file onto main in an unrelated single-parent commit may produce matching contents while losing the integration relationship the task requires.

git merge --abort is appropriate when you decide to abandon a merge, but cannot always reconstruct complicated uncommitted pre-merge edits. Start integrations with an understood working state. Rebase and cherry-pick have their own continue/abort commands. During a rebase the labels ours and theirs have a different operational viewpoint: the upstream plus already-replayed commits are ours, and the replayed commit is theirs. Prefer explicit revision names when the side labels might be misunderstood.

Operation state matters
start / 4
Operation state matters

Practice the stated resolution

This lab deliberately makes both sides disagree on one setting and supplies a clear integration decision. You need not guess which behavior is better. Preserve both histories, choose the agreed feature contents, resolve the index and complete the merge. Outside a lab, read the surrounding code and run relevant tests: selecting a side is a tool, not a general conflict-resolution policy.

Watch & read

Free lectures, talks and readings that cover this skill from another angle. All resources →

Review the object/reference model and core workflows here. The authored lesson and linked Git manual cover the current command forms and advanced details used in this lab.