Supposons que l' origine il y avait 3 commits, A, B, C:
Ensuite, le développeur Dan a créé la validation Det le développeur Ed a créé la validation E:
De toute évidence, ce conflit devrait être résolu d'une manière ou d'une autre. Pour cela, il existe 2 façons:
MERGE :
Les deux validations Det Esont toujours là, mais nous créons une validation de fusion Mqui hérite des modifications des deux Det E. Cependant, cela crée une forme de diamant , ce que beaucoup de gens trouvent très déroutant.
REBASE :
Nous créons un commit R, dont le contenu réel du fichier est identique à celui du commit de fusion Mci-dessus. Mais, nous nous débarrassons du commit E, comme il n'a jamais existé (indiqué par des points - ligne de fuite). En raison de cette oblitération, Edevrait être local pour le développeur Ed et n'aurait jamais dû être poussé vers un autre référentiel. L'avantage du rebase est que la forme de diamant est évitée et que l'histoire reste belle en ligne droite - la plupart des développeurs adorent ça!
Belles illustrations. Cependant, je ne suis pas entièrement d'accord avec le ton positif que le rebase est géré. Dans les deux fusionner et rebaser des conflits peuvent se produire qui nécessitent une résolution manuelle. Et comme toujours lorsque les programmeurs sont impliqués, il y a un risque non négligeable d'erreurs aka bugs. Si une erreur de fusion se produit, toute l'équipe ou la communauté peut voir la fusion et vérifier si un bogue y a été introduit. L'histoire du rebase reste dans le repo d'un développeur et même là, il n'a qu'une durée de vie limitée dans le reflog. Cela pourrait sembler plus joli, mais personne d'autre ne peut voir aussi facilement ce qui s'est mal passé.
Uwe Geuder
> "Cependant, cela crée une forme de diamant, ce que beaucoup de gens trouvent très déroutant." Um ... pouvez-vous élaborer?
Greg Maletic
@GregMaletic: La forme du diamant est une histoire non linéaire. Je ne sais pas pour vous, mais je n'aime pas les choses non linéaires en général. Cela dit, vous pouvez utiliser la fusion avec des diamants si vous le préférez vraiment - personne ne vous force.
mvp
1
Bien que cette réponse soit extrêmement utile, il serait préférable que vous ajoutiez des commandes git réelles avec de simples fichiers foo.txt pour les reproduire localement. Comme l'a dit le dernier utilisateur, il n'est pas évident de savoir qui fait le rebase.
Vortex
1
@pferrel: Je ne pense pas que vous l'ayez correctement compris. git mergen'entrelace pas les commits (mais cela peut apparaître ainsi en regardant git log). Au lieu de cela, git mergeconserve les deux histoires de développement de Dan et Ed intactes, comme cela a été vu de chaque point de vue à la fois. git rebasedonne l'impression que Dan y a travaillé en premier, et Ed l'a suivi. Dans les deux cas (fusion et rebase), l'arborescence de fichiers résultante réelle est absolument identique.
Les pages de manuel sont un tout-puissant «f *** you» 1 . Ils décrivent les commandes du point de vue d'un informaticien, pas d'un utilisateur. Exemple concret:
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
Le problème n'est pas la langue ou si l'utilisateur est un informaticien ou non. Si le reformuler d'une autre manière aide à clarifier les fins (c'est-à-dire ce qui se passe), il ne parvient pas à expliquer les moyens (comment cela se produit). Git nécessite de comprendre les moyens pour comprendre les fins. C'est précisément comprendre les moyens qui rendent Git si difficile. En tant qu'outil, quelque chose utilisé pour simplifier ou réduire l'effort requis dans la tâche, Git échoue horriblement. Malheureusement, trop de développeurs ne le réalisent pas.
ATL_DEV
128
Personnellement, je ne trouve pas la technique de diagramme standard 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, qui finit par être en arrière dans le temps, ce qui est bizarre).
Pour l'expliquer avec des mots:
Lorsque vous rebasez votre branche sur sa branche, vous dites à Git de donner l' impression que vous avez bien extrait sa branche, puis avez fait tout votre travail à partir de là. Cela fait un ensemble de changements propre et conceptuellement simple que quelqu'un peut examiner. Vous pouvez répéter ce processus à nouveau lorsqu'il y a de nouveaux changements sur leur branche, et vous vous retrouverez toujours avec un ensemble propre de changements "sur la pointe" de leur branche.
Lorsque vous fusionnez leur branche dans votre branche, vous liez les deux historiques de branche ensemble à ce stade. Si vous recommencez plus tard avec plus de changements, vous commencez à créer un fil d'histoires entrelacées: certains de leurs changements, 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 GUI pour Git n'ont jamais fait beaucoup d'efforts pour présenter les histoires de fusion plus proprement, en faisant abstraction des fusions individuelles. Donc, si vous voulez un "historique propre", vous devez utiliser le rebase.
Je me souviens d' avoir lu les messages du blog de programmeurs qui n'utilisent rebasage et d' autres qui n'utilisent rebasage.
Exemple
Je vais essayer d'expliquer cela avec un exemple de mots justes. Supposons que d'autres personnes sur votre projet travaillent sur l'interface utilisateur et que vous rédigez de la documentation. Sans rebase, votre historique pourrait ressembler à:
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 de l'interface utilisateur 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 reste de la masterbranche.
( Avertissement: 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 obtenu deux états développés différemment de notre référentiel. Fusionnons-les ensemble. Deux parents, un enfant résultant. "
rebaser
«Donnez les modifications de la branche principale (quel que soit son nom) à ma branche de fonctionnalité. Faites-le en prétendant que mon travail sur les longs métrages a commencé plus tard, en fait sur l'état actuel de la branche principale. »
"Réécrivez l'historique de mes modifications pour refléter cela." (besoin de les forcer, car normalement le versioning consiste à ne pas altérer l'historique donné)
"Probablement - si les changements que j'ai ratifiés ont peu à voir avec mon travail - l'histoire ne changera pas grand-chose, si je regarde mes commits diff par diff (vous pouvez aussi penser à des" patchs ")."
résumé: Lorsque cela est possible, le rebasage est presque toujours meilleur. Faciliter la réintégration dans la branche principale.
Parce que? Work votre travail de fonctionnalité peut être présenté comme un gros `` fichier patch '' (alias diff) en ce qui concerne la branche principale, sans avoir à `` expliquer '' plusieurs parents: au moins deux, provenant d'une fusion, mais probablement beaucoup plus, s'il y a étaient plusieurs fusions. Contrairement aux fusions, plusieurs rebases ne s'additionnent pas. (un autre gros avantage)
Git rebase est plus proche d'une fusion. La différence de rebase est:
les commits locaux sont supprimés temporairement de la branche.
exécuter le git pull
réinsérez tous vos commits locaux.
Cela signifie donc que toutes vos validations locales sont déplacées à la fin, après toutes les validations distantes. Si vous avez un conflit de fusion, vous devez également le résoudre.
Pour une compréhension facile peut voir ma figure.
Rebase changera le hachage de validation, de sorte que si vous voulez éviter beaucoup de conflits, utilisez simplement rebase lorsque cette branche est terminée / terminée comme stable.
J'ai trouvé un article vraiment intéressant sur git rebase vs merge , j'ai pensé le partager ici
Si vous voulez voir l'historique complètement comme il s'est produit, vous devez utiliser la fusion. La fusion préserve l'historique tandis que le rebase le réécrit.
La fusion ajoute un nouveau commit à votre historique
Le rebasage est préférable pour rationaliser un historique complexe, vous pouvez modifier l'historique de validation par rebase interactif.
Réponses:
Supposons que l' origine il y avait 3 commits,
A
,B
,C
:Ensuite, le développeur Dan a créé la validation
D
et le développeur Ed a créé la validationE
:De toute évidence, ce conflit devrait être résolu d'une manière ou d'une autre. Pour cela, il existe 2 façons:
MERGE :
Les deux validations
D
etE
sont toujours là, mais nous créons une validation de fusionM
qui hérite des modifications des deuxD
etE
. Cependant, cela crée une forme de diamant , ce que beaucoup de gens trouvent très déroutant.REBASE :
Nous créons un commit
R
, dont le contenu réel du fichier est identique à celui du commit de fusionM
ci-dessus. Mais, nous nous débarrassons du commitE
, comme il n'a jamais existé (indiqué par des points - ligne de fuite). En raison de cette oblitération,E
devrait être local pour le développeur Ed et n'aurait jamais dû être poussé vers un autre référentiel. L'avantage du rebase est que la forme de diamant est évitée et que l'histoire reste belle en ligne droite - la plupart des développeurs adorent ça!la source
git merge
n'entrelace pas les commits (mais cela peut apparaître ainsi en regardantgit log
). Au lieu de cela,git merge
conserve les deux histoires de développement de Dan et Ed intactes, comme cela a été vu de chaque point de vue à la fois.git rebase
donne l'impression que Dan y a travaillé en premier, et Ed l'a suivi. Dans les deux cas (fusion et rebase), l'arborescence de fichiers résultante réelle est absolument identique.J'adore 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):
Et puis nous avons
ce qui est une bonne description.
1. non censuré dans l'original
la source
Personnellement, je ne trouve pas la technique de diagramme standard 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, qui finit par être en arrière dans le temps, ce qui est bizarre).
Pour l'expliquer avec des mots:
Pour des raisons que je ne comprends pas, les outils GUI pour Git n'ont jamais fait beaucoup d'efforts pour présenter les histoires de fusion plus proprement, en faisant abstraction des fusions individuelles. Donc, si vous voulez un "historique propre", vous devez utiliser le rebase.
Je me souviens d' avoir lu les messages du blog de programmeurs qui n'utilisent rebasage et d' autres qui n'utilisent rebasage.
Exemple
Je vais essayer d'expliquer cela avec un exemple de mots justes. Supposons que d'autres personnes sur votre projet travaillent sur l'interface utilisateur et que vous rédigez de la documentation. Sans rebase, votre historique pourrait ressembler à:
Autrement dit, les fusions et les validations de l'interface utilisateur au milieu de vos validations de documentation.
Si vous rebasiez votre code sur master au lieu de le fusionner, cela ressemblerait à ceci:
Tous vos commits sont en haut (les plus récents), suivis du reste de la
master
branche.( Avertissement: je suis l'auteur du message "10 choses que je déteste à propos de Git" mentionné dans une autre réponse )
la source
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
rebaser
résumé: Lorsque cela est possible, le rebasage est presque toujours meilleur. Faciliter la réintégration dans la branche principale.
Parce que? Work votre travail de fonctionnalité peut être présenté comme un gros `` fichier patch '' (alias diff) en ce qui concerne la branche principale, sans avoir à `` expliquer '' plusieurs parents: au moins deux, provenant d'une fusion, mais probablement beaucoup plus, s'il y a étaient plusieurs fusions. Contrairement aux fusions, plusieurs rebases ne s'additionnent pas. (un autre gros avantage)
la source
Git rebase est plus proche d'une fusion. La différence de rebase est:
Cela signifie donc que toutes vos validations locales sont déplacées à la fin, après toutes les validations distantes. Si vous avez un conflit de fusion, vous devez également le résoudre.
la source
Pour une compréhension facile peut voir ma figure.
Rebase changera le hachage de validation, de sorte que si vous voulez éviter beaucoup de conflits, utilisez simplement rebase lorsque cette branche est terminée / terminée comme stable.
la source
J'ai trouvé un article vraiment intéressant sur git rebase vs merge , j'ai pensé le partager ici
la source