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 ):
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
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
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 ...
pour résumer les commandes sous forme de texte:
- Open gitk comme un processus indépendant en utilisant la commande:
gitk --all &
. - Exécuter
git rebase --onto a b f
. - Appuyez sur F5 dans gitk . Rien ne change. Mais aucun
HEAD
n'est marqué. - Exécuter
git branch selection
- 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.
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
git format-patch --full-index --binary --stdout range... | git am -3
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
en Fait, la façon la plus simple pourrait être de
- enregistrer la fusion de la base entre les deux branches
MERGE_BASE=$(git merge-base branch-a branch-b)
- avance rapide ou de rebase l'ancienne branche sur la nouvelle branche
-
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)