Déplacer le travail existant et non engagé vers une nouvelle branche dans Git

3127

J'ai commencé à travailler sur une nouvelle fonctionnalité et après avoir codé un peu, j'ai décidé que cette fonctionnalité devrait être sur sa propre branche.

Comment déplacer les modifications non validées existantes vers une nouvelle branche et réinitialiser ma modification actuelle?

Je souhaite réinitialiser ma branche actuelle tout en préservant le travail existant sur la nouvelle fonctionnalité.

Dane O'Connor
la source
Le même sujet intéressant stackoverflow.com/q/556923/269514 ?
Gilberto

Réponses:

3644

Utilisez le suivant:

git checkout -b <new-branch>

Cela laissera votre branche actuelle telle qu'elle est, créera et retirera une nouvelle branche et conservera toutes vos modifications. Vous pouvez ensuite effectuer des modifications dans les fichiers à valider avec:

git add <files>

et engagez-vous dans votre nouvelle succursale avec:

git commit -m "<Brief description of this commit>"

Les changements dans le répertoire de travail et les changements dans l'index n'appartiennent à aucune branche pour le moment. Cela change la branche où ces modifications se termineraient.

Vous ne réinitialisez pas votre branche d'origine, elle reste telle quelle. Le dernier commit <old-branch>sera toujours le même. Par conséquent, vous checkout -bet ensuite vous engagez.


Mise à jour 2020 / Git 2.23

Git 2.23 ajoute la nouvelle switchsous-commande pour tenter de dissiper une partie de la confusion qui vient de l'utilisation surchargée de checkout(changement de branche, restauration de fichiers, détachement de HEAD, etc.)

À partir de cette version de Git, remplacez la commande ci-dessus par:

git switch -c <new-branch>

Le comportement est identique et reste inchangé.

knittl
la source
15
Juste pour être sûr, je dois valider la fonctionnalité inachevée AVANT de réinitialiser ma branche d'origine? Ou ces fichiers non validés seront-ils conservés indépendamment de la validation?
Dane O'Connor, le
192
Pour info: les changements dans le répertoire de travail et les changements dans l'index n'appartiennent pas à une branche. git checkout -b <new branch>changements où ces changements se termineraient.
Jakub Narębski
152
Si vous avez déjà une succursale et souhaitez déplacer vos modifications vers la succursale existante,
consultez
14
Si vous souhaitez pousser votre nouvelle branche vers le référentiel distant: stackoverflow.com/questions/2765421/…
Dewayne
10
@JDSmith: changements uncommit NE PAS appartiennent à une branche. Ils résident uniquement dans le répertoire de travail git checkout ./ git reset --hardse unrecoverably enlever les
Knittl
331

Alternativement:

  1. Enregistrez les modifications actuelles dans une réserve temporaire:

    $ git stash

  2. Créez une nouvelle branche basée sur cette réserve et basculez vers la nouvelle branche:

    $ git stash branch <new-branch> stash@{0}

Astuce: utilisez la touche de tabulation pour réduire la saisie du nom de la cachette.

Robin Qiu
la source
51
Si l'autre branche existe déjà, vous pouvez simplement y basculer avec le paiement, alors git stash apply.
Archonic
6
Je ne comprends pas l'astuce "Astuce: utilisez la touche de tabulation pour réduire la saisie du nom de la cachette". "Stash @ {0}" n'est-il pas le nom? Je ne peux pas l'exécuter avec succès.
Herbert
7
Pourquoi est-ce mieux que la réponse acceptée stackoverflow.com/a/1394804/754997 ?
Chris Page
10
Je ne comprends pas pourquoi c'est mieux que la réponse acceptée degit checkout -b <new branch name>
Noitidart
6
Vous n'en avez pas besoin git add -Aavant de ranger.
vichle
48

Si vous avez effectué des validations sur votre branche principale pendant que vous avez codé, mais que vous souhaitez maintenant déplacer ces validations vers une autre branche, voici un moyen rapide:

  1. Copiez votre historique actuel sur une nouvelle branche, en apportant également toutes les modifications non validées:

    git checkout -b <new-feature-branch>
    
  2. Maintenant, forcez la branche d'origine "en désordre" à revenir en arrière: (sans y basculer)

    git branch -f <previous-branch> <earlier-commit-id>
    

    Par exemple:

    git branch -f master origin/master
    

    ou si vous aviez fait 4 commits:

    git branch -f master HEAD~4
    

Avertissement: git branch -f master origin/master vous réinitialiser les informations de suivi pour cette branche. Donc, si vous avez configuré votremasterbranche pour pousser ailleurs,origin/mastercette configuration sera perdue.

Avertissement: Il existe également un danger si vous rebasez après la ramification, ce qui est décrit ici . La seule façon d'éviter cela est de créer une nouvelle histoire à l'aide de la sélection de cerise. Ce lien décrit la méthode infaillible la plus sûre . Si vous avez des modifications non validées, vous voudrez peut-êtregit stashau début etgit stash popà la fin.

joeytwiddle
la source
6
Cela répond à une question qui est légèrement différente de ce que l'op a demandé. J'ai décidé de mettre cette réponse ici parce que c'est là que Google m'a amené lorsque je cherchais une réponse. La vraie question qui traite de cette situation est ici .
joeytwiddle
26

Le scénario courant est le suivant: j'ai oublié de créer la nouvelle branche pour la nouvelle fonctionnalité et je faisais tout le travail dans l'ancienne branche de fonctionnalité. J'ai confié tous les "anciens" travaux à la branche maître, et je veux que ma nouvelle branche se développe à partir du "maître". Je n'ai fait aucun engagement de mon nouveau travail. Voici la structure de la branche: "master" -> "Old_feature"

git stash 
git checkout master
git checkout -b "New_branch"
git stash apply
Alex Burov
la source
18

Si vous le validez, vous pouvez également sélectionner le seul ID de validation. Je le fais souvent lorsque je commence à travailler en master, puis je souhaite créer une branche locale avant de pousser vers mon origine /.

git cherry-pick <commitID>

Il y a beaucoup de choses que vous pouvez faire avec la sélection de cerises, comme décrit ici , mais cela pourrait être un cas d'utilisation pour vous.

mot de passe
la source
2
Une solution plus agréable pour déplacer des modifications partielles vers une nouvelle branche ... puisque vous pouvez valider ce que vous voulez pour l'instant, cacher toutes les autres modifications, vérifier la branche à partir de laquelle vous souhaitez créer une branche, choisir avec le cerise qui s'engage sur la nouvelle branche, revenir en arrière à la branche d'origine, réinitialisez en dur un commit, puis faites un pop stash, ajoutez, validez et chantez allelujah.
Meredith
1
@Meredith, haha, ya quelque chose comme ça. C'est génial, à moins que vous ne planifiiez vos changements à l'avance ... et qui le fera;)
mot de passe
1

Il existe en fait un moyen très simple de le faire avec GitHub Desktop maintenant que je ne pense pas que c'était une fonctionnalité auparavant.

Tout ce que vous avez à faire est de basculer vers la nouvelle branche dans GitHub Desktop, et cela vous invitera à laisser vos modifications sur la branche actuelle (qui sera cachée), ou à apporter vos modifications avec vous à la nouvelle branche. Choisissez simplement la deuxième option, pour apporter les modifications à la nouvelle branche. Vous pouvez ensuite vous engager comme d'habitude.

Bureau GitHub

Kristofer Doman
la source
1

Cela peut être utile pour tous ceux qui utilisent des outils pour GIT

Commander

Changer de branche - il déplacera vos modifications vers new-branch. Ensuite, vous pouvez valider les modifications.

 $ git checkout -b <new-branch>

TortoiseGIT

Faites un clic droit sur votre référentiel puis utilisez TortoiseGit-> Switch / Checkout

entrez la description de l'image ici entrez la description de l'image ici

SourceTree

Utilisez le bouton "Commander" pour changer de branche. Vous verrez le bouton "caisse" en haut après avoir cliqué sur une branche. Les modifications de la branche actuelle seront appliquées automatiquement. Ensuite, vous pouvez les valider.

entrez la description de l'image ici

Przemek Struciński
la source
0

J'ai utilisé @Robin answer & listing tout ce que j'ai fait,

git status                               <-- review/list uncommitted changes
git stash                                <-- stash uncommitted changes
git stash branch <new-branch> stash@{1}  <-- create a branch from stash
git add .                                <-- add local changes
git status                               <-- review the status; ready to commit
git commit -m "local changes ..."        <-- commit the changes
git branch --list                        <-- see list of branches incl the one created above
git status                               <-- nothing to commit, working tree (new-branch) is clean
git checkout <old-branch>                <-- switch back

! Si le dépôt a plus d'une cachette, voyez celle à appliquer à la nouvelle branche:

git stash list  
  stash@{0}: WIP on ...  
  stash@{1}: WIP on ...

et inspecter la réserve individuelle par,

git stash show stash@{1}

Ou inspectez toutes les réserves en même temps:

git stash list -p
NBhat
la source