Git Rebase: ours and theirs, local and remote


A rebase switches the meaning of "ours" and "theirs":

git checkout topic
git rebase   master    # rebase topic branch on top of master branch

Whatever HEAD's pointing to is "ours"

The first thing a rebase does is resetting the HEAD to master; before cherry-picking commits from the old branch topic to a new one (every commit in the former topic branch will be rewritten and will be identified by a different hash).

With respect to terminologies used by merge tools (not to be confused with local ref or remote ref)

=> local is master ("ours"),
=> remote is topic ("theirs")

That means a merge/diff tool will present the upstream branch as local (master: the branch on top of which you are rebasing), and the working branch as remote (topic: the branch being rebased)

| LOCAL:master |    BASE   | REMOTE:topic |
|             MERGED                      |

Inversion illustrated

On a merge:

c--c--x--x--x(*) <- current branch topic ('*'=HEAD)
      \--y--y--y <- other branch to merge

We don't change the current branch topic, so what we have is still what we were working on (and we merge from another branch)

c--c--x--x--x---------o(*)  MERGE, still on branch topic
    \       ^        /
     \     ours     /
      \            /

On a rebase:

But on a rebase we switch sides because the first thing a rebase does is to checkout the upstream branch to replay the current commits on top of it!

c--c--x--x--x(*) <- current branch topic ('*'=HEAD)
      \--y--y--y <- upstream branch

A git rebase upstream will first set HEAD to the upstream branch, hence the switch of 'ours' and 'theirs' compared to the previous "current" working branch.

c--c--x--x--x <- former "current" branch, new "theirs"
      \--y--y--y(*) <- set HEAD to this commit, to replay x's on it
               ^       this will be the new "ours"

The rebase will then replay 'their' commits on the new 'our' topic branch:

c--c..x..x..x <- old "theirs" commits, now "ghosts", available through "reflogs"
      \--y--y--y--x'--x'--x'(*) <- topic  once all x's are replayed,
               ^                      point branch topic to this commit
        upstream branch