Git conflicts are a normal part of collaborative development, but resolving them safely requires more than choosing “ours” or “theirs.” This guide explains a repeatable Git merge conflict workflow: identify the operation in progress, inspect each conflicting change, resolve files deliberately, stage the result, run verification, and recover with the reflog when a merge or rebase does not go as planned.
Overview
A conflict occurs when Git cannot combine two sets of changes automatically. This commonly happens when branches modify the same lines, when one branch edits a file that another deletes, or when a rebase replays a commit onto code that has changed.
The conflict itself does not mean that either branch is wrong. It means Git needs a developer to decide what the final version should contain. The safest approach is to treat conflict resolution as a small code-review task rather than a mechanical editing exercise.
Before changing anything, check the repository state:
git status
The output usually tells you whether you are completing a merge, rebase, or cherry-pick, and lists files that need attention. That context matters because the command used to continue or cancel the operation depends on the operation in progress.
Merge versus rebase: which approach fits?
| Situation | Usually prefer | Reason |
|---|---|---|
| Combining a shared feature branch into a target branch | Merge | It preserves the existing branch history and is generally safer for commits others may already have. |
| Updating your private branch before opening or refreshing a pull request | Rebase | It replays your commits on top of the newer base and can produce a linear history. |
| Changes have already been pushed and collaborators may depend on them | Usually merge | Rebasing published commits changes their identities and may require a force push. |
| You need to stop and return to the state before the operation | Abort | Aborting lets you reconsider the approach without completing a partial history change. |
Team conventions take priority over this general guide. If a project requires rebasing, merging, or a particular pull-request workflow, follow that convention and confirm the expected history before rewriting commits.
What to track
A reliable conflict workflow tracks more than whether a file is marked unresolved. Track the operation, the affected files, the intended behavior, and the verification needed before the branch is considered complete.
1. Identify the operation
Run git status and read its instructions. During a merge, Git may direct you to resolve files and run git commit. During a rebase, it may direct you to run git rebase --continue. Do not guess which continuation command to use.
2. Locate every conflict
Git places conflict markers in files that contain competing text:
<<<<<<< HEAD
version from the current branch
=======
version from the incoming commit
>>>>>>> other-branch
The labels vary depending on the operation. In a merge, the section above the separator commonly represents the current branch, while the section below represents the incoming branch. In a rebase, the wording can be less intuitive, so inspect the commit and surrounding code rather than relying only on the labels.
Search for all unresolved markers, including in files your editor may not have opened:
git diff --check
git diff --name-only --diff-filter=U
3. Understand the intended final behavior
Compare the conflict with the surrounding implementation and the purpose of both changes. Sometimes the correct resolution is to keep one side. Often it is a combination: preserve a new function from one branch while adapting it to an API, configuration key, or test introduced by the other.
Useful inspection commands include:
git diff
git diff --ours -- path/to/file
git diff --theirs -- path/to/file
git log --oneline --decorate --graph -n 12
Use “ours” and “theirs” as inspection terms, not as automatic answers. Taking an entire side can silently remove valid work elsewhere in the file.
4. Record resolution state
After editing a file, remove every conflict marker and save the intended content. Then stage it:
git add path/to/resolved-file
Staging tells Git that you have resolved that path; it does not prove the code is correct. Review the staged result before continuing:
git diff --cached
Cadence and checkpoints
Use the following checkpoints every time a merge conflict or Git rebase conflict appears.
- Protect useful work. If you have unrelated local edits, consider committing them on a temporary branch or stashing them before starting. Do not discard changes merely to make the status output simpler.
- Read the operation state. Run
git status and note whether Git is merging, rebasing, or performing another operation. - Review the base and incoming changes. Inspect the diff, recent commits, and relevant tests. Ask what behavior each side was trying to introduce.
- Resolve one file at a time. Edit the file, remove markers, compare the result with both versions, and stage it with
git add. - Check for omissions. Run
git diff --check, inspect git diff --cached, and confirm that no unmerged paths remain with git status. - Continue the operation. For a rebase, use
git rebase --continue. For a merge, complete the merge commit when Git requests it. If another conflict appears, repeat the same process. - Run focused tests first. Test the affected package, endpoint, query, or UI behavior before running the broader project suite. Then run the normal lint, type-check, build, or test commands required by the repository.
- Review the final history. Use
git log --oneline --decorate --graph and inspect the final diff against the target branch.
For recurring team work, make this checklist part of pull-request review. Conflict resolution should be reviewed for behavioral correctness, not accepted solely because the repository becomes clean.
How to interpret changes
A clean status is only one signal. Interpret the result across four dimensions: content, behavior, history, and collaboration risk.
Content: Confirm that conflict markers are gone and that the merged file contains the required imports, configuration, error handling, and documentation. A conflict can compile while still omitting a necessary branch of logic.
Behavior: Pay particular attention to changed assumptions. If one branch updates an API response shape and another updates the parser, resolve them together and test the complete path. For database or migration code, verify ordering and compatibility rather than comparing text alone.
History: A merge should show the expected merge result. A rebase should show your commits replayed on the new base. If the history looks unexpectedly shortened or contains duplicate work, stop and investigate before pushing.
Collaboration: Be cautious when rebasing commits that others may have pulled. If a push requires rewriting remote history, confirm the team’s process and use the least disruptive option available. A force push, even when technically permitted, can remove another person’s newer remote work if used carelessly.
If you realize that the operation is becoming confusing, you can safely stop an active operation before completion:
git merge --abort
git rebase --abort
Use the command matching the operation shown by git status. If an abort is unavailable or the repository is no longer in the expected state, avoid additional destructive commands and inspect the reflog.
When to revisit
Revisit this workflow whenever a pull request reports conflicts, a branch has been inactive for a while, a major refactor changes shared files, or a rebase produces a result you cannot explain. Teams can also review their conflict patterns monthly or quarterly.
During that review, look for repeated conflict locations, frequent accidental overwrites, long-lived branches, and tests that fail only after integration. Those patterns may point to smaller improvements: split large files, reduce branch lifetime, coordinate ownership of migrations, improve integration tests, or document the project’s merge and rebase policy.
If commits appear to have disappeared after a reset, rebase, or mistaken checkout, Git’s reflog may help recover them:
git reflog
git show <commit>
git branch recovery/<name> <commit>
The reflog records recent movements of local references, so its entries are useful for finding a previous branch tip. Recovery details depend on the repository state and local retention, so create a safety branch before experimenting with any candidate commit.
Keep this short checklist near your repository documentation:
- Run
git status before editing. - Resolve intent, not just conflict markers.
- Stage each resolved file and inspect
git diff --cached. - Run
git diff --check and focused tests. - Use
--abort when the current operation should not continue. - Inspect
git reflog before assuming lost work is unrecoverable. - Review the final diff, test results, and history before pushing.
For adjacent debugging workflows, a formatted API response can make integration failures easier to inspect; see the JSON Formatter for API Debugging guide. When a conflict affects request contracts, the OpenAPI validation guide can help verify that the final implementation still matches its documented interface.