web-dev-qa-db-fra.com

Tirez tous les validations d'une branche, Poussez les validations spécifiques vers une autre

J'ai les branches suivantes:

  • master
  • production

et les branches distantes suivantes:

  • Origin/master
  • Origin/production

J'ai un script qui récupère le Origin/master branche et obtient la différence de ce qui a changé depuis ma dernière extraction (log -p master..Origin/master). Ensuite, je fusionne Origin/master.

Les validations trouvées sont transmises à un outil de révision de code.

Je veux pousser les commits réussis - et seulement eux - vers la branche de production, puis bien sûr vers Origin/production.

Comment faire?

De plus, j'ai 2 scripts en cours d'exécution: celui qui va de Origin/master, Push valide les détails dans une base de données et fusionne, et l'autre que j'écris actuellement qui devra pousser les validations réussies.

J'aimerais que ces 2 scripts soient exécutés tout en évitant les conditions de concurrence/les conflits de fusion. Étant donné que je souhaite uniquement travailler avec des validations spécifiées, il existe peut-être un moyen de supprimer les validations dont je ne veux pas?

92
Sylvain

Le terme que je pense que vous recherchez est un "choix de cerise". C'est-à-dire, prenez un seul commit au milieu d'une branche et ajoutez-le à un autre:

A-----B------C
 \
  \
   D

devient

A-----B------C
 \
  \
   D-----C'

Ceci, bien sûr, peut être fait avec la commande git cherry-pick.

Le problème avec cette validation est que git considère que les validations incluent tout l'historique avant elles - donc, si vous avez trois validations comme ceci:

A-----B-----C

Et essayez de vous débarrasser de B, vous devez créer un commit entièrement nouveau comme ceci:

A-----------C'

Où C 'a un ID SHA-1 différent. De même, choisir un commit d'une branche à une autre implique de générer un patch, puis de l'appliquer, perdant ainsi l'historique de cette manière également.

Ce changement d'ID de commit rompt entre autres la fonctionnalité de fusion de git (bien que s'il est utilisé avec parcimonie, il y a des heuristiques qui vont s'en occuper). Plus important encore, il ignore les dépendances fonctionnelles - si C a effectivement utilisé une fonction définie en B, vous ne le saurez jamais.

Peut-être qu'une meilleure façon de gérer cela serait d'avoir plus de branches à grains fins. Autrement dit, au lieu de simplement avoir un "maître", ayez "featureA", "bugfixB", etc. Effectuez un examen du code sur une branche entière à la fois - où chaque branche est très concentrée sur ne faire qu'une seule chose - puis fusionnez une branche quand vous avez terminé. C'est le workflow pour lequel git est conçu, et à quoi il sert :)

Si vous insistez pour traiter des choses au niveau des correctifs, vous voudrez peut-être regarder les darcs - il considère un référentiel comme un ensemble de correctifs, et donc la sélection des cerises devient l'opération fondamentale. Cependant, cela a son propre ensemble de problèmes, comme être très lent :)

Edit: De plus, je ne suis pas sûr de comprendre votre deuxième question, sur les deux scripts. Peut-être pourriez-vous le décrire plus en détail, peut-être comme une question distincte pour éviter que les choses ne deviennent confuses?

289
bdonlan

Je réalise que c'est une vieille question, mais est référencée ici: Comment fusionner un commit spécifique dans Git

Par conséquent, une réponse plus récente: utilisez les branches de fonctionnalités et les demandes d'extraction.

À quoi cela ressemble, où fA est un commit avec la fonctionnalité A et fB est un commit avec la fonctionnalité B:

            fA   fC (bad commit, don't merge)
           /  \ /
master ----A----B----C
                \  /
                 fB

Les demandes d'extraction sont associées à la fonctionnalité de GitHub, mais tout ce que je veux dire, c'est que quelqu'un a la responsabilité de fusionner les branches de fonctionnalité en maître.

1
MattJenko