1193 votes

Comment fusionner un commit spécifique dans Git

J'ai forké une branche à partir d'un dépôt sur GitHub et commis quelque chose de spécifique pour moi. Maintenant, j'ai découvert que le dépôt original avait une fonctionnalité intéressante qui se trouvait à HEAD.

Je veux la fusionner uniquement sans les commits précédents. Que dois-je faire? Je sais comment fusionner tous les commits :

git branch -b une-bonne-fonctionnalite
git pull dépôt master
git checkout master
git merge une-bonne-fonctionnalite
git commit -a
git push

0 votes

Si vous essayez de faire cela par rapport à GitHub, cet article vous guidera à travers cela. markosullivan.ca/how-to-handle-a-pull-request-from-github

28voto

Si vous avez commis des changements à la branche principale. Maintenant, vous voulez déplacer ce même commit vers la branche de sortie. Vérifiez l'identifiant du commit (par exemple: xyzabc123) pour le commit.

Essayez maintenant de suivre les commandes

git checkout release-branch
git cherry-pick xyzabc123
git push origin release-branch

26voto

LarsH Points 14726

Les réponses principales décrivent comment appliquer les modifications depuis un commit spécifique sur la branche actuelle. Si c'est ce que vous entendez par "comment fusionner", alors utilisez simplement cherry-pick comme ils le suggèrent.

Mais si vous voulez vraiment une fusion, c'est-à-dire que vous voulez un nouveau commit avec deux parents -- le commit existant sur la branche actuelle et le commit dont vous vouliez appliquer les modifications -- alors un cherry-pick ne permettra pas cela.

Avoir un historique de fusion véritable peut être souhaitable, par exemple, si votre processus de build utilise l'ascendance git pour définir automatiquement les chaînes de versions en se basant sur la dernière balise (en utilisant git describe).

Au lieu de cherry-pick, vous pouvez effectuer une réelle fusion git --no-commit, puis ajuster manuellement l'index pour supprimer les modifications indésirables.

Supposons que vous êtes sur la branche A et que vous voulez fusionner le commit à la pointe de la branche B:

git checkout A
git merge --no-commit B

Maintenant vous êtes prêt à créer un commit avec deux parents, les commits de pointe actuels de A et B. Cependant, vous pouvez avoir plus de modifications appliquées que ce que vous voulez, y compris des modifications des commits antérieurs sur la branche B. Vous devez annuler ces modifications indésirables, puis commettre.

(Il peut y avoir une manière facile de remettre l'état du répertoire de travail et de l'index comme il était avant la fusion, afin que vous ayez une base propre sur laquelle cherry-pick le commit que vous vouliez au départ. Mais je ne sais pas comment obtenir cette base propre. git checkout HEAD et git reset HEAD supprimeront tous les états de fusion, contredisant le but de cette méthode.)

Donc annulez manuellement les modifications indésirables. Par exemple, vous pourriez

git revert --no-commit 012ea56

pour chaque commit indésirable 012ea56.

Lorsque vous avez terminé d'ajuster les choses, créez votre commit:

git commit -m "Fusion du commit 823749a de B qui a modifié le code de délai d'attente"

Maintenant, vous n'avez que la modification désirée, et l'arbre de l'ascendance montre que vous avez techniquement fusionné depuis B.

12voto

Rishabh Agarwal Points 165

Nous devrons utiliser git cherry-pick

Scénario : Je suis sur une branche appelée release et je veux ajouter seulement quelques changements de la branche master à la branche release.

Étape 1 : basculez sur la branche où vous voulez ajouter les changements

git checkout release

Étape 2 : obtenez le numéro de commit des changements que vous voulez ajouter

par exemple

git cherry-pick 634af7b56ec

Étape 3 : git push

Remarque : Chaque fois que vous fusionnez, un numéro de commit séparé est créé. Ne prenez pas le numéro de commit pour la fusion qui ne fonctionnera pas. Au lieu de cela, prenez le numéro de commit pour tout commit régulier que vous voulez ajouter.

7voto

nrkkalyan Points 43

Dans mon cas d'utilisation, nous avions un besoin similaire de CI CD. Nous avons utilisé git flow avec les branches develop et master. Les développeurs sont libres de fusionner leurs modifications directement avec develop ou via une pull request à partir d'une branche de fonctionnalité. Cependant, pour master, nous fusionnons uniquement les commits stables de la branche develop de manière automatisée via Jenkins.

Dans ce cas, utiliser cherry-pick n'est pas une bonne option. Cependant, nous créons une branche locale à partir de l'identifiant de commit, puis fusionnons cette branche locale avec master et exécutons mvn clean verify (nous utilisons maven). En cas de succès, nous publions la version de production de l'artifact sur nexus en utilisant le plugin de publication Maven avec l'option localCheckout=true et pushChanges=false. Enfin, lorsque tout est réussi, nous poussons les modifications et le tag vers l'origine.

Un extrait de code exemple:

En supposant que vous êtes sur master si vous le faites manuellement. Cependant, sur Jenkins, lorsque vous récupérez le dépôt, vous serez sur la branche par défaut (master si configuré).

git pull // Juste pour récupérer les modifications.
git branch local-  // Créer une branche à partir du commit-id donné
git merge local- // Fusionner cette branche locale avec master.
mvn clean verify // Vérifier si le code peut être compilé
mvn  release:clean release:prepare release:perform // Publier les artefacts
git push origin/master // Pousser les modifications locales effectuées ci-dessus vers l'origine.
git push origin  // Pousser le tag vers l'origine

Cela vous donnera un contrôle total avec une fusion sans peur ou enfer des conflits.

N'hésitez pas à donner des conseils s'il existe une meilleure option.

4voto

Si vous êtes nouveau sur cherrypick, essayez la version bureau de GitHub, lorsque vous sélectionnez l'option cherry-pick, GitHub vous demandera de choisir la branche sur laquelle vous souhaitez pousser une validation.

1)

entrer la description de l'image ici

2)

entrer la description de l'image ici

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