• Understanding `ours` and `theirs` in Git Merge and Rebase

    Git has two small words that cause a surprising amount of damage: ours and theirs.

    They look obvious. They are not.

    The trap is that Git does not define those words from your emotional point of view. It defines them from the point of view of the operation currently applying changes. During a normal merge, that usually matches what you expect. During a rebase, it often feels reversed.

    This article is about the exact behavior of:

    git merge -Xours other-branch
    git merge -Xtheirs other-branch
    git rebase -Xours main
    git rebase -Xtheirs main

    The short version:

    Operationours meanstheirs means
    mergecurrent branchbranch being merged in
    rebasebranch being rebased ontocommit currently being replayed

    One more important warning: -Xours and -Xtheirs are merge strategy options. They help Git resolve conflicting hunks. They do not mean “throw away every change from the other branch.”

    Merge: The Intuitive Case

    Suppose you are on main and merge feature:

    git switch main
    git merge feature

    During this merge:

    • ours is main, because that is the branch you are on;
    • theirs is feature, because that is the branch being merged in.

    So if both branches changed the same line and you run:

    git merge -Xours feature

    Git prefers the conflicting version from main.

    If you run:

    git merge -Xtheirs feature

    Git prefers the conflicting version from feature.

    That is the easy case.

    Rebase: The Perspective Flip

    Now suppose you are on feature and rebase it onto main:

    git switch feature
    git rebase main

    A rebase does not merge main into feature in one step. It first checks out the target base, then replays your feature commits on top of it.

    During each replayed commit:

    • ours is the branch being rebased onto, here main;
    • theirs is the commit from your feature branch currently being replayed.

    So:

    git rebase -Xours main

    prefers the conflicting version from main.

    And:

    git rebase -Xtheirs main

    prefers the conflicting version from your feature commit.

    That is why -Xtheirs during rebase often feels like “keep my branch,” even though during merge theirs means the other branch.

    A Tiny Repro

    You can verify the behavior with one file.

    Start with a base commit:

    git init ours-theirs-demo
    cd ours-theirs-demo
    git config user.email test@example.com
    git config user.name Test
    
    printf 'base\n' > note.txt
    git add note.txt
    git commit -m base

    Create a feature branch:

    git switch -c feature
    printf 'feature\n' > note.txt
    git commit -am 'feature change'

    Change the same file on main:

    git switch main
    printf 'main\n' > note.txt
    git commit -am 'main change'

    Now merge from main:

    git merge -Xours feature
    cat note.txt
    # main

    ours is the current branch, so the conflicting line from main wins.

    If you reset and try:

    git merge -Xtheirs feature
    cat note.txt
    # feature

    theirs is the branch being merged in, so the conflicting line from feature wins.

    For rebase, recreate the same base situation, switch to feature, and run:

    git rebase -Xours main
    cat note.txt
    # main

    Then recreate it again and run:

    git rebase -Xtheirs main
    cat note.txt
    # feature

    That is the whole mental model.

    -Xours Is Not -s ours

    These two commands look similar but do very different things:

    git merge -Xours feature
    git merge -s ours feature

    -Xours is an option passed to the normal merge strategy. Git still tries to merge both branches. When a conflicting hunk cannot be resolved automatically, it prefers our side for that hunk.

    -s ours selects the ours merge strategy. That strategy records a merge commit while ignoring the other branch’s tree entirely.

    Use -s ours rarely and deliberately. It is useful for history bookkeeping, such as marking a topic branch as merged without taking its content. It is not a normal conflict-resolution tool.

    Per-File Resolution

    Sometimes you should not apply a global strategy option at all. If only one file is tricky, resolve that file explicitly:

    git checkout --ours path/to/file
    git checkout --theirs path/to/file
    git add path/to/file

    During merge, --ours means current branch and --theirs means branch being merged.

    During rebase, the same perspective flip applies: --ours is the rebased-onto side, and --theirs is the commit being replayed.

    If you use newer Git versions, you can also use git restore:

    git restore --source=:2 path/to/file
    git restore --source=:3 path/to/file

    In conflict stages, stage 2 is ours and stage 3 is theirs.

    When To Use Each

    Use git merge -Xours feature when you are on the target branch and want its conflicting hunks to win.

    Use git merge -Xtheirs feature when you are on the target branch and want the incoming branch’s conflicting hunks to win.

    Use git rebase -Xours main when rebasing a feature branch and you want the base branch’s conflicting hunks to win.

    Use git rebase -Xtheirs main when rebasing a feature branch and you want the feature commits’ conflicting hunks to win.

    And in all cases: read the diff before committing the result.

    git diff
    git diff --staged

    Automatic conflict preferences are convenient, but they can hide semantic conflicts. If two branches changed the same area of code for different reasons, “ours” or “theirs” may compile and still be wrong.

    rerere Helps With Repeated Conflicts

    If you resolve similar conflicts often, look at git rerere.

    git config --global rerere.enabled true

    rerere means “reuse recorded resolution.” Git remembers how you resolved a conflict and can reuse that resolution when the same conflict appears again. It is especially helpful during long-running rebases.