Ours and theirs during merge vs rebase Jump to heading
git checkout --ours file during a merge keeps your branch’s version. Run the same command during a rebase and it keeps the other branch’s version — the one you are rebasing onto — discarding your own change. This is not a bug; it follows directly from how rebase works. But it catches nearly everyone at least once, usually while resolving a large conflict quickly and confidently picking “ours” everywhere. The same swap affects conflict markers, the -X ours strategy option and merge tool pane labels. This page explains the mechanics once, so the swap stops being surprising, and gives a few habits that remove the need to remember. It belongs to 3-way merge fundamentals.
When to use this approach Jump to heading
- You resolve conflicts during both merges and rebases.
- You use
checkout --ours/--theirsor-X ours/theirsto resolve conflicts in bulk. - A rebase resolution once threw away your own changes and you were not sure why.
- You use rebase-based workflows such as configuring git pull --rebase safely for a team.
Step 1 — Understand what “ours” means in each operation Jump to heading
“Ours” always means the commit that HEAD points to while the conflict is being resolved. The difference between merge and rebase is what HEAD is at that moment.
A rebase is a series of cherry-picks onto the target branch. Git checks out the target, then applies your commits one at a time. While applying each one, HEAD is the target plus whatever has been replayed so far, so “ours” is the target branch and “theirs” is the commit being replayed — yours.
# Verification: during a stopped rebase, HEAD is not your branch
git rebase main # stops on a conflict
git rev-parse --abbrev-ref HEAD # prints HEAD (detached), not your branch name
git log -1 --format='%h %s' HEAD # the last commit on main or the last replayed commit
cat .git/rebase-merge/stopped-sha 2>/dev/null # the commit of yours being applied Step 2 — Apply it to checkout --ours and --theirs Jump to heading
The flags pick a whole-file version from the index stages. Stage 2 is ours and stage 3 is theirs, whatever the operation.
# During a MERGE of feature into your branch:
git checkout --ours path # keep your branch's version
git checkout --theirs path # take feature's version
# During a REBASE of your branch onto main:
git checkout --ours path # take main's version (discards your change to this file)
git checkout --theirs path # keep your commit's version The same applies to the strategy options. git rebase -X theirs main resolves every conflicting hunk in favour of your commits; -X ours in favour of main. Using -X ours in a rebase “to keep my changes” does the exact opposite.
Step 3 — Read conflict markers by label, not by position Jump to heading
Conflict markers label each side. During a merge the top section is labelled HEAD and the bottom with the incoming branch name. During a rebase the top is labelled with the upstream commit and the bottom with your commit’s subject.
<<<<<<< HEAD
timeout = 30
||||||| parent of 7c1e2a9 (Raise API timeout for slow regions)
timeout = 20
=======
timeout = 45
>>>>>>> 7c1e2a9 (Raise API timeout for slow regions) That bottom label is your commit. With zdiff3 the base label also names it (“parent of 7c1e2a9”), which makes the situation unambiguous: the bottom section is the change you made, and the top section is what main has now. Turning on ancestor-style markers, described in reading diff3 and zdiff3 conflict markers, is the single best fix for ours/theirs confusion.
Step 4 — Use explicit refs instead of ours and theirs Jump to heading
When in doubt, avoid the words entirely. Take a file’s version from a named commit, which reads the same in every operation.
# During a rebase: take your commit's version explicitly
git checkout "$(cat .git/rebase-merge/stopped-sha)" -- path/to/file
# During a merge: take a named branch's version
git checkout feature/x -- path/to/file
# Or take main's version explicitly, in any operation
git checkout main -- path/to/file Checking out a whole file from one side discards the other side’s changes to that file entirely, not just the conflicting hunks. Prefer it only for files where one side’s version is clearly correct, such as generated files.
# Verification: your change is still present after resolving
git diff --cached -- path/to/file Step 5 — Recover when you picked the wrong side Jump to heading
If you resolved with the wrong flag and continued, the discarded version is not lost. During a rebase, your original commits remain in the reflog; after a merge, the other side is still a parent of the merge commit.
# Rebase: find your branch's state before the rebase began
git reflog show --date=relative "$(git branch --show-current)" | head -5
git diff ORIG_HEAD HEAD -- path/to/file # what the rebase changed in this file
# Restore the file from your pre-rebase branch and amend
git checkout ORIG_HEAD -- path/to/file && git commit --amend --no-edit ⚠️ SAFETY WARNING:
ORIG_HEADis overwritten by the next operation that sets it — another rebase, a reset, a merge. If you are not recovering immediately, use the reflog entry instead (branch@{1}or the hash fromgit reflog), which stays available for ninety days by default.
Validation checklist Jump to heading
Frequently Asked Questions Jump to heading
Why didn’t Git just swap the meanings for rebase to make them intuitive? Jump to heading
Because “ours” is defined as HEAD in all operations, which keeps the low-level machinery consistent. Rebase is implemented as repeated cherry-picks onto the upstream, so HEAD is the upstream. Changing that would make the plumbing inconsistent.
Does the same swap apply to git pull --rebase? Jump to heading
Yes. pull --rebase fetches and then rebases your local commits onto the updated upstream, so during its conflicts your local commits are “theirs”.
What about stash pop? Jump to heading
When applying a stash, HEAD is your current branch and the stash is being applied on top, so the stash is “theirs”. Conflicts from popping a stash are covered in resolving conflicts when popping a stash.
Related Jump to heading
- 3-Way Merge Fundamentals — the parent topic.
- Safe Git Rebase -i for Shared Branches — where these conflicts most often appear.
- Configuring git mergetool for Three-Way Resolution — how tools label the same two sides.
- Aborting and Recovering a Rebase Gone Wrong — the broader recovery toolkit.