205 votes

git rebase, en gardant la trace de 'local' et de 'remote'

Lors d'une refonte de git, j'ai souvent du mal à comprendre ce qui se passe entre le "local" et le "distant" lors de la résolution de conflits. J'ai parfois l'impression qu'ils changent de côté d'un engagement à l'autre.

C'est probablement (définitivement) parce que je n'ai toujours pas bien compris.

Lors de la refonte, qui est «local» et qui est «distant»?

(J'utilise P4Merge pour résoudre les conflits)

286voto

VonC Points 414372

TL;DR;

Un rebase commutateurs ours (actuelles de la direction générale avant de rebase commence) et theirs (en amont de la branche en haut, vous voulez rebase).
Je soutiens 'local"est la branche courante, et 'remote' en amont de la branche.
Mais kutschkem souligne que, dans une interface graphique, mergetool contexte:

  • références locales, partiellement indexé s'engage: "ours" (de l'amont de la branche)
  • distance désigne les modifications entrantes: "theirs" - la branche courante avant de le rebase.

Voir les illustrations dans la dernière partie de cette réponse.

Que Benubird commentaires:

Pour résumer, lorsque:

git checkout A
git rebase   B    # rebase A on top of B
  • local est B,
  • remote est A

Inversion lorsque rebase

La confusion pourrait être liée à l' inversion de la nôtre et la leur au cours d'un rebase.
(extraits)

git rebase page de man:

Notez qu'un rebase fusion fonctionne en relisant chaque commit de la branche sur le dessus de l' <upstream> de la branche.

De ce fait, lorsqu'un conflit de fusion qui se passe:

  • le côté rapporté que 'ours"est la mesure relocalisée série, en commençant par <upstream>,
  • et 'theirs"est la branche. En d'autres termes, les côtés sont inversés.

Inversion illustré

Sur une fusion

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

nous n'avons pas changer la direction de 'B', donc ce que nous avons est toujours ce que nous étions (et nous fusion à partir d'une autre branche)

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

Sur un rebase:

Mais sur un rebase, nous changeons de côté parce que la première chose qu'un rebase n'est à la caisse de l'amont de la branche! (relire le courant s'engage sur le dessus de celui-ci)

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

Un git rebase upstream sera premier changement HEAD de B à l'amont de la branche HEAD (d'où le commutateur de "les nôtres" et "les leurs", par rapport à la précédente "actuel" de travail de la branche.)

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

et puis cela va de relecture de "leurs" s'engage sur la nouvelle 'notre' B branche:

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

Remarque: la "en amont", la notion est le référentiel de données (un toutes les pensions ou, comme ici, d'une branche) à partir duquel les données sont lues ou dans laquelle les nouvelles données sont ajoutées/créé.


'local"et"remote' vs. 'mine"et"theirs'

Pandawood ajoute dans les commentaires:

Pour moi, la question demeure, qui est "local" et qui est "à distance" (puisque les termes "nous" et "leurs" ne sont pas utilisés lors de la relocalisation dans git, se référant à eux semble juste pour faire une réponse plus à confusion).

Tout d'abord, dans le git rebase page de man, de "local" et "à distance" sont uniquement utilisées une fois, par opposition à "la nôtre" (8 fois) et "les leurs" (3 fois). Ils sont les termes pertinents ici.

Plus 'remote' n'a pas vraiment de sens: vous pouvez rebase sur le haut de la branche (l'un dans l' 'remotes' espace de noms, like 'origin/master' ou une nature purement locale 'myBranch')

"distant" est utilisée uniquement pour l' git rebase dans cette phrase:

si <upstream> n'est pas spécifié, l'amont configuré en branch.<name>.remote et branch.<name>.merge option.

C'est pourquoi j'ai répondu dans les commentaires:

  • "local" est "branche" (qui devient "theirs"),
  • "remote" est "en amont de la branche" (qui devient "ours").

Même si kutschkem semble pas d'accord, la définition même d'un rebase est:

De l'avant-port local s'engage à la mise à jour en amont de la tête

Ne pas mélanger:

  • "local" et le conflit maker 'mine' (c'est à dire qu'est-ce que le "travail" de la branche lors d'une fusion), qui vient de l' upstream de la branche depuis un git rebase commence par faire un checkout de l'amont de la branche, en faisant le travail.
  • 'à distance' et le conflit marqueur 'theirs': encore une fois, "distance" dans un git contexte n'est lié qu'à l'amont de la branche, et ne servent à rien lorsque l'on traite avec des conflits de fusion.

Par exemple, disons que vous êtes rebasage 'abranch' sur le haut de l' master:

git checkout abranch
git rebase master

Qui pourrait donner:

"first content" 
<<<<<<< HEAD
"a line for master" 
=======
"a line for abranch" 
>>>>>>> modif abranch"

Si vous obtenez un conflit, il ne serait pas logique de faire voir ce qui est "local" ou "à distance", mais plutôt:

  • qu'est - mine (en provenance du fichier en cours d'extraction, qui est dans ce cas, celui de l' master, en amont de la branche)
  • qu'est -'theirs' (venant de la direction de la fusion, qui est, ici, abranch, et qui a utilisé pour être le "travail" de la branche juste avant le rebase).

Dans ce contexte de conflit de fusion, de "local" ou "à distance" ne sont pas vraiment pertinents.
'mine', 'commun' et 'eux' sont pertinents, et l'inversion je décris est entre "la nôtre" (ou "mine") et "les leurs", qui diffère entre un git merge et git rebase.


GUI git mergetool

Cela étant dit, kutschkem ajoute, et à juste titre:

Lors de la résolution des conflits, git va dire quelque chose comme:

local: modified file and remote: modified file. 

Je suis tout à fait sûr que la question vise à la définition du local et à distance à ce point. À ce point, il me semble de mon expérience:

  • références locales, partiellement indexé s'engage: "ours" (de l'amont de la branche)
  • distance désigne les modifications entrantes: "theirs" - la branche courante avant de le rebase.

Eh bien... non, git merge et git rebase ne pas mentionner 'local"et"remote'.

  • une fusion avec le conflit dirais:
Auto-fusion f.txt
CONFLIT (contenu): conflit de Fusion dans f.txt
Automatique de fusion a échoué; résoudre les conflits puis de valider le résultat.
  • un rebase les conflits dirais:
Retomber à l'application des correctifs de base et 3-way merge...
Auto-fusion f.txt
CONFLIT (contenu): conflit de Fusion dans f.txt
Pas réussi à fusionner les modifications.
Patch a échoué à 0001 modif abranche"

Mais git mergetool n'est:

Merging:
f.txt

Normal merge conflict for 'f.txt':
  {local}: modified file
  {remote}: modified file
Hit return to start merge resolution tool (kdiff3):

Par exemple, KDiff3 serait d'affichage de la fusion de la résolution comme:

kdiff3

Et fusionner permettrait d' afficher trop:

Meld diff

De même pour VimDiff, qui affiche:

Invoquer Vimdiff comme un mergetool avec git mergetool -t gvimdiff. Les dernières versions de Git invoquer Vimdiff la fenêtre suivante mise en page:

+--------------------------------+
| LOCAL  |     BASE     | REMOTE |
+--------------------------------+
|             MERGED             |
+--------------------------------+
  • LOCAL:
    Un fichier temporaire contenant le contenu du fichier sur la branche courante.
  • BASE:
    Un fichier temporaire contenant la base commune pour la fusion.
  • REMOTE:
    Un fichier temporaire contenant le contenu du fichier fusionné.
  • MERGED:
  • Le fichier contenant les marqueurs de conflit.

Git a effectué autant automatique de la résolution des conflits que possible et l'état de ce fichier est une combinaison des deux LOCAL et REMOTE avec des marqueurs de conflit entourant tout ce que Git ne pouvait pas résoudre lui-même.
L' mergetool doit écrire le résultat de la résolution de ce fichier.

50voto

Kyralessa Points 76456

La ligne de fond

git rebase

  • LOCAL = la base, vous êtes rebasage sur
  • DISTANCE = les commits que vous vous déplacez sur le dessus

git merge

  • LOCAL = l'original de la direction générale, vous êtes en fusion
  • DISTANCE = l'autre branche dont vous engage regroupons dans

En d'autres termes, le LOCAL est toujours l'original, et la DISTANCE est toujours le gars dont le commet n'étaient pas là avant, parce qu'ils sont fusionnées ou relocalisée sur le dessus

Le prouver!

Certainement. Ne prenez pas mon mot pour lui! Voici une expérience facile que vous pouvez faire pour voir par vous-même.

Tout d'abord, assurez-vous d'avoir git mergetool configuré correctement. (Si vous ne l'avez pas, vous n'auriez probablement pas être la lecture de cette question de toute façon.) Ensuite, trouver un répertoire de travail.

Configurer votre dépôt:

md LocalRemoteTest
cd LocalRemoteTest

Créer un premier commit (avec un fichier vide):

git init
notepad file.txt  (use the text editor of your choice)
  (save the file as an empty file)
git add -A
git commit -m "Initial commit."

Créer un commit sur une branche qui n'est pas maître:

git checkout -b notmaster
notepad file.txt
  (add the text: notmaster)
  (save and exit)
git commit -a -m "Add notmaster text."

Créer un commit sur la branche master:

git checkout master
notepad file.txt
  (add the text: master)
  (save and exit)
git commit -a -m "Add master text."

gitk --all

À ce stade, votre référentiel devrait ressembler à ceci:

Repository with a base commit and two one-commit branches

Maintenant, pour le rebase test:

git checkout notmaster
git rebase master
  (you'll get a conflict message)
git mergetool
  LOCAL: master
  REMOTE: notmaster

Maintenant, la fusion de test. Fermer votre mergetool sans enregistrer les modifications, puis annuler le rebase:

git rebase --abort

Alors:

git checkout master
git merge notmaster
git mergetool
  LOCAL: master
  REMOTE: notmaster
git reset --hard  (cancels the merge)

Vos résultats doivent être les mêmes que ce qui est affiché en haut.

2voto

Je n’ai pas bien compris votre problème, mais je pense que le schéma suivant résout votre problème. (Base: référentiel distant ---> espace de travail)

http://assets.osteele.com/images/2008/git-transport.png

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X