213 votes

Comment fonctionne la fusion git après cherry-pick ?

Imaginons que nous ayons un master branche.

Ensuite, nous créons un newbranch

git checkout -b newbranch

et faire deux nouveaux commits dans newbranch : commettre1 y commettre2

Puis nous passons à master et faisons cherry-pick

git checkout master
git cherry-pick hash_of_commit1

Regarder dans gitk nous voyons que commettre1 et sa version "cherry-picked" ont des hashs différents, donc techniquement ce sont deux commits différents.

Enfin, nous fusionnons newbranch en master :

git merge newbranch

et voir que ces deux commits avec des hachages différents ont été fusionnés sans problèmes bien qu'ils impliquent que les mêmes changements soient appliqués deux fois, donc l'un d'eux devrait échouer.

Est-ce que git fait vraiment une analyse intelligente du contenu des commits lors de la fusion et décide que les changements ne doivent pas être appliqués deux fois ou que ces commits sont marqués en interne comme liés entre eux ?

148voto

helmbert Points 1870

Réponse courte

Ne vous inquiétez pas, Git s'en occupe.

Réponse longue

Contrairement à SVN, par exemple 1 Git ne stocke pas les commits au format delta, mais est basé sur des instantanés 2,3 . Alors que SVN essaierait naïvement d'appliquer chaque commit fusionné comme un patch (et échouerait, pour la raison exacte que vous avez décrite), Git est généralement capable de gérer ce scénario.

Lors de la fusion, Git essaiera de combiner les instantanés des deux commits HEAD en un nouvel instantané. Si une portion de code ou un fichier est identique dans les deux snapshots (c'est-à-dire parce qu'un commit a déjà été cherry-pické), Git n'y touchera pas.

Sources

1 Skip-Deltas dans Subversion
2 Les bases de Git
3 Le modèle objet de Git

50 votes

En fait, je dirais vous devriez vous soucier de la fusion et "git s'en chargera" n'est pas une bonne règle de base.

6 votes

En fait, la fusion peut aboutir à un contenu dupliqué dans certains cas. Git le gère parfois, mais parfois non.

0 votes

C'est horriblement mal. Got stocke les fichiers sous toutes les formes possibles. Et si je me souviens bien, SVN avait l'habitude de stocker des snapshots.

60voto

ephemerr Points 756

Après une telle fusion, vous pouvez avoir choisi deux fois les commits de l'historique.

Solution pour éviter cela, je cite article qui recommande pour les branches avec des commits dupliqués (cherry-picked) d'utiliser rebase avant merge :

git merge après git cherry-pick : éviter les commits dupliqués

Imaginons que nous ayons la branche master et une branche b :

   o---X   <-- master
    \
     b1---b2---b3---b4   <-- b

Maintenant, nous avons besoin de façon urgente des commits b1 et b3 dans master, mais pas des commits mais pas des commits restants dans b. Donc ce que nous faisons est de vérifier la branche master et extraire les commits b1 et b3 :

$ git checkout master
$ git cherry-pick "b1's SHA"
$ git cherry-pick "b3's SHA"

Le résultat serait :

   o---X---b1'---b3'   <-- master
    \
     b1---b2---b3---b4   <-- b

Disons qu'on fait un autre commit sur master et on obtient :

   o---X---b1'---b3'---Y   <-- master
    \
     b1---b2---b3---b4   <-- b

Si nous voulions maintenant fusionner la branche b dans master :

$ git merge b

Nous obtiendrions ce qui suit :

   o---X---b1'---b3'---Y--- M  <-- master
     \                     /
      b1----b2----b3----b4   <-- b

Cela signifie que les changements introduits par b1 et b3 apparaîtraient deux fois dans l'historique. Pour éviter cela, nous pouvons rebaser au lieu de fusionner :

$ git rebase master b

Ce qui donnerait :

   o---X---b1'---b3'---Y   <-- master
                        \
                         b2'---b4'   <-- b

Enfin :

$ git checkout master
$ git merge b

nous donne :

   o---X---b1'---b3'---Y---b2'---b4'   <-- master, b

EDIT Corrections supposées par le commentaire de David Lemon

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