16 votes

Comment déplacer les commits du tronc vers une branche dans Git ?

J'ai fait un tas de commits sur le master et j'ai réalisé après coup qu'ils auraient dû être dans une branche.

J'ai regardé plusieurs choses sur le rebasement, la fusion et la réinitialisation du master. Mais aucune tentative de manipulation n'a permis d'obtenir un historique qui ressemble à ce que j'essaie de faire.

Mes tentatives m'amènent à penser que cela nécessite une combinaison de rebase --onto y reset --hard pour faire reculer le maître dans le temps. Mais ma compréhension du branchement de Git laisse à désirer. Une partie de ce travail consiste à apprendre comment je peux l'utiliser.

Il faut noter qu'aucun des changements que j'essaie d'apporter n'a été mis en place.

Actuel

  * remote/trunk
--o--a--b--c--d--e--f     <- master
  |
  o                       <- remote branch foo

Résultat souhaité

  * remote/trunk
--o                       <- master
  |
  o--a--b--c--d--e--f     <- remote branch foo

9voto

hasenj Points 36139

Une variante de la réponse de Martin qui ne s'appliquera pas nécessairement à votre situation, mais je veux quand même la publier :)

Supposons que vous ayez oublié de créer la branche lors du commit o donc vous avez :

x--y--z--o--a--b--c--d--e--f  master
         |
         +
   [forgot to make a branch here]

Et puis tu as réalisé que ce que tu voulais vraiment, c'était.. :

x--y--z--o   master
         |
         +--a--b--c--d--e--f  topic

Ce que vous pouvez faire dans ce cas est de créer une branche à o en utilisant son hachage :

git branch topic # creates new branch 'topic' - will be at commit `f`
git checkout o -b newmaster # creates new branch called newmaster pointing on commit `o` (please replace `o` with the actual hash)
git branch -M newmaster master # force rename newmaster to master (means master points on hash `o`)

Vous serez dans la branche master (commit o ), donc comme dernière étape vous pouvez :

git checkout topic

Le hachage peut bien sûr être constitué des 5 premiers caractères

EDITAR

Cela ne devrait pas avoir beaucoup d'importance que vous utilisiez git-svn ce qui compte vraiment, c'est que vous n'ayez pas publié votre branche principale à un moment quelconque après o

Une branche dans git n'est rien d'autre qu'un pointeur vers un commit. C'est pourquoi les branches sont si peu coûteuses : il suffit de créer un pointeur, et vous avez une branche.

Je ne sais pas ce qu'il en est du suivi des branches distantes, vous devrez peut-être le configurer après avoir renommé/déplacé vos branches.

6voto

VonC Points 414372

Je ne suis pas sûr que renommer les branches soit la bonne solution, puisque cela vous mènerait de :

  * remote/trunk
--M--a--b--c--d--e--f     <- master
  |
  F                       <- remote branch foo

à :

--F                       <- master
  |
  M--a--b--c--d--e--f     <- remote branch foo
  * remote/trunk

(à condition que vous renommiez remote/foo ce qui n'est pas conseillé : vous devriez d'abord le suivre, puis le renommer, même si le résultat final est différent de ce dont vous avez besoin).

ce qui n'est pas le "résultat souhaité" que vous voulez (foo doit partir de F, pas de M) :

  * remote/trunk
--M                       <- master
  |
  F--a--b--c--d--e--f     <- remote branch foo

Vous ne pouvez y parvenir que par le biais d'un rebase --onto

git checkout --track -b origin/foo  # create a local branch named after the remote one
git branch tmp                      # mark current foo HEAD to 'F'
git branch -f foo master            # put foo where it should b: at 'f'
git branch -f master tmp^           # reset master to M, parent of tmp
git checkout tmp                    # go to where we must replay the commits
git rebase --onto tmp master foo    # replay a to f on top of tmp
git svn dcommit                     # push the local foo in order to update remote/foo

en vous donnant :

  * remote/trunk
--M                             <- master
  |
  F--a'--b'--c'--d'--e'--f'     <- local foo and remote branch foo

1voto

Jilles van Gurp Points 1596

Presque correct ce que hasen j suggère, mais j'ai dû faire quelques petites modifications (et j'utilise git-svn) :

# create the branch with your commits
git branch performance
# fork the master to a new branch at the commit before your local, non pushed commits
git branch newmaster 2d0516dfe8252de87
# checkout your branch 
git checkout performance
# rename the newmaster
git branch -M newmaster master
# now checkout the master
git checkout master

Vous ne pouvez pas renommer une branche sur laquelle vous êtes, donc j'ai vérifié la branche performance où j'ai déplacé mes commits.

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