Partie cherry-picking un commit avec Git

je travaille sur 2 branches différentes: release et development .

j'ai remarqué que j'ai encore besoin d'intégrer certains changements qui ont été engagés pour la branche release dans la branche development .

le problème est que je n'ai pas besoin de tout le commit, seulement quelques morceaux dans certains fichiers, donc un simple

git cherry-pick bc66559

ne fait pas l'affaire.

quand je fais un

git show bc66559

je peux voir la différence, mais je ne connais pas vraiment une bonne façon de l'appliquer partiellement à mon arbre de travail actuel.

440
demandé sur Mateusz Piotrowski 2009-10-06 18:47:04

5 réponses

la chose principale que vous allez vouloir ici est git add -p ( -p est un synonyme de --patch ). Cela fournit une façon interactive de vérifier le contenu, vous laissant décider si chaque morceau doit entrer, et même vous laissant éditer manuellement le patch si nécessaire.

pour l'utiliser en combinaison avec la cerise-pick:

git cherry-pick -n <commit> # get your patch, but don't commit (-n = --no-commit)
git reset                   # unstage the changes from the cherry-picked commit
git add -p                  # make all your choices (add the changes you do want)
git commit                  # make the commit!

(merci à Tim Henigan de me rappeler que git-cherry-pick a une option --no-commit, et merci à Felix Rabe pour avoir fait remarquer que vous devez réinitialiser! Si vous ne voulez laisser que quelques choses hors de la propagation, vous pouvez utiliser git reset <path>... pour déballer seulement ces fichiers.)

vous pouvez bien sûr fournir des chemins spécifiques à add -p si nécessaire. Si vous commencez avec un patch, vous pouvez remplacer le cherry-pick par apply .


Si vous voulez vraiment un git cherry-pick -p <commit> (cette option n'existe pas), vous pouvez utiliser

git checkout -p <commit>

qui différenciera la propagation courante de la propagation que vous spécifiez, et vous permettra d'appliquer des morceaux de cette différenciation individuellement. Cette option peut être plus utile si la propagation que vous effectuez a des conflits de fusion dans une partie de la propagation qui ne vous intéresse pas. (Note, cependant, que checkout diffère de cherry-pick : checkout tente d'appliquer <commit> 'S contenu entièrement, cherry-pick applique la diff du commit spécifié de son parent. Cela signifie que checkout peut s'appliquer plus que juste ce commit, qui pourrait être plus que vous voulez.)

690
répondu Cascabel 2017-05-03 21:27:38

je sais que je réponds à une vieille question, mais il semble qu'il y ait une nouvelle façon de le faire avec la vérification interactive:

git checkout -p bc66559

Crédit puis-je choisir de manière interactive les beaux mecs de l'autre git commit?

63
répondu Mike Monkiewicz 2017-05-23 12:03:05

en supposant que les changements que vous voulez soient à la tête de la branche d'où vous voulez les changements, utilisez git checkout

pour un seul fichier:

git checkout branch_that_has_the_changes_you_want path/to/file.rb

pour plusieurs fichiers juste chaîne daisy:

git checkout branch_that_has_the_changes_you_want path/to/file.rb path/to/other_file.rb
35
répondu Jay Swain 2010-02-01 06:06:38

construire sur Mike Monkiewicz réponse vous pouvez également spécifier un ou plusieurs fichiers à vérifier à partir de la sha1/branche fournie.

git checkout -p bc66559 -- path/to/file.java 

Cela vous permettra de choisir de manière interactive les changements que vous voulez appliquer à votre version actuelle du fichier.

12
répondu Christian.D 2017-05-23 12:18:17

si "partially cherry picking" signifie "à l'intérieur des fichiers, choisir certains changements mais en rejeter d'autres", il peut être fait en apportant git stash :

  1. Faire le plein cherry pick.
  2. git reset HEAD^ convertir l'ensemble du commit en modifications de travail non programmées.
  3. maintenant git stash save --patch : sélectionner interactivement les matériaux indésirables à stocker.
  4. Git retrousse les changements votre copie de travail.
  5. git commit
  6. jeter la cachette des changements indésirables: git stash drop .

Tip: si vous donnez la cachette de changements indésirables un nom: git stash save --patch junk puis si vous oubliez de faire (7) maintenant, plus tard, vous reconnaîtrez la cachette pour ce qu'il est.

1
répondu Kaz 2014-10-02 17:28:45