web-dev-qa-db-fra.com

Comment sélectionner plusieurs commits

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 ):

enter image description here

695
tig

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

1021
Eric Darchis

La méthode la plus simple consiste à utiliser l'option ontoto rebasename__. Supposons que la branche dont le nom se termine par as'appelle mybranch et qu'il s'agisse de la branche vers laquelle vous souhaitez déplacer cname __-fname__.

# 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
89
CB Bailey

Ou le one-liner demandé:

git rebase --onto a b f
75
wolfc

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 ...

Workflow

Pour résumer les commandes sous forme de texte:

  1. Ouvrez gitk en tant que processus indépendant à l'aide de la commande: gitk --all &.
  2. Exécutez git rebase --onto a b f.
  3. Presse F5 dans gitk . Rien ne change. Mais aucun HEADn'est marqué.
  4. Exécutez git branch selection
  5. Presse F5 dans gitk . La nouvelle branche avec ses commits apparaît.

Cela devrait clarifier les choses:

  • Commit aest la nouvelle destination racine du groupe.
  • Commit best la validation avant la première validation du groupe (exclusif).
  • Commit fest la dernière validation du groupe (inclusif).

Ensuite, vous pouvez utiliser git checkout feature && git reset --hard b pour supprimer les commits cjusqu’à fde la branche featurename__.

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.

58
JJD

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
35
Andy
git rev-list --reverse b..f | xargs -n 1 git cherry-pick
18
Dustin

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

13
Shrikant Wandhare

En fait, le moyen le plus simple de le faire serait de:

  1. enregistrer la base de fusion entre les deux branches: MERGE_BASE=$(git merge-base branch-a branch-b)
  2. avancez ou rebassez l'ancienne branche sur la nouvelle branche
  3. 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)

3
ealfonso
git format-patch --full-index --binary --stdout range... | git am -3
3
Roger Wang

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
0
nickboldt

Pour sélectionner un identifiant de commit jusqu'au sommet de la branche, vous pouvez utiliser:

git cherry-pick commit_id^..branch_name

0
ut9081