5841 votes

Déplacer le plus récent commit(s) à une nouvelle branche avec Git

Je voudrais déplacer le dernier plusieurs commits que j'ai fait pour maîtriser une nouvelle branche et prendre de maître datant d'avant ces commits ont été faites. Malheureusement, mon Git-fu n'est pas assez fort encore, toute aide?

I. e. Comment puis-je aller à partir de ce

master A - B - C - D - E

à présent?

newbranch     C - D - E
             /
master A - B 

7564voto

sykora Points 30290

Le déplacement vers une nouvelle branche

Sauf si il y a d'autres circonstances, cela peut être facilement fait par branchement et de restauration.

git branch newbranch
git reset --hard HEAD~3 # Go back 3 commits. You *will* lose uncommitted work.*1
git checkout newbranch

Mais assurez-vous combien s'engage à revenir en arrière.

*1 Vous aurez seulement être "perdant" commits de la branche master, mais ne vous inquiétez pas, vous aurez ceux qui s'engage dans newbranch!

Le déplacement d'une branche

AVERTISSEMENT La méthode ci-dessus fonctionne parce que vous êtes la création d'une nouvelle branche avec la première commande: git branch newbranch. Si vous souhaitez utiliser une branche vous avez besoin de fusionner vos modifications dans la branche avant l'exécution d' git reset --hard HEAD~3. Si vous n'avez pas fusionner vos modifications tout d'abord, ils seront perdus. Donc, si vous travaillez avec une branche, il ressemblera à ceci:

git checkout existingbranch
git merge master
git checkout master
git reset --hard HEAD~3 # Go back 3 commits. You *will* lose uncommitted work.
git checkout existingbranch

1171voto

Kyralessa Points 76456

Pour ceux qui se demandent pourquoi ça marche (comme j'étais au premier abord):

Vous voulez retourner à C, et de le déplacer D et E de la nouvelle branche. Voici à quoi il ressemble au premier abord:

A-B-C-D-E (HEAD)
        ↑
      master

Après l' git branch newBranch:

    newBranch
        ↓
A-B-C-D-E (HEAD)
        ↑
      master

Après l' git reset --hard HEAD~2:

    newBranch
        ↓
A-B-C-D-E (HEAD)
    ↑
  master

Depuis une branche est juste un pointeur, maître souligné le dernier commit. Lorsque vous faites newBranch, vous faites simplement un nouveau pointeur vers le dernier commit. Ensuite à l'aide d' git reset vous avez déplacé le maître pointeur de retour de deux validations. Mais puisque vous n'avez pas déplacer newBranch, il pointe toujours à l'engagement initial.

535voto

Ivan Points 3347

En Général...

La méthode exposée par sykora est la meilleure option dans ce cas. Mais parfois n'est pas facile et ce n'est pas une méthode générale. Pour une méthode générale d'utiliser git cherry-pick:

Pour parvenir à ce que l'OP veut, c'est un procédé en 2 étapes:

Étape 1 - Notez ce qui s'engage à partir de maître que vous voulez sur un newbranch

Exécuter

git checkout master
git log

Remarque les valeurs de hachage de (3) commet vous voulez sur newbranch. Ici je vais utiliser:
C commettre: 9aa1233
D engager: 453ac3d
E commit: 612ecb3

Remarque: Vous pouvez trouver les six premiers caractères de chaque commit ou de l'ensemble de la nom de commit

Étape 2 - les Mettre sur l' newbranch

git checkout newbranch
git cherry-pick 612ecb3
git cherry-pick 453ac3d
git cherry-pick 9aa1233

OU (sur Git 1.7.2+, utilisent des plages)

git checkout newbranch
git cherry-pick 612ecb3..9aa1233

git cherry-pick applique ces trois s'engage à newbranch.

371voto

aragaer Points 3518

Encore une autre façon de le faire, en utilisant seulement 2 commandes. Garde également votre arbre de travail intact.

git checkout -b newbranch # switch to a new branch
git push . +HEAD~3:master # make master point to some older commit 

Être en mesure d' push de . est une belle astuce pour savoir.

32voto

Sukima Points 2005

Ce n'est pas "déplacer" dans le sens technique, mais il a le même effet:

A--B--C  (branch-foo)
 \    ^-- I wanted them here!
  \
   D--E--F--G  (branch-bar)
      ^--^--^-- Opps wrong branch!

While on branch-bar:
$ git reset --hard D # remember the SHAs for E, F, G (or E and G for a range)

A--B--C  (branch-foo)
 \
  \
   D-(E--F--G) detached
   ^-- (branch-bar)

Switch to branch-foo
$ git cherry-pick E..G

A--B--C--E'--F'--G' (branch-foo)
 \   E--F--G detached (This can be ignored)
  \ /
   D--H--I (branch-bar)

Now you won't need to worry about the detached branch because it is basically
like they are in the trash can waiting for the day it gets garbage collected.
Eventually some time in the far future it will look like:

A--B--C--E'--F'--G'--L--M--N--... (branch-foo)
 \
  \
   D--H--I--J--K--.... (branch-bar)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X