git switch branch sans abandonner les modifications locales

182

Bon, disons qu'un jour nous faisons arriver à faire un tas de modifications et quand nous allons les valider nous remarquons que nous travaillions sur la mauvaise branche.

Comment forcer git à changer de branche sans abandonner les changements locaux .

Je vais probablement m'y prendre de manière naïve en attendant une réponse, mais j'aimerais savoir s'il y a une procédure correcte car je mentirais si je disais que cela ne m'est pas arrivé auparavant ...

  • Sauvegarde du dépôt modifié
  • git reset --hard
  • git checkout right-branch
  • Restaurer les modifications
  • git commit -m "changes"
mégawac
la source

Réponses:

343

Il existe de nombreuses façons différentes en fonction de votre progression et de la ou des branches sur lesquelles vous les souhaitez.

Prenons une erreur classique:

$ git checkout master
... pause for coffee, etc ...
... return, edit a bunch of stuff, then: oops, wanted to be on develop

Alors maintenant, vous voulez que ces changements, auxquels vous ne vous êtes pas encore engagés master, soient appliqués develop.

  1. Si vous ne disposez pas d' une developencore, la méthode est triviale:

    $ git checkout -b develop
    

    Cela crée une nouvelle developbranche à partir de l'endroit où vous vous trouvez maintenant. Vous pouvez maintenant vous engager et les nouveautés sont activées develop.

  2. Vous avez un develop. Voyez si Git vous permettra de changer sans rien faire:

    $ git checkout develop
    

    Cela réussira ou se plaindra. Si ça réussit, tant mieux! Engagez-vous. Sinon ( error: Your local changes to the following files would be overwritten ...), vous avez encore beaucoup d'options.

    Le plus simple est probablement git stash(comme l'ont dit tous les autres répondants qui m'ont battu en cliquant post). Exécutez git stash saveou git stash push, 1 ou tout simplement git stashqui est l'abréviation de save/ push:

    $ git stash
    

    Cela valide votre code (oui, cela fait vraiment des commits) en utilisant une méthode étrange non-branch-y. Les commits qu'il fait ne sont "sur" aucune branche mais sont maintenant stockés en toute sécurité dans le référentiel, vous pouvez donc maintenant changer de branche, puis "appliquer" la cachette:

    $ git checkout develop
    Switched to branch 'develop'
    $ git stash apply
    

    Si tout se passe bien et que vous aimez les résultats, vous devriez alors git stash drople cacher. Cela supprime la référence aux commits étranges non-branch-y. (Ils sont toujours dans le référentiel et peuvent parfois être récupérés en cas d'urgence, mais dans la plupart des cas, vous devriez les considérer comme partis à ce stade.)

L' applyétape effectue une fusion des modifications cachées, en utilisant la puissante machine de fusion sous-jacente de Git, le même genre de chose qu'elle utilise lorsque vous effectuez des fusions de branches. Cela signifie que vous pouvez obtenir des "conflits de fusion" si la branche sur laquelle vous travailliez par erreur est suffisamment différente de la branche sur laquelle vous vouliez travailler. C'est donc une bonne idée d' inspecter soigneusement les résultats avant de supposer que la réserve s'est appliquée proprement, même si Git lui-même n'a détecté aucun conflit de fusion.

Beaucoup de gens utilisent git stash pop, ce qui est un raccourci pour git stash apply && git stash drop. C'est bien dans la mesure où cela se passe, mais cela signifie que si l'application entraîne un désordre et que vous décidez que vous ne voulez pas suivre cette voie, vous ne pouvez pas récupérer la réserve facilement. C'est pourquoi je recommande de séparer apply, d'inspecter les résultats, dropuniquement si / lorsqu'ils sont satisfaits. (Cela introduit bien sûr un autre point où vous pouvez prendre une autre pause-café et oublier ce que vous faisiez, revenir et faire la mauvaise chose, donc ce n'est pas un remède parfait.)


1 Le savein git stash saveest l'ancien verbe pour créer une nouvelle réserve. La version 2.13 de Git a introduit le nouveau verbe pour rendre les choses plus cohérentes popet pour ajouter plus d'options à la commande de création. La version 2.16 de Git a formellement déprécié l'ancien verbe (bien qu'il fonctionne toujours dans Git 2.23, qui est la dernière version au moment où je modifie ceci).

Torek
la source
3
Que faire si je veux passer à une autre branche sans m'engager dans la branche actuelle (par exemple, les modifications ne sont pas terminées) et revenir plus tard pour continuer?
stt106
@ stt106: vous devez toujours commettre, mais vous pouvez le faire, comme dans ceci et les autres réponses, via git stashpour que les commits - car git stash, vous obtenez deux commits par entrée de stash, dans un arrangement inhabituel - ne soient sur aucune branche. Sauf pour des cas spéciaux à très court terme, cependant, je préfère généralement faire un commit normal. Vous pouvez git reset --softou git reset --mixedplus tard, ou utiliser git commit --amendpour le mettre de côté, lorsque vous revenez à travailler sur cette branche. (Dans Git moderne, vous pouvez également utiliser git worktree add, ce qui peut être une solution encore meilleure.)
torek
"Cela réussira ou se plaindra.". Quelles seraient les raisons du succès ou de l'erreur lors du paiement?
nanocv
toutes mes modifications locales se perdent lorsque je change avec les étapes ci-dessus, je suis dans la branche <a> et j'effectue mes modifications et je veux passer à la branche <b> et y pousser toutes mes modifications. quand je fais git stash et que je passe à d'autres branches, il extrait tous les fichiers de la branche <b> et mes modifications locales se perdent
Mukul Munjal
38

Utiliser git stash

git stash

Il pousse les modifications dans une pile. Lorsque vous voulez les retirer, utilisez

 git stash apply

Vous pouvez même retirer des éléments individuels. Pour faire sauter complètement la réserve:

 git stash clear
Rayon
la source
7
La dernière commande devrait probablement être git stash drop; git stash cleareffacera toute la pile de cachettes, y compris les cachettes éventuellement sans rapport avec cet ensemble de commandes.
Leland
15
  • git stash pour enregistrer vos modifications non validées
  • git stash list pour répertorier vos cachettes non validées enregistrées
  • git stash apply stash@{x} où x peut être 0,1,2..no de stashes que vous avez créés
pied cassé
la source
4

Tu peux soit :

  • Utilisez git stashpour mettre vos modifications en attente ou,

  • Créez une autre branche et validez vos modifications, puis fusionnez cette branche dans votre répertoire de travail

X3074861X
la source