Git Cherry-pick vs Merge Workflow

en supposant que je suis le mainteneur d'une pension, et je veux tirer dans les changements d'un contributeur, il y a quelques workflows possibles:

  1. I cherry-pick chaque commit depuis la télécommande (dans l'ordre). Dans ce cas, git enregistre la propagation sans lien avec la branche distante.
  2. je merge la branche, en tirant dans tous les changements, et l'ajout d'un nouveau "conflit" commit (si nécessaire).
  3. I merge chaque la branche distante individuellement (encore une fois dans l'ordre), permettant d'enregistrer les conflits pour chaque propagation, au lieu de les regrouper tous en un seul.
  4. pour être complet, vous pouvez faire un rebase (même que cherry-pick option?), mais je crois comprendre que cela peut être source de confusion pour le donateur. Peut-être que ça élimine l'option 1.

dans les deux cas 2 et 3, git enregistre l'historique de la branche des commits, contrairement à 1.

Quels sont les avantages et les inconvénients entre l'utilisation des méthodes cherry-pick ou merge décrites? ma compréhension est que la méthode 2 est la norme, mais je pense que la résolution d'un grand commit avec un seul "conflit" Fusion, n'est pas la solution la plus propre.

277
demandé sur cmcginty 2009-08-07 01:50:25

3 réponses

les deux rebase (et cherry-pick ) et merge ont leurs avantages et inconvénients. Je plaide pour merge ici, mais ça vaut la peine de comprendre les deux. (Voir ici pour une alternative, bien argumentée réponse énumérant les cas où rebase est préférable.)

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

  1. Robustesse . L'identifiant SHA1 d'une commit l'identifie non seulement en lui-même mais aussi par rapport à toutes les autres commits qui le précèdent. Cela vous offre la garantie que L'état du dépôt à un SHA1 donné est identique pour tous les clones. Il n'y a (en théorie) aucune chance que quelqu'un ait fait ce qui ressemble au même changement mais qui corrompt ou détourne votre dépôt. Vous pouvez choisir dans les changements individuels et ils sont même, mais vous n'avez aucune garantie. (Le mineur comme une question secondaire de la nouvelle cerise cueillies s'engage prendra de l'espace supplémentaire si quelqu'un d'autre à la cerise se ramasse dans la même livraison, ils seront tous deux présents dans l'histoire, même si vos copies de travail finissent par être identiques.)
  2. facilité d'utilisation . Les gens ont tendance à comprendre le flux de travail merge assez facilement. rebase tend à être considéré comme plus avancé. Il est préférable de comprendre les deux, mais les gens qui ne veulent pas être des experts dans le contrôle de version (qui dans mon expérience a inclus De nombreux collègues qui sont sacrément bons à ce qu'ils font, mais ne veulent pas passer le temps supplémentaire) ont un temps plus facile juste la fusion.

même avec une fusion-flux de travail lourd rebase et cherry-pick sont encore utiles pour des cas particuliers:

  1. un des inconvénients de merge est l'histoire encombrée. rebase empêche une longue série de commits d'être dispersés dans votre histoire, comme ils le seraient si vous périodiquement fusionné à d'autres changements. C'est en fait son principal objectif que je l'utilise. Ce que vous voulez être très prudent de, n'est jamais rebase code que vous avez partagé avec d'autres dépôts. Une fois qu'un commit est push ed quelqu'un d'autre pourrait avoir commis sur elle, et rebaser sera au mieux cause du type de duplication discuté ci-dessus. Au pire, vous pouvez vous retrouver avec un un dépôt très confus et des erreurs subtiles il vous faudra beaucoup de temps pour les débusquer.
  2. cherry-pick est utile pour échantillonner un petit sous-ensemble de changements d'une branche de sujet que vous avez essentiellement décidé de jeter, mais réalisé qu'il ya un couple de pièces utiles sur.

quant à la préférence de fusionner plusieurs changements plutôt qu'un seul: c'est juste beaucoup plus simple. Il peut devenir très fastidieux de faire des fusions de changesets individuels une fois que vous commencez à avoir beaucoup d'entre eux. La résolution de fusion dans git (et dans Mercurial, et dans Bazaar) est très bonne. Vous ne rencontrerez pas de problèmes majeurs en fusionnant même les longues branches la plupart du temps. Je fusionne généralement tout en une seule fois et seulement si je reçois un grand nombre de conflits que je sauvegarder et relancer la fusion au coup par coup. Même alors, je n'en gros morceaux. Comme un exemple très réel, j'ai eu un collègue qui avait 3 mois de changements à fusionner, et a obtenu quelque 9000 conflits dans 250000 ligne base de code. Ce que nous avons fait pour corriger est de faire la fusion un mois de valeur à la fois: les conflits ne s'accumulent pas de façon linéaire, et le faire en morceaux résulte en loin moins de 9000 conflits. Il avait encore beaucoup de travail, mais pas autant que d'essayer de faire un commit à la fois.

266
répondu quark 2017-05-23 10:31:16

à mon avis, la cueillette de cerises devrait être réservée à des situations rares où elle est nécessaire, par exemple si vous avez fait quelques fixations directement sur la branche 'master' (tronc, branche principale de développement) et que vous avez ensuite réalisé qu'elle devrait être appliquée aussi à 'maint'. Vous devez baser le flux de travail soit sur la fusion, soit sur rebase (ou "git pull --rebase").

s'il vous Plaît rappelez-vous que la cerise cueillies ou relocalisée commettre est différents du point de vue de Git (a différent de L'identifiant SHA-1) que l'original, il est donc différent de la propagation dans le dépôt distant. (Rebase peut généralement gérer cela, car il vérifie le patch id, c'est-à-dire les modifications, pas un commit id).

aussi dans git vous pouvez fusionner plusieurs branches à la fois: ainsi appelé Octopus merge . Notez que octopus merge doit réussir sans conflits. Néanmoins, il pourrait être utile.

HTH.

89
répondu Jakub Narębski 2009-08-08 12:22:19

Rebase et Cherry-pick est le seul moyen de garder propre l'histoire de commit. Évitez d'utiliser la fusion et évitez de créer un conflit de fusion. Si vous utilisez gerrit, définissez un projet pour fusionner si nécessaire et un projet pour choisir le mode et essayer vous-même.

-4
répondu Nagaraj Magadum 2017-12-13 06:10:38