Git: créer une branche à partir de modifications non stadifiées / non validées sur le maître

991

Contexte: je travaille sur master en ajoutant une fonctionnalité simple. Après quelques minutes, je me rends compte que ce n'était pas si simple et qu'il aurait dû être préférable de travailler dans une nouvelle branche.

Cela m'arrive toujours et je n'ai aucune idée de comment passer à une autre branche et prendre toutes ces modifications non validées avec moi en laissant la branche principale propre. Je supposais git stash && git stash branch new_branchsimplement accomplir cela, mais voici ce que j'obtiens:

~/test $ git status
# On branch master
nothing to commit (working directory clean)

~/test $ echo "hello!" > testing 

~/test $ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   testing
#
no changes added to commit (use "git add" and/or "git commit -a")

~/test $ git stash
Saved working directory and index state WIP on master: 4402b8c testing
HEAD is now at 4402b8c testing

~/test $ git status
# On branch master
nothing to commit (working directory clean)

~/test $ git stash branch new_branch
Switched to a new branch 'new_branch'
# On branch new_branch
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   testing
#
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (db1b9a3391a82d86c9fdd26dab095ba9b820e35b)

~/test $ git s
# On branch new_branch
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   testing
#
no changes added to commit (use "git add" and/or "git commit -a")

~/test $ git checkout master
M   testing
Switched to branch 'master'

~/test $ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   testing
#
no changes added to commit (use "git add" and/or "git commit -a")

Savez-vous s'il existe un moyen d'y parvenir?

knoopx
la source
1
Bien qu'il existe une solution plus simple à votre problème, pourriez-vous spécifier en quoi le résultat que vous obtenez diffère de ce que vous vouliez?
Gauthier
2
en faisant ce qui précède ou les réponses en bas, les modifications non validées concernent à la fois le maître et la nouvelle branche. Je les veux uniquement sur la nouvelle branche, donc je peux commander master et travailler sur autre chose sans que ces changements flottent
knoopx
1
voir ma réponse modifiée. Vous devez valider vos modifications locales sur la nouvelle branche si vous souhaitez extraire un maître propre. Les modifications locales ne sont que les différences entre le HEAD actuel et vos fichiers sur le disque. Ces modifications sur les fichiers locaux ne sont pas versionnées, vous devez dire à git de les enregistrer quelque part si vous souhaitez les récupérer plus tard.
Gauthier

Réponses:

1207

Pas besoin de planquer.

git checkout -b new_branch_name

ne touche pas à vos changements locaux. Il crée simplement la branche à partir du HEAD actuel et y définit le HEAD. Donc je suppose que c'est ce que vous voulez.

--- Modifier pour expliquer le résultat du maître de caisse ---

Êtes-vous confus car checkout masterne rejette pas vos modifications?

Comme les modifications ne sont que locales, git ne veut pas que vous les perdiez trop facilement. Lors d'un changement de branche, git n'écrase pas vos modifications locales. Le résultat de votre checkout masterest:

M   testing

, ce qui signifie que vos fichiers de travail ne sont pas propres. git a changé le HEAD, mais n'a pas écrasé vos fichiers locaux. C'est pourquoi votre dernier statut affiche toujours vos modifications locales, bien que vous soyez activé master.

Si vous voulez vraiment ignorer les modifications locales, vous devez forcer le paiement avec -f.

git checkout master -f

Étant donné que vos modifications n'ont jamais été validées, vous les perdriez.

Essayez de revenir dans votre branche, validez vos modifications, puis récupérez à nouveau le maître.

git checkout new_branch
git commit -a -m"edited"
git checkout master
git status

Vous devriez recevoir un Mmessage après le premier paiement, mais plus maintenant après le checkout master, et git statusne montrer aucun fichier modifié.

--- Modifier pour éliminer la confusion au sujet du répertoire de travail (fichiers locaux) ---

En réponse à votre premier commentaire, les changements locaux sont juste ... enfin, locaux. Git ne les enregistre pas automatiquement, vous devez lui dire de les enregistrer pour plus tard. Si vous apportez des modifications et ne les validez pas ou ne les cache pas explicitement, git ne les mettra pas à jour. Si vous modifiez HEAD ( checkout master), les modifications locales ne sont pas écrasées car non enregistrées.

Gauthier
la source
32
La chose déroutante ici est que la page de manuel de git indique que git checkout«Met à jour les fichiers dans l'arborescence de travail pour correspondre à la version de l'index ou de l'arborescence spécifiée.». Cela suppose que vos modifications dans votre système de fichiers seront EFFECTUÉES par la suite. Sans aucune chance de les récupérer. Même si vous dites qu'ils ne le feront pas, cela laisse un très mauvais sentiment. Je ne fais pas confiance du tout à ça . Soit la documentation est vraiment mauvaise, soit le comportement par défaut de git est vraiment dangereux. Il ne faut pas se fier à une heuristique «automagique» pour détecter que dans ce cas, vous ne voulez pas perdre vos modifications.
Evi1M4chine
16
Si vous extrayez un commit qui écraserait vos modifications locales (si l'historique entre le commit actuel et le commit cible touche vos fichiers modifiés localement), git refuse. Uniquement si cela checkoutn'entre pas en conflit avec vos modifications locales, le paiement fonctionne et laisse les modifications locales seules. Je comprends bien le mauvais sentiment, la page de manuel devrait peut-être dire "Met à jour les fichiers non modifiés dans l'arborescence de travail". Git ne permet pas en revanche de perdre trop facilement les modifications locales. git checkoutsoit laisse vos changements locaux seuls, soit refuse en cas de conflit.
Gauthier
1
eh bien, comment puis-je passer à une autre succursale sans y apporter les changements locaux?
ア レ ッ ク ス
5
@Alex git checkout <other_branch> -f. Vous perdrez vos modifications locales sans avertissement.
Gauthier
2
@ Evi1M4chine Le premier. La documentation est vraiment mauvaise.
Qwertie
62

Essayer:

git stash
git checkout -b new-branch
git stash apply
Grant Limberg
la source
6
Est-ce différent de simplement faire «git checkout -b new-branch» seul?
Adrian Mouat
Je ne pense pas que c'était lorsque la réponse a été écrite à l'origine, mais je peux me tromper. Malheureusement, en raison de mes conditions de travail, j'utilise perforce depuis quelques années, je ne peux donc pas attester de sa précision maintenant.
Grant Limberg
6
Ou au lieu des deux dernières étapes: git stash branch new-branch
rethab
1
git stash n'est plus requis
kory
Quand vous avez une branche déjà existante où vous voulez mettre toutes vos affaires, stash a du sens pour moi: (éventuellement git fetch --all; pour obtenir la branche distante à l'origine) git stash; git checkout <existing-branch>; git stash s'applique;
Paolof76
24

Vous pouvez faire deux choses:

git checkout -b sillyname
git commit -am "silly message"
git checkout - 

ou

git stash -u
git branch sillyname stash@{0}

(git checkout - <- le tiret est un raccourci pour la branche précédente sur laquelle vous étiez)

( git stash -u<- -usignifie qu'il faut également des modifications non mises en scène)

Pylinux
la source
7

Si vous utilisez le client GitHub Windows (comme je le suis) et que vous êtes dans la situation d'avoir apporté des modifications non validées que vous souhaitez déplacer vers une nouvelle branche, vous pouvez simplement "Créer une nouvelle branche" via le client GitHub. Il basculera vers la branche nouvellement créée et conservera vos modifications.

entrez la description de l'image ici

Tod Birdsall
la source
qui cache les modifications avant de créer la nouvelle branche pour ne pas les conserver (version 223 sur Mac OS)
Fernando Gallego
2

Si vous souhaitez que vos modifications non validées actuelles sur la branche actuelle soient déplacées vers une nouvelle branche, utilisez la commande suivante pour créer une nouvelle branche et copiez automatiquement les modifications non validées.

git checkout -b branch_name

Cela créera une nouvelle branche à partir de votre branche actuelle (en supposant qu'elle soit maître), copiera les modifications non validées et basculera vers la nouvelle branche.

Validez vos modifications dans la nouvelle branche.

git commit -m "First commit"

Depuis, une nouvelle branche est créée, avant de la pousser à distance, vous devez définir l'amont. Utilisez la commande ci-dessous pour définir l'amont et le pousser à distance.

git push --set-upstream origin feature/feature/NEWBRANCH

Une fois que vous appuyez sur cette commande, une nouvelle branche sera créée sur la télécommande et votre nouvelle branche locale sera poussée sur la télécommande.

Maintenant, si vous souhaitez supprimer vos modifications non validées de la branche principale, utilisez:

git checkout master -f

Cela supprimera toutes les modifications locales non validées lors du paiement.

Maverick
la source
En quoi cette réponse diffère-t-elle de la réponse acceptée?
kometen
Bien qu'il y ait un certain chevauchement avec la réponse acceptée, cela fournit un guide étape par étape simple, et comprend également les opérations requises pour pousser une nouvelle branche à distance. Simple, clair et utile.
Kjartan
Cette réponse est claire et m'a beaucoup aidé.
Vadim
0

Dans le dernier client GitHub pour Windows , si vous avez des modifications non validées et choisissez de créer une nouvelle branche.
Il vous demande comment gérer ce scénario exact:

entrez la description de l'image ici

La même chose s'applique si vous changez simplement de branche aussi.

Jerry Dodge
la source