J'ai deux branches. Commit a
est à la tête de l’un, tandis que l’autre est précédé de b
, c
, d
, e
et f
et a
. Je souhaite déplacer c
, d
, e
et f
vers la première branche sans validation b
. Il est facile d’utiliser Cherry Pick: commandez une première branche, sélectionnez une par une c
à f
et rebasonnez la seconde branche sur la première. Mais existe-t-il un moyen de sélectionner tous les éléments c
-f
en une seule commande?
Voici une description visuelle du scénario (merci JJD ):
Git 1.7.2 a introduit la possibilité de sélectionner une série de commits. De la notes de version :
git cherry-pick "a appris à choisir une série de commits (par exemple," cherry-pick A..B "et" cherry-pick - stdin "), de même que" git revert "; rebase [-i] "a, cependant.
Y compris les commentaires importants (crédits des auteurs respectifs)
Remarque 1: Sous la forme "cherry-pick A..B", A doit être plus ancien que B. S'il est dans le mauvais ordre, la commande va échouer en silence. - Damian
Note 2: En outre, cela ne sélectionnera pas A, mais tout ce qui suit A jusqu'à B. inclus. - J. B. Rainsberger
Note 3: Pour inclure A tapez simplement git cherry-pick A ^ .. B - sschaef
La méthode la plus simple consiste à utiliser l'option onto
to rebase
name__. Supposons que la branche dont le nom se termine par a
s'appelle mybranch et qu'il s'agisse de la branche vers laquelle vous souhaitez déplacer c
name __-f
name__.
# 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
Ou le one-liner demandé:
git rebase --onto a b f
Vous pouvez utiliser une combinaison en série de git rebase
et git branch
pour appliquer un groupe de validations à une autre branche. Comme déjà posté par wolfc la première commande copie réellement les commits. Toutefois, la modification n'est visible que lorsque vous ajoutez un nom de branche au groupe le plus en amont du groupe.
S'il vous plaît ouvrir l'image dans un nouvel onglet ...
Pour résumer les commandes sous forme de texte:
gitk --all &
.git rebase --onto a b f
.HEAD
n'est marqué.git branch selection
Cela devrait clarifier les choses:
a
est la nouvelle destination racine du groupe.b
est la validation avant la première validation du groupe (exclusif).f
est la dernière validation du groupe (inclusif).Ensuite, vous pouvez utiliser git checkout feature && git reset --hard b
pour supprimer les commits c
jusqu’à f
de la branche feature
name__.
En plus de cette réponse, j’ai écrit un article de blog qui décrit les commandes d’un autre scénario qui devrait aider à l’utiliser de manière générale.
Pour appliquer les commentaires de J. B. Rainsberger et sschaef, répondez spécifiquement à la question ... Pour utiliser une plage de sélection de cerises sur cet exemple:
git checkout a
git cherry-pick b..f
ou
git checkout a
git cherry-pick c^..f
git rev-list --reverse b..f | xargs -n 1 git cherry-pick
Si vous avez des révisions sélectives à fusionner, dites A, C, F, J de A, B, C, D, E, F, G, H, I, J commits, utilisez simplement la commande ci-dessous:
pique-nique A C F J
En fait, le moyen le plus simple de le faire serait de:
MERGE_BASE=$(git merge-base branch-a branch-b)
rebassez la branche résultante sur elle-même, en partant de la base de fusion de l'étape 1, et supprimez manuellement les validations non souhaitées:
git rebase ${SAVED_MERGE_BASE} -i
Sinon, s'il n'y a que quelques nouveaux commits, ignorez l'étape 1 et utilisez simplement
git rebase HEAD^^^^^^^ -i
dans la première étape, utilisez suffisamment de ^
pour dépasser la base de fusion.
Vous verrez quelque chose comme ceci dans la base interactive:
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 supprimez les lignes b (et toutes les autres que vous voulez)
git format-patch --full-index --binary --stdout range... | git am -3
Voici un script qui vous permettra de sélectionner plusieurs commits à la suite en indiquant simplement au script les branches source et cible pour les sélections et le nombre de commits:
https://Gist.github.com/nickboldt/99ac1dc4eb4c9ff003a1effef2eb2d81
Pour sélectionner dans votre branche à maîtriser (utilise la branche actuelle comme source):
./gcpl.sh -m
Pour sélectionner les 5 derniers commits de votre branche 6.19.x à maîtriser:
./gcpl.sh -c 5 -s 6.19.x -t master
Pour sélectionner un identifiant de commit jusqu'au sommet de la branche, vous pouvez utiliser:
git cherry-pick commit_id^..branch_name