Quelle est la différence entre git merge
et git rebase
?
Supposons qu’il y avait initialement 3 commits, A
, B
, C
:
Ensuite, le développeur Dan a créé commit D
et le développeur Ed a créé commit E
:
De toute évidence, ce conflit devrait être résolu d’une manière ou d’une autre. Pour cela, il y a 2 façons:
FUSION:
Les deux commits D
et E
sont toujours présents, mais nous créons un commit de fusion M
qui hérite des modifications de D
et E
. Cependant, cela crée un losange , que beaucoup de gens trouvent très déroutant.
REBASE:
Nous créons commit R
, dont le contenu du fichier est identique à celui de merge commit M
ci-dessus. Mais nous nous débarrassons de commit E
, comme il n’a jamais existé (noté par des points - ligne de fuite). En raison de cette suppression, E
devrait être local pour le développeur Ed et n'aurait jamais dû être déplacé vers un autre référentiel. L'avantage de rebase est que le diamant est évité, et que l'histoire reste belle ligne droite - la plupart des développeurs adorent ça!
J'aime vraiment cet extrait de 10 choses que je déteste à propos de git (il donne une brève explication de rebase dans son deuxième exemple):
3. documentation de merde
Les pages de manuel sont un tout-puissant "f *** you"1. Ils décrivent les commandes du point de vue d'un informaticien et non d'un utilisateur. Exemple:
git-Push – Update remote refs along with associated objects
Voici une description pour les humains:
git-Push – Upload changes from your local repository into a remote repository
Mise à jour, un autre exemple: (merci cgd)
git-rebase – Forward-port local commits to the updated upstream head
Traduction:
git-rebase – Sequentially regenerate a series of commits so they can be applied directly to the head node
Et puis nous avons
git-merge - Join two or more development histories together
ce qui est une bonne description.
1. non censurée dans l'original
Personnellement, je ne trouve pas la technique standard de création de diagrammes très utile - les flèches semblent toujours indiquer le mauvais sens pour moi. (Ils pointent généralement vers le "parent" de chaque commit, ce qui finit par être en arrière dans le temps, ce qui est étrange).
Pour l'expliquer avec des mots:
Pour des raisons que je ne comprends pas, les outils d'interface graphique de Git n'ont jamais fait beaucoup d'efforts pour présenter les historiques de fusion plus clairement, en résumant les fusions individuelles. Donc, si vous voulez un "historique propre", vous devez utiliser rebase.
Je semble me souvenir d’avoir lu des articles de blog de programmeurs qui seulement utilisent rebase et d’autres qui jamais utilisent rebase.
Je vais essayer d'expliquer cela avec un exemple juste. Supposons que d'autres personnes de votre projet travaillent sur l'interface utilisateur et que vous rédigiez de la documentation. Sans rebase, votre historique pourrait ressembler à quelque chose comme:
Write tutorial
Merge remote-tracking branch 'Origin/master' into fixdocs
Bigger buttons
Drop down list
Extend README
Merge remote-tracking branch 'Origin/master' into fixdocs
Make window larger
Fix a mistake in howto.md
Autrement dit, les fusions et les validations d’UI se situent au milieu des validations de votre documentation.
Si vous rebasez votre code sur master au lieu de le fusionner, cela ressemblerait à ceci:
Write tutorial
Extend README
Fix a mistake in howto.md
Bigger buttons
Drop down list
Make window larger
Tous vos commits sont en haut (les plus récents), suivis du reste de la branche master
.
( Disclaimer: Je suis l'auteur du message "10 choses que je déteste à propos de Git" mentionné dans une autre réponse )
Bien que la réponse acceptée et la plus votée soit excellente, je trouve également utile d'essayer d'expliquer la différence uniquement par des mots:
fusionner
rebase
summary: Lorsque cela est possible, rebase est presque toujours préférable. Faciliter la réintégration dans la branche principale.
Parce que? Work votre travail de fonctionnalité peut être présenté comme n gros 'fichier de correctif' (diff aussi) en ce qui concerne la branche principale, sans avoir à 'expliquer' plusieurs parents: au moins deux, venant d'une fusion, mais probablement beaucoup plus, s'il y avait plusieurs fusions. Contrairement aux fusions, les répétitions multiples ne s'additionnent pas. (autre atout majeur)
Git Rebase est plus proche d'une fusion. La différence de rebase est la suivante:
Cela signifie donc que tous vos commits locaux sont déplacés à la fin, après tous les commits distants. Si vous avez un conflit de fusion, vous devez le résoudre aussi.