views:

169

answers:

4

When doing a git rebase, I often have difficulty working out what is happening with the 'local' and 'remote' when resolving conflicts. I sometimes have the impression that they swap sides from one commit to the next.

This is probably (definitely) because I still haven't properly understood.

When rebasing, who is 'local' and who is 'remote'?

(I use P4Merge for resolving conflicts)

+1  A: 

Is it possible that reading this would help you? The rest of the tutorial is very helpful as well....

ivans
A: 

Another excellent git resource.

Unknown
+2  A: 

I didn't get your problem exactly but I think the following diagram resolves your issue. (Rebase : Remote Repository ---> Workspace)

alt text

Chathuranga Chandrasekara
+3  A: 

The confusion might be related to the inversion of ours and theirs during a rebase.
(relevant extracts)

git rebase man page:

Note that a rebase merge works by replaying each commit from the working branch on top of the <upstream> branch.

Because of this, when a merge conflict happens:

  • the side reported as ours is the so-far rebased series, starting with <upstream>,
  • and theirs is the working branch. In other words, the sides are swapped.

On a merge:

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

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

x--x--x--x--x---------o(*)  MERGE, still on branch B
    \       ^        /
     \     ours     /
      \            /
       --y--y--y--/  
               ^
              their

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

x--x--x--x--x(*) <- current branch B
    \
     \
      \--y--y--y <- upstream branch

A git rebase upstream will first change HEAD of B to the upstream branch HEAD (hence the switch of 'ours' and 'theirs' compared to the previous "current" working branch.)

x--x--x--x--x <- former "current" branch, new "theirs"
    \
     \
      \--y--y--y(*) <- upstream branch with B reset on it,  
                       new "ours", to replay x's on it

, and then the rebase will replay 'their' commits on the new 'our' B branch:

x--x..x..x..x <- old "theirs" commits, now "ghosts", available through reflogs
    \
     \
      \--y--y--y--x'--x'--x'(*) <-  branch B with HEAD updated ("ours")
               ^
               |
        upstream branch

Note: the "upstream" notion is the referential set of data (a all repo or, like here, a branch) from which data are read or to which new data are added/created.

VonC
Chose promise chose due...
Benjol
@Benjol: just added a link to the "upstream" definition.
VonC