web-dev-qa-db-fra.com

Flux de production Git Cherry-pick vs Merge

En supposant que je sois le responsable d’un repo et que je veuille extraire les modifications d’un contributeur, il existe quelques workflows possibles:

  1. Je cherry-pick chaque validation de la télécommande (dans l’ordre). Dans ce cas, git enregistre la validation comme étant non liée à la branche distante.
  2. Je merge la branche, en prenant en compte toutes les modifications et en ajoutant un nouveau commit "conflict" (si nécessaire).
  3. Je merge chacun des commit de la branche distante individuellement (encore une fois dans l’ordre), ce qui permet d’enregistrer les conflits pour chaque commit, au lieu de les regrouper tous en un.
  4. Pour être complet, vous pouvez utiliser une option rebase (identique à l'option cherry-pick??). Toutefois, si j'ai bien compris, cela peut créer de la confusion pour le contributeur. Cela élimine peut-être l'option 1.

Dans les deux cas 2 et 3, git enregistre l'historique des branches des commits, contrairement à 1.

Quels sont les avantages et inconvénients de l'utilisation des méthodes cherry-pick ou merge décrites? Je pense que la méthode 2 est la norme, mais j'estime que la résolution d'un grand commit avec un fusion unique "conflit", n’est pas la solution la plus propre.

289
cmcginty

rebase (et cherry-pick) et merge ont tous deux des avantages et des inconvénients. Je plaide pour merge ici, mais cela vaut la peine de comprendre les deux. (Regardez ici pour un autre, bien argumenté réponse énumérant les cas où rebase est préféré.)

merge est préférable à cherry-pick et rebase pour plusieurs raisons.

  1. Robustesse . L'identifiant SHA1 d'une validation l'identifie non seulement en lui-même mais également par rapport à toutes les autres validations qui le précèdent. Cela vous garantit que l'état du référentiel à un SHA1 donné est identique pour tous les clones. En théorie, il n’ya aucune chance que quelqu'un ait fait ce qui ressemble au même changement mais corrompe ou détourne votre référentiel. Vous pouvez choisir les modifications individuelles et elles sont probablement les mêmes, mais vous n'avez aucune garantie. (En tant que problème secondaire mineur, les nouveaux commits choisis par cerisier prendront de la place si quelqu'un d'autre sélectionne à nouveau dans le même commis, car ils seront tous les deux présents dans l'historique, même si vos copies de travail sont identiques.)
  2. Facilité d'utilisation . Les gens ont tendance à comprendre le flux de travail merge assez facilement. rebase a tendance à être considéré comme plus avancé. Il est préférable de comprendre les deux, mais les personnes qui ne veulent pas être des experts en contrôle de version (qui, selon mon expérience, ont inclus de nombreux collègues extrêmement doués pour ce qu'ils font, mais ne veulent pas passer plus de temps) ont plus de facilité. le temps vient de fusionner.

Même avec un workflow lourd de fusion, rebase et cherry-pick restent utiles dans des cas particuliers:

  1. Un inconvénient de merge est une histoire encombrée. rebase empêche une longue série de commits de se disperser dans votre historique, comme cela serait le cas si vous fusionniez périodiquement avec les modifications des autres. C’est en fait son objectif principal, tel que je l’utilise. Ce que vous voulez être très prudent, ce n’est jamais le code rebase que vous avez partagé avec d’autres référentiels. Une fois qu'un commit est Pushed, quelqu'un d'autre aurait pu le commettre par-dessus, et le changement de base causera au mieux le type de duplication discuté ci-dessus. Au pire, vous pouvez vous retrouver avec un référentiel très confus et des erreurs subtiles, il vous faudra beaucoup de temps pour déceler.
  2. cherry-pick est utile pour échantillonner un petit sous-ensemble de modifications d'une branche de sujet que vous avez essentiellement décidé d'ignorer, mais que vous réaliserez qu'il contient quelques éléments utiles.

Pour ce qui est de préférer la fusion de plusieurs changements plutôt qu’un seul: c’est beaucoup plus simple. Il peut être très fastidieux de fusionner des ensembles de modifications individuels une fois que vous commencez à en avoir beaucoup. La résolution de fusion dans git (et dans Mercurial et dans Bazaar) est très très bonne. Vous ne rencontrerez pas de problèmes majeurs lors de la fusion de branches même longues la plupart du temps. En général, je fusionne tout en une seule fois si je reçois un grand nombre de conflits puis-je sauvegarder et réexécuter la fusion au coup par coup. Même alors je le fais en gros morceaux. Comme exemple très réel, un de mes collègues a dû fusionner pendant 3 mois et a eu quelque 9 000 conflits dans une base de code de 25 000 lignes. Ce que nous avons fait pour résoudre le problème, c’est la fusion, un mois à la fois: les conflits ne s’accumulent pas linéairement, et le faire par morceaux entraîne beaucoup moins que 9000 conflits. C'était encore beaucoup de travail, mais pas autant que d'essayer de le faire engagement par engagement.

280
quark

À mon avis, la sélection de cerises devrait être réservée aux rares situations où elle est requise, par exemple si vous fixez directement sur la branche "maître" (tronc, branche principale de développement) et que vous vous rendez compte qu'elle doit également s'appliquer à "maint". '. Vous devez baser le flux de travail soit sur la fusion, soit sur la base (ou "git pull --rebase").

Rappelez-vous que la validation sélectionnée ou redéfinie est différente du point de vue de Git (avec un identificateur SHA-1 différent) de l'original, elle est donc différente de la validation dans le référentiel distant. (Rebase peut généralement gérer cela, car il vérifie l'identifiant du correctif, c'est-à-dire les modifications, pas un identifiant de validation).

De plus, dans git, vous pouvez fusionner plusieurs branches à la fois: on appelle ainsi la fusion du poulpe . Notez que la fusion de poulpe doit réussir sans conflits. Néanmoins, cela pourrait être utile.

HTH.

93
Jakub Narębski