git pull VS git fetch Vs git rebase

294

Une autre question a dit git pullest comme un git fetch+ git merge.

Mais quelle est la différence entre git pullVS git fetch+ git rebase?

Michael
la source
2
quelqu'un devrait nettoyer le lien ... et je suis étonné du nombre de votes que cette autre question a obtenu.
xenoterracide
13
@xeno: Je pense que c'est juste un décompte du nombre de personnes qui vont "J'ai aussi eu cette question"
bobobobo
45
Un jour, je trouverai le temps de lire vraiment la documentation de git, mais d'ici là, j'ajoute mes votes à ce type de questions
Eran Medan

Réponses:

336

Il devrait être assez évident d'après votre question que vous ne posez en fait que la différence entre git mergeet git rebase.

Supposons donc que vous soyez dans le cas commun - vous avez effectué un certain travail sur votre branche principale et vous tirez de l'origine, qui a également effectué un certain travail. Après la récupération, les choses ressemblent à ceci:

- o - o - o - H - A - B - C (master)
               \
                P - Q - R (origin/master)

Si vous fusionnez à ce stade (le comportement par défaut de git pull), en supposant qu'il n'y a pas de conflits, vous vous retrouvez avec ceci:

- o - o - o - H - A - B - C - X (master)
               \             /
                P - Q - R --- (origin/master)

Si d'un autre côté vous avez fait le rebase approprié, vous vous retrouveriez avec ceci:

- o - o - o - H - P - Q - R - A' - B' - C' (master)
                          |
                          (origin/master)

Le contenu de votre arbre de travail devrait finir de la même manière dans les deux cas; vous venez de créer une histoire différente qui y mène . Le rebase réécrit votre historique, donnant l'impression que vous aviez validé par-dessus la nouvelle branche principale d'origine ( R), au lieu de l'endroit où vous l'aviez initialement validé ( H). Vous ne devez jamais utiliser l'approche de rebase si quelqu'un d'autre s'est déjà retiré de votre branche principale.

Enfin, notez que vous pouvez réellement configurer git pullune branche donnée pour utiliser le rebase au lieu de la fusion en définissant le paramètre config branch.<name>.rebasesur true. Vous pouvez également le faire pour une seule traction en utilisant git pull --rebase.

Cascabel
la source
39
Que se passe-t-il si vous deviez rebaser après que quelqu'un se soit déjà retiré de votre branche principale? Est-ce que cela briserait le repo?
Didier A.
12
Comment savoir si quelqu'un s'est retiré de votre branche principale?
Frank
29
Si vous ne savez pas avec certitude si quelqu'un ne l'a pas fait , vous devez supposer qu'il l'a fait.
Chris Down
4
Je pensais juste qu'à moins que vous ne poussiez également des changements ailleurs que sur origine / maître, je ne vois jamais de problème avec quelqu'un d'autre qui aurait retiré les changements en question, parce que si vous aviez déjà poussé ces changements à l'origine / maître, il n'y aurait rien à rebaser en premier lieu. Il me semble que l'avertissement n'a vraiment d'importance que dans les cas où vous avez quelque chose de plus complexe que X -> origine / X, mais je peux me tromper. Si quelqu'un connaît un scénario que je néglige, veuillez le partager.
neverfox
1
@SteveChambers Non, ce n'est pas le résultat. Les lignes représentent simplement l'ascendance de la validation, c'est-à-dire que A est le parent de B. Il n'y a aucune implication quant à savoir si Q ou B était le premier dans le temps. Toutes ces opérations sont basées sur des graphes de validation, pas sur le temps. Rebase transplante simplement certaines validations, avec le résultat que j'ai montré, quels que soient les horodatages de validation.
Cascabel
9

TLDR:

git pullest comme courir git fetchalors git merge
git pull --rebaseest comme git fetchalorsgit rebase

En réponse à votre première déclaration,

git pullc'est comme un git fetch+ git merge.

"Dans son mode par défaut, git pull est un raccourci pour git fetchsuivi de git mergeFETCH_HEAD" Plus précisément, git pulls'exécute git fetchavec les paramètres donnés, puis appelle git mergepour fusionner les têtes de branche récupérées dans la branche actuelle "

(Réf: https://git-scm.com/docs/git-pull )


Pour votre deuxième déclaration / question:

«Mais quelle est la différence entre git pullVS git fetch+ git rebase»

Encore une fois, de la même source:
git pull --rebase

"Avec --rebase, il exécute git rebase au lieu de git merge."


Maintenant, si vous vouliez demander

«la différence entre mergeet rebase»

cela est également répondu ici:
https://git-scm.com/book/en/v2/Git-Branching-Rebasing
(la différence entre la modification de la façon dont l'historique des versions est enregistré)

harshvchawla
la source
2
Je voudrais mentionner que "git pull --rebase" est comme "git fetch puis git rebase" la plupart du temps - mais pas toujours. Dans certaines situations, "git pull --rebase" fait un peu plus. Voir cet exemple souvent référencé ici: gitolite.com/git-pull--rebase
Daniel K.
1
Merci beaucoup pour votre réponse. Je comprends vraiment le git fetch + git rebasefonctionnement des commandes à partir de maintenant. Il n'y a plus ou moins de conflit sur notre arbre git à partir de maintenant :)
Travis Le