← Recipes

阅读中文版本

Resolve a Merge Conflict Without Losing Work

Inspect both sides of a conflict, choose or combine the intended changes, stage the result, and verify with tests before completing the merge.

~20 mingitcollaborationversion-control

Task

Resolve conflicts produced by git merge or git rebase while preserving the intended behavior from both branches.

When to use this

Two branches changed the same lines or deleted and modified the same file. Git stops the merge and marks conflicted paths.

Prerequisites

  • A merge or rebase in progress
  • Understanding of the intended behavior on both branches
  • A test command that covers the affected code

Steps

1. List conflicted files and inspect each conflict marker. Identify the base, current branch, and incoming branch sections.

git status --short && git diff --name-only --diff-filter=U

Expected output: A list of conflicted files and their marker locations.

2. Edit each file to the intended final state. Remove all conflict markers; do not simply choose one side without checking semantic dependencies.

grep -rn '<<<<<<<\|=======\|>>>>>>>' . --exclude-dir=.git

Expected output: No conflict markers remain.

3. Stage resolved files and run the test suite before completing the merge.

git add <resolved-files> && npm test

Expected output: Tests pass with the combined changes.

4. Complete the merge or rebase and review the resulting commit.

git commit   # or git rebase --continue

Expected output: A merge/rebase commit containing both sets of intended changes.

Troubleshooting

Problem

A file was deleted on one branch and modified on the other

Solution

Decide explicitly whether the file should exist; use git rm to keep it deleted or git add to keep the modified version.

Problem

Tests pass but behavior is wrong

Solution

Review the semantic diff, not just syntax; conflicts in configuration or generated files can hide intent differences.

Limitations

  • Automatic merge tools cannot infer business intent; a human must decide which behavior is correct.
  • Resolving by choosing "ours" or "theirs" for an entire file can silently drop unrelated changes.

Read the conflict before editing

A conflict is a question, not an error. The markers show three versions: the common base, the current branch, and the incoming branch. Understand why each side changed before choosing a result.

git status
git diff --name-only --diff-filter=U
# open each file and remove <<<<<<<, =======, >>>>>>> markers
git add src/payments/refund.ts
npm test
git commit

For a rebase, the workflow is the same but the commit is created with git rebase --continue instead of git commit.

Verify

  • No conflict markers remain in the tree.
  • The test suite passes on the merged result.
  • git diff HEAD^ shows the combined intent, not a wholesale replacement of one side.
  • The merge commit message explains non-obvious resolution decisions.

Prevention

Keep branches short-lived, rebase or merge from main frequently, and avoid reformatting entire files in feature branches. Small, frequent integrations produce smaller conflicts with clearer intent.