Git Rebase: les nôtres et les leurs, local et distant


Exemple

Une rebase change le sens de "notre" et "leurs":

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

Quelle que soit la direction de HEAD, c'est "la nôtre"

La première chose que fait un rebase est de réinitialiser le HEAD pour le master ; avant picorage engage de l'ancienne branche topic à un nouveau (tous les commits dans l'ancien topic branche sera réécrite et seront identifiés par un hachage différent).

En ce qui concerne les terminologies utilisées par les outils de fusion (à ne pas confondre avec ref local ou ref distant )

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

Cela signifie qu'un outil de fusion / diff présentera la branche en amont comme local ( master : la branche au-dessus de laquelle vous rebasez), et la branche de travail comme remote ( topic : la branche en cours de rebasage)

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

Inversion illustrée

Sur une fusion:

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

Nous ne changeons pas le topic branche actuelle, donc ce que nous avons est toujours ce sur quoi nous travaillions (et nous fusionnons à partir d'une autre branche)

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

Sur un rebase:

Mais sur une rebase, nous changeons de côté car la première chose que fait une rebase est de récupérer la branche en amont pour rejouer les commits en cours!

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

Un git rebase upstream abord HEAD sur la branche en amont, d'où le changement de «ours» et de «leurs» par rapport à la branche de travail «actuelle» précédente.

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"
               |
            upstream      

Le rebasage sera ensuite rejouer « leur » engage sur le nouveau « notre » topic branche:

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