Quelle est la différence entre ‘git merge’ et ‘git rebase’?

Quelle est la différence entre git merge et git rebase ?

Supposons à l’origine qu’il y ait 3 commits, A , B , C :

ABC

Ensuite, le développeur Dan a créé commit D , et le développeur Ed a créé E :

A-B-C-D-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 :

A-B-C-D-E-M

Les deux commits D et E sont toujours là, mais nous créons un commit de fusion M qui hérite des changements de D et E Cependant, cela crée une forme de diamant , que beaucoup de gens trouvent très déroutant.

REBASE :

A-B-C-D-E-R

Nous créons commit R , dont le contenu réel est identique à celui de merge commit M ci-dessus. Mais, nous nous débarrassons du commit E , comme il n’a jamais existé (désigné par des points – ligne de fuite). A cause de cette oblitération, E devrait être local pour le développeur Ed et ne devrait jamais avoir été poussé vers un autre référentiel. L’avantage de rebase est que la forme du diamant est évitée et que l’histoire rest en ligne droite – la plupart des développeurs aiment ça!

J’aime vraiment cet extrait de 10 choses que je déteste à propos de git (cela donne une brève explication de rebase dans son deuxième exemple):

3. Documentation délirante

Les pages de manuel en sont une toute puissante “f *** you” 1 . Ils décrivent les commandes du sharepoint vue d’un informaticien et non d’un utilisateur. Par 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, 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 

qui est une bonne description.


1. non censuré dans l’original

Personnellement, je ne trouve pas la technique de création de diagrammes standard très utile – les flèches semblent toujours me tromper. (Ils pointent généralement vers le “parent” de chaque commit, ce qui finit par être un retour en arrière, ce qui est étrange).

Pour l’expliquer en mots:

  • Lorsque vous rebase votre twig sur sa twig, vous dites à Git de faire en sorte que vous ayez correctement extrait sa twig, puis que vous ayez fait tout votre travail à partir de là. Cela fait un ensemble de modifications propres et conceptuellement simples que quelqu’un peut examiner. Vous pouvez répéter ce processus quand il y a de nouveaux changements sur leur twig, et vous vous retrouverez toujours avec un ensemble de modifications “sur la pointe” de leur twig.
  • Lorsque vous fusionnez leur twig dans votre twig, vous associez les deux historiques de twig à ce stade. Si vous recommencez plus tard avec d’autres modifications, vous commencez à créer un fil entrelacé d’histoires: certaines de leurs modifications, certains de mes changements, certains de leurs changements. Certaines personnes trouvent cela désordonné ou indésirable.

Pour des raisons que je ne comprends pas, les outils d’interface graphique pour Git n’ont jamais fait beaucoup d’efforts pour présenter les historiques de fusion plus proprement, en faisant abstraction des fusions individuelles. Donc, si vous voulez un “historique propre”, vous devez utiliser rebase.

Il me semble avoir lu des articles de blog de programmeurs qui n’utilisent que rebase et d’autres qui n’utilisent jamais de rebase.

Exemple

Je vais essayer d’expliquer cela avec un exemple de mots justes. Disons que d’autres personnes de votre projet travaillent sur l’interface utilisateur et que vous écrivez de la documentation. Sans rebase, votre historique pourrait ressembler à ceci:

 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 

C’est-à-dire que les fusions et l’interface utilisateur sont validées au milieu de vos validations de documentation.

Si vous rebasiez 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 rest de la twig principale.

( Déni de responsabilité: 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

  • «D’accord, nous avons deux états développés différemment de notre repository. Faisons les fusionner ensemble. Deux parents, un enfant en résultant.

rebase

  • “Donnez les modifications de la twig principale (quel que soit son nom) à ma twig. Faites-le en prétendant que mon travail sur les fonctionnalités a démarré plus tard, en fait sur l’état actuel de la twig principale.
  • “Réécrivez l’historique de mes modifications pour refléter cela.” (Nécessité de les forcer, car la gestion des versions consiste normalement à ne pas altérer l’historique donné)
  • “Probablement – si les modifications que j’ai apscopes ont peu à voir avec mon travail – l’histoire ne changera pas grand-chose si je regarde mes comms diff par diff (vous pouvez aussi penser à des” patchs “).”

résumé: Si possible, rebase est presque toujours meilleur. Faciliter la réintégration dans la twig principale.

Car? Work votre travail de fonctionnalité peut être présenté sous la forme d’ un gros «fichier de patch» (aka diff) par rapport à la twig principale, sans avoir à «expliquer» plusieurs parents: au moins deux, provenant d’une fusion, mais probablement beaucoup plus, s’il y en a étaient plusieurs fusions. Contrairement aux fusions, les rebases multiples ne s’additionnent pas. (un autre gros plus)

Git rebase est plus proche d’une fusion. La différence de rebase est la suivante:

  • les commits locaux sont supprimés temporairement de la twig.
  • courir le pull git
  • réinsérez tous vos commits locaux.

Cela signifie donc que tous vos commits locaux sont déplacés à la fin, après tous les commits à distance. Si vous avez un conflit de fusion, vous devez également le résoudre.

Pour comprendre facilement peut voir ma figure.

Rebase va changer le hash de commit, donc si vous voulez éviter beaucoup de conflits, utilisez simplement rebase lorsque cette twig est terminée / complète en tant que stable.

entrer la description de l'image ici