Comment choisir plusieurs commits

j'ai deux branches. Commettre a est à la tête de l'un, tandis que l'autre a b , c , d , e et f par-dessus a . Je veux déménager. c , d , e et f à la première branche sans commettre b . Il est facile d'utiliser cherry pick: vérifiez la première branche cherry-pick un par un c à f et rebase deuxième branche sur la première. Mais est-il possible d' choisir toutes les commandes c - f en une seule commande?

Voici une description visuelle du scénario (merci JJD ):

enter image description here

592
demandé sur JJD 2009-11-04 03:07:03

9 réponses

Git 1.7.2 introduit la possibilité de rechercher une gamme de commits. De la notes de version :

git cherry-pick" appris à choisir une gamme de commits (par exemple " cherry-pick A..B" et "cherry-pick --stdin"), et n'a donc "git revert"; ceux-ci ne supportent pas le nicer sequencing control". [-i]" a, cependant.


y compris commentaires importants (crédits aux auteurs respectifs)

Note 1: dans le " cherry-pick A..B " Forme, A devrait être plus ancien que B. Si elles sont le mauvais ordre la commande échouera silencieusement. - damian

Note 2: en outre, ce ne sera pas cherry-pick A, mais plutôt tout après un jusqu'à et y compris B.-J. B. Rainsberger

Note 3: Pour inclure Un type juste git cherry-pick^..B-sschaef

859
répondu Eric Darchis 2015-10-28 18:00:16

la façon la plus simple de faire ceci est avec l'option onto à rebase . Supposons que la branche que le courant termine à a s'appelle mybranch et c'est la branche sur laquelle vous voulez déplacer c - f .

# checkout mybranch
git checkout mybranch

# reset it to f (currently includes a)
git reset --hard f

# rebase every commit after b and transplant it onto a
git rebase --onto a b
86
répondu CB Bailey 2009-11-04 08:13:13

ou la doublure demandée:

git rebase --onto a b f
70
répondu wolfc 2011-05-25 15:12:16

vous pouvez utiliser une combinaison de série de git rebase et git branch pour appliquer un groupe de commits sur une autre branche. Comme déjà posté par wolfc la première commande copie réellement les commits. Cependant, le changement n'est pas visible jusqu'à ce que vous ajoutiez un nom de branche au plus haut commit du groupe.

Veuillez ouvrir l'image dans un nouvel onglet ...

Workflow

pour résumer les commandes sous forme de texte:

  1. Open gitk comme un processus indépendant en utilisant la commande: gitk --all & .
  2. Exécuter git rebase --onto a b f .
  3. Appuyez sur F5 dans gitk . Rien ne change. Mais aucun HEAD n'est marqué.
  4. Exécuter git branch selection
  5. de la Presse F5 dans gitk . La nouvelle branche avec ses commits apparaît.

cela devrait clarifier les choses:

  • Commit a est la nouvelle destination racine du groupe.
  • Commit b est le commit avant la première livraison du groupe (exclusif).
  • Commit f est la dernière livraison du groupe (inclus).

ensuite, vous pouvez utiliser git checkout feature && git reset --hard b pour supprimer les commits c jusqu'à f de la branche feature .

en plus de cette réponse, j'ai écrit un blog post qui décrit les commandes dans un autre scénario qui devrait aider à Généralement l'utiliser.

51
répondu JJD 2017-05-23 11:33:24

pour appliquer les commentaires de J. B. Rainsberger et sschaef pour répondre spécifiquement à la question... Pour utiliser une plage de sélection sur cet exemple:

git checkout a
git cherry-pick b..f

ou

git checkout a
git cherry-pick c^..f
23
répondu Andy 2015-07-26 18:25:40
git rev-list --reverse b..f | xargs -n 1 git cherry-pick
18
répondu Dustin 2009-11-04 03:59:07
git format-patch --full-index --binary --stdout range... | git am -3
4
répondu Roger Wang 2011-06-16 13:02:48

si vous avez des révisions sélectives pour fusionner, par exemple A, C, F,J à partir de A,B,C,D,E,F,G,H,I, J commits, utilisez simplement la commande suivante:

git cherry-pick A C F J

2
répondu Shrikant W 2018-02-20 10:00:36

en Fait, la façon la plus simple pourrait être de

  1. enregistrer la fusion de la base entre les deux branches MERGE_BASE=$(git merge-base branch-a branch-b)
  2. avance rapide ou de rebase l'ancienne branche sur la nouvelle branche
  3. rebaser la branche résultante sur elle-même, en commençant à la base de fusion de l'étape 1, et supprimer manuellement les propagations qui ne sont pas désirées:

    git rebase ${SAVED_MERGE_BASE} -i
    

    alternativement, s'il n'y a qu'un peu de nouvelles propagations, sauter l'étape 1, et tout simplement utiliser

    git rebase HEAD^^^^^^^ -i
    

    dans la première étape, en utilisant assez de ^ pour passer la base de fusion.

Vous verrez quelque chose comme ceci dans le rebase interactif:

pick 3139276 commit a
pick c1b421d commit b
pick 7204ee5 commit c
pick 6ae9419 commit d
pick 0152077 commit e
pick 2656623 commit f

puis supprimer les lignes b (et toutes les autres que vous voulez)

1
répondu ealfonso 2018-06-04 06:36:28