Je ne pense pas que la réponse acceptée de @ bukzor soit une réponse correcte à la question telle qu'elle a été posée. git stash --keep-indexconserve l'index, mais il cache tout - à la fois dans l'index et à l'extérieur.
Raman
@Antonio Il me semble que votre prime devrait en fait être une question distincte, car la question d'origine n'a rien à voir avec TortoiseGit en particulier.
JesusFreke
1
@JesusFreke Yep, étant donné le résultat, j'aurais pu épargner 50 répétitions :) C'est juste que c'est la question à laquelle vous êtes redirigé si vous essayez de rechercher "tortoisegit cachette partielle". Tortoisegit ne semble pas être un sujet populaire ici stackoverflow.com/questions/tagged/tortoisegit
La plupart des réponses ci-dessous sont obsolètes. Depuis Git 2.13 (Q2 2017), il est pris en charge avec git stash push [--] [<pathspec>...].
Ohad Schneider
Réponses:
1372
Avertissement : la réponse suivante est pour git avant git 2.13. Pour git 2.13 et plus, consultez une autre réponse plus bas .
Attention
Comme indiqué dans les commentaires, cela met tout dans la cachette, à la fois mis en scène et non mis en scène. --Keep-index laisse juste l'index seul une fois le stash terminé. Cela peut entraîner des conflits de fusion lorsque vous ouvrez ultérieurement la réserve.
Cela stockera tout ce que vous n'avez pas ajouté précédemment. Juste git addce que vous voulez garder, puis exécutez-le.
git stash --keep-index
Par exemple, si vous souhaitez diviser un ancien commit en plusieurs changements, vous pouvez utiliser cette procédure:
git rebase -i <last good commit>
Marquer certains changements comme edit.
git reset HEAD^
git add <files you want to keep in this change>
git stash --keep-index
Réparez les choses si nécessaire. N'oubliez pas git addles modifications.
Je ne sais pas pourquoi cela fait l'objet d'un vote positif. Tout le monde doit avoir une attente différente de moi. Le message d'origine demande "comment puis-je cacher juste une partie des modifications non validées?" Lorsque j'utilise git stash save -k, oui, l'index (en vert git stat) est conservé, mais l' ensemble des modifications (à la fois vert et rouge) va dans la cachette. Cela viole la demande du PO, "ne cache que quelques modifications". Je veux ranger juste une partie du rouge (pour une utilisation future).
Pistos
70
Si vous êtes plus intéressé par la réponse à la question posée par @Pistos (comme je l'étais), alors regardez ici: stackoverflow.com/questions/5506339/…
Raman
27
@Raman: Excellent! git stash -pest exactement ce que je cherchais. Je me demande si ce commutateur n'a été ajouté que récemment.
Pistos
14
ATTENTION: git stash --keep-indexest cassé. Si vous apportez plus de modifications, essayez git stash popensuite d'obtenir des conflits de fusion car la cachette comprend les fichiers modifiés que vous avez conservés, pas seulement ceux que vous n'avez pas conservés. Par exemple: je modifie les fichiers A et B, puis je stocke B, car je veux tester les modifications dans A; Je trouve un problème avec A que je corrige ensuite; Je commets A; Maintenant, je ne peux pas déchausser car une ancienne version de A est dans la cachette sans raison valable, provoquant un conflit de fusion. Dans la pratique, A et B peuvent avoir de nombreux fichiers, peut-être même des images binaires ou quelque chose, donc je dois essentiellement abandonner et perdre B.
rjmunro
3015
Vous pouvez également utiliser git stash save -p "my commit message". De cette façon, vous pouvez sélectionner quels morceaux doivent être ajoutés à la stash, des fichiers entiers peuvent également être sélectionnés.
Vous serez invité avec quelques actions pour chaque morceau:
y - stash this hunk
n - do not stash this hunk
q - quit; do not stash this hunk or any of the remaining ones
a - stash this hunk and all later hunks in the file
d - do not stash this hunk or any of the later hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help
Ce n'était pas. Il a été emprunté à Darcs, environ 7 ans après les faits.
nomen
6
Je suis accro à TortoiseGit. Cependant TortoiseGit ne prend pas en charge stash -p. J'attribue cette réponse car elle reste la plus interactive / conviviale.
Antonio
27
vous voudrez peut-être ajouter git stash save -p my stash message:; puisque l'ordre de l'argumenst n'est pas très intuitif ...
Chris Maes
15
Entre cela et git log -p, je pense que le -pdrapeau doit signifier "fais la chose cool que je veux mais je ne sais pas comment l'exprimer".
Kyle Strand
2
pourquoi diable cette excellente réponse est en 12ème position ?? après toutes ces réponses 0, +1, +2 ??????
DenisFLASH
550
Étant donné que git consiste fondamentalement à gérer tout le contenu et l'index du référentiel (et non un ou plusieurs fichiers) git stash, il n'est pas surprenant queavec le répertoire de travail.
En fait, depuis Git 2.13 (Q2 2017), vous pouvez cacher des fichiers individuels, avec git stash push:
git stash push [--] [<pathspec>...]
Quand pathspecest donné à ' git stash push', la nouvelle cachette enregistre les états modifiés uniquement pour les fichiers qui correspondent à la spécification de chemin Voir "Modifications de la cachette dans des fichiers spécifiques " pour plus d'informations.
Exemple simplifié:
git stash push path/to/file
Le scénario de test pour cette fonctionnalité montre quelques options supplémentaires désactivées:
test_expect_success 'stash with multiple pathspec arguments' '
>foo &&
>bar &&
>extra &&
git add foo bar extra &&
git stash push -- foo bar &&
test_path_is_missing bar &&
test_path_is_missing foo &&
test_path_is_file extra &&
git stash pop &&
test_path_is_file foo &&
test_path_is_file bar &&
test_path_is_file extra
La réponse originale (ci-dessous, juin 2010) concernait la sélection manuelle de ce que vous souhaitez ranger.
Ceci (la stash --patchsolution d'origine) est bien, mais souvent j'ai modifié beaucoup de fichiers, donc l'utilisation du patch est ennuyeuse
bukzor de réponse (upvoted, Novembre 2011) propose une solution plus pratique, basée sur git add+git stash --keep-index .
Allez voir et voter pour sa réponse, qui devrait être la réponse officielle (au lieu de la mienne).
À propos de cette option, chhh souligne un autre workflow dans les commentaires:
vous devriez « git reset --soft» après stash un pour obtenir votre dos de mise en scène claire:
Pour se rendre à l'état d' origine - qui est une zone de mise en scène claire et avec seulement une sélection de modifications non mis en scène, on pourrait doucement réinitialiser l'index pour obtenir (sans commettre quelque chose comme vous - bukzor - l'a fait).
(Réponse originale juin 2010: plan de travail manuel)
Pourtant, cela git stash save --patchpourrait vous permettre d'obtenir le stockage partiel que vous recherchez:
Avec --patch, vous pouvez sélectionner interactivement des morceaux dans le diff entre HEAD et l'arborescence de travail à ranger.
L'entrée de stash est construite de telle sorte que son état d'index est le même que l'état d'index de votre référentiel, et son arbre de travail contient uniquement les modifications que vous avez sélectionnées de manière interactive. Les modifications sélectionnées sont ensuite annulées à partir de votre arbre de travail.
Cependant, cela enregistrera l'index complet (qui peut ne pas être ce que vous voulez car il peut inclure d'autres fichiers déjà indexés) et un arbre de travail partiel (qui pourrait ressembler à celui que vous souhaitez ranger).
git stash --patch --no-keep-index
pourrait être un meilleur ajustement.
Si --patchcela ne fonctionne pas, un processus manuel peut:
Pour un ou plusieurs fichiers, une solution intermédiaire serait de:
C'est bien, mais j'ai souvent modifié beaucoup de fichiers, donc utiliser le patch est ennuyeux
Casebash
6
@VonC: C'est bien d'avoir une seule réponse par réponse. En outre, copier-coller les réponses des autres dans les vôtres est une mauvaise manière.
bukzor
3
@bukzor: Je suis désolé si ma réponse modifiée semble incorrecte. Ma seule intention était de donner plus de visibilité à votre réponse. J'ai retravaillé mon message afin de clarifier cette intention.
git is fundamentally about managing a all repository content and index and not one or several files- cette mise en œuvre éclipse le problème résolu; c'est une explication, mais pas une justification. Tout système de contrôle de source consiste à "gérer plusieurs fichiers". Regardez simplement quels commentaires sont les plus votés.
Victor Sergienko
90
Quand git stash -p(ou git add -pavec stash --keep-index) serait trop encombrant, je l'ai trouvé plus facile à utiliser diff, checkoutet apply:
Pour «cacher» un fichier / répertoire particulier uniquement:
Alternative intéressante à celle que git add -pj'ai mentionnée dans ma propre réponse ci-dessus. +1.
VonC
11
Notez que si vous avez des fichiers binaires (comme les PNG), ils ne seront pas sortis dans le fichier diff. Ce n'est donc pas une solution à 100%.
void.pointer
1
@RobertDailey: C'est un point intéressant pour moi, comme git diff > file.diffet git applysont mes outils habituels stash partiels. Je devrais peut-être envisager de passer à git stash -pdes ensembles de modifications plus importants.
thekingoftruth
1
@thekingoftruth Voici l'alias que j'utilise pour créer des fichiers de patch, et il fait des binaires de soutien: patch = log --pretty=email --patch-with-stat --reverse --full-index --binary. Notez cependant que cela nécessite vos modifications pour que le correctif soit validé.
void.pointer
2
Cela ne fonctionnait pas correctement pour moi si le fichier à cacher était quelque chose comme ça ../../foo/bar.txt. Le correctif génère OK, mais je dois ensuite passer à la racine du référentiel pour appliquer le correctif. Donc, si vous rencontrez des problèmes avec cela - assurez-vous de le faire à partir du répertoire racine du référentiel.
Michael Anderson
86
Utilisez git stash push, comme ceci:
git stash push [--] [<pathspec>...]
Par exemple:
git stash push -- my/file.sh
Ceci est disponible depuis Git 2.13, sorti au printemps 2017.
Je suis heureux que Git progresse si rapidement, cela n'a pas été possible pendant longtemps, puis la version 2.13 est sortie et soudain, une solution simple est disponible!
sandstrom
1
@VonC vous avez raison, vous mentionnez également la bonne réponse, cependant, entre les deux réponses, celle-ci est plus facile à lire (pas de texte déroutant et il y a aussi un exemple). Peut-être qu'ils auraient dû modifier votre réponse à la place
Utopik
@Utopik Vous m'aviez dit "vous avez raison" ... mais oui, j'ai modifié ma réponse pour inclure un exemple.
VonC
Peut-on alors utiliser git stash applypour récupérer les modifications cachées?
Tchad
49
Disons que vous avez 3 fichiers
a.rb
b.rb
c.rb
et vous ne voulez cacher que b.rb et c.rb mais pas a.rb
vous pouvez faire quelque chose comme ça
# commit the files temporarily you don't want to stash
git add a.rb
git commit -m "temp"
# then stash the other files
git stash save "stash message"
# then undo the previous temp commit
git reset --soft HEAD^
git reset
# Save everything
git stash
# Re-apply everything, but keep the stash
git stash apply
git checkout <"files you don't want in your stash"># Save only the things you wanted saved
git stash
# Re-apply the original state and drop it from your stash
git stash apply stash@{1}
git stash drop stash@{1}
git checkout <"files you put in your stash">
Je l'ai trouvé après être (encore une fois) venu sur cette page et je n'ai pas aimé les deux premières réponses (la première réponse ne répond tout simplement pas à la question et je n'aimais pas vraiment travailler avec le -pmode interactif).
L'idée est la même que ce que @VonC a suggéré d'utiliser des fichiers en dehors du référentiel, vous enregistrez les modifications que vous voulez quelque part, supprimez les modifications que vous ne voulez pas dans votre stash, puis réappliquez les modifications que vous avez déplacées. Cependant, j'ai utilisé la cachette git comme "quelque part" (et en conséquence, il y a une étape supplémentaire à la fin: supprimer les obstacles que vous avez mis dans la cachette, car vous les avez également déplacés).
je préfère le plus cette approche. Il fournit un flux de travail facile en tortoisegit en utilisant uniquement les commandes stash et revert.
Mark Ch
Il n'est pas conseillé de se référer aux réponses sur les SO en utilisant des positions. Les positions changent à mesure que les notes changent.
Bryan Ash
2
@BryanAsh Eh bien, ce n'est pas comme si c'était important ici. Je donne une anecdote plutôt que de me référer vraiment aux autres réponses. Le message est que je n'aimais pas les réponses que la communauté aimait et pas ce que ces réponses contiennent réellement. En outre, l'écart de 900 votes entre la deuxième et la troisième réponse rend peu probable que cela change dans un proche avenir, et si cela devait changer, je peux toujours le modifier pour dire "le plus haut pour les réponses à l'époque". Vraiment, je ne vois pas en quoi c'est un problème dans cette situation.
Jasper
23
Mise à jour (14/02/2015) - J'ai un peu réécrit le script, pour mieux gérer le cas des conflits, qui devraient maintenant être présentés comme des conflits non fusionnés plutôt que des fichiers .rej.
Je trouve souvent plus intuitif de faire l'inverse de l'approche de @ bukzor. C'est-à-dire, pour mettre en scène certains changements, puis ne cacher que ces changements par étapes.
Malheureusement, git n'offre pas de cachette git --only-index ou similaire, j'ai donc préparé un script pour le faire.
#!/bin/sh
# first, go to the root of the git repo
cd `git rev-parse --show-toplevel`
# create a commit with only the stuff in staging
INDEXTREE=`git write-tree`
INDEXCOMMIT=`echo "" | git commit-tree $INDEXTREE -p HEAD`
# create a child commit with the changes in the working tree
git add -A
WORKINGTREE=`git write-tree`
WORKINGCOMMIT=`echo "" | git commit-tree $WORKINGTREE -p $INDEXCOMMIT`
# get back to a clean state with no changes, staged or otherwise
git reset -q --hard
# Cherry-pick the index changes back to the index, and stash.
# This cherry-pick is guaranteed to succeed
git cherry-pick -n $INDEXCOMMIT
git stash
# Now cherry-pick the working tree changes. This cherry-pick may fail
# due to conflicts
git cherry-pick -n $WORKINGCOMMIT
CONFLICTS=`git ls-files -u`
if test -z "$CONFLICTS"; then
# If there are no conflicts, it's safe to reset, so that
# any previously unstaged changes remain unstaged
#
# However, if there are conflicts, then we don't want to reset the files
# and lose the merge/conflict info.
git reset -q
fi
Vous pouvez enregistrer le script ci-dessus git-stash-indexquelque part sur votre chemin, puis l'invoquer en tant que git stash-index
# <hack hack hack>
git add <files that you want to stash>
git stash-index
Maintenant, la cachette contient une nouvelle entrée qui ne contient que les modifications que vous aviez mises en scène, et votre arborescence de travail contient toujours toutes les modifications non mises en scène.
Dans certains cas, les modifications de l'arborescence de travail peuvent dépendre des modifications d'index, donc lorsque vous planifiez les modifications d'index, les modifications de l'arborescence de travail ont un conflit. Dans ce cas, vous obtiendrez les conflits non fusionnés habituels que vous pouvez résoudre avec git merge / git mergetool / etc.
Recommander à la pushdplace cdet popdà la fin du script, donc si le script réussit, l'utilisateur se retrouve dans le même répertoire qu'avant de l'exécuter.
Nate
1
@Nate: pour autant que je sache, cela ne devrait changer le répertoire de l'utilisateur que s'il a trouvé le script. Si vous exécutez le script normalement (~ / bin / git-stash-index), ou via git (git stash-index), il s'exécute dans une session de terminal distincte, et toute modification du répertoire de travail dans cette session n'affecte pas le répertoire de travail dans la session de terminal de l'utilisateur. Êtes-vous au courant d'un cas d'utilisation courant lorsque ce n'est pas vrai? (autre que l'approvisionnement du script, que je ne considérerais pas comme "commun")
JesusFreke
20
Si vous ne souhaitez pas spécifier un message avec vos modifications cachées, passez le nom de fichier après un double tiret.
$ git stash -- filename.ext
S'il s'agit d'un fichier non suivi / nouveau, vous devrez d'abord le mettre en scène.
Cette méthode fonctionne dans les versions git 2.13+
Cette réponse est verbeuse, c'est concis. Si cela aide quelqu'un, je le laisse. Personne sur cette page ne mentionne cette syntaxe et ce résultat - ils mentionnent plutôt `git stash push`.
sealocal
C'est la réponse que je cherchais. Merci! +1
nicodp
19
Étant donné que la création de branches dans Git est triviale, vous pouvez simplement créer une branche temporaire et y archiver les fichiers individuels.
Vous ne pouvez pas créer une branche avec des modifications non échelonnées. Vous pouvez facilement déplacer toutes les modifications vers une nouvelle branche (stash / stash pop) mais vous revenez à la case départ: comment tester votre branche avec seulement certaines de ces modifications, sans perdre les autres?
bukzor
7
Vous ne pouvez pas changer de branche si vous avez des changements locaux. Cependant, vous pouvez créer une nouvelle branche et ajouter / valider des fichiers de manière sélective, puis créer une autre branche et faire la même chose récursivement ... puis extraire la branche d'origine et fusionner de manière sélective. Je viens de le faire. Cela semble en fait la façon naturelle de faire les choses, car vous créez essentiellement des branches de fonctionnalités.
iain
3
@iain vous pouvez changer de branche si vous avez des changements locaux, tant qu'ils ne nécessitent pas de fusion. Voir Exemple Gist . Cela est vrai à partir de Git v2.7.0 au moins.
Cela n'ajoute rien de nouveau. Git stash push est déjà mentionné dans plusieurs réponses
JesusFreke
12
Enregistrez le code suivant dans un fichier, par exemple, nommé stash. L'utilisation est stash <filename_regex>. L'argument est l'expression régulière du chemin complet du fichier. Par exemple, pour ranger un / b / c.txt, stash a/b/c.txtou stash .*/c.txt, etc.
Grande méthode. J'aurais choisi cela comme réponse. Astuce pour les futurs lecteurs: vous devez correspondre sur le chemin complet. par exemple, stash subdir / foo.c
er0
12
Juste au cas où vous voudriez dire supprimer les changements chaque fois que vous utilisez git stash(et n'utilisez pas vraiment git stash pour le ranger temporairement), dans ce cas, vous pouvez utiliser
git checkout -- <file>
[ NOTE ]
C'est git stashjuste une alternative plus rapide et simple à la ramification et à la réalisation de tâches.
Le problème avec la solution `` intermédiaire '' de VonC de copier des fichiers vers l'extérieur du référentiel Git est que vous perdez les informations de chemin, ce qui rend la copie d'un tas de fichiers plus tard un peu compliquée.
A trouver plus facile d'utiliser tar (des outils similaires le feront probablement) au lieu de copier:
tar cvf /tmp/stash.tar chemin / vers / certains / fichier chemin / vers / certains / autres / fichier (... etc.)
git checkout path / to / some / file path / to / some / other / file
checkout -fn'est pas nécessaire, checkout(sans -f) suffit, j'ai mis à jour la réponse.
eleotlecram
8
Parfois, j'ai effectué un changement sans rapport avec ma branche avant de l'avoir validé, et je veux le déplacer vers une autre branche et le valider séparément (comme master). Je fais ça:
git stash
git checkout master
git stash pop
git add <files that you want to commit>
git commit -m 'Minor feature'
git stash
git checkout topic1
git stash pop
...<resume work>...
Notez que le premier stash& stash poppeut être éliminé, vous pouvez reporter toutes vos modifications à la mastersuccursale lors de votre paiement, mais uniquement s'il n'y a pas de conflits. De plus, si vous créez une nouvelle branche pour les modifications partielles, vous aurez besoin de la cachette.
Vous pouvez le simplifier en supposant qu'aucun conflit et aucune nouvelle branche:
git checkout master
git add <files that you want to commit>
git commit -m 'Minor feature'
git checkout topic1
...<resume work>...
Cela peut être fait facilement en 3 étapes en utilisant SourceTree.
Validez temporairement tout ce que vous ne voulez pas cacher.
Git ajoutez tout le reste, puis rangez-le.
Pop votre commit temporaire en exécutant git reset, en ciblant le commit avant votre commit temporaire.
Tout cela peut être fait en quelques secondes dans SourceTree, où vous pouvez simplement cliquer sur les fichiers (ou même les lignes individuelles) que vous souhaitez ajouter. Une fois ajoutés, il suffit de les valider dans un commit temporaire. Ensuite, cochez la case pour ajouter toutes les modifications, puis cliquez sur cachette pour tout cacher. Avec les changements cachés, jetez un œil à votre liste de commit et notez le hachage pour le commit avant votre commit temporaire, puis exécutez 'git reset hash_b4_temp_commit', ce qui revient à "sauter" le commit en réinitialisant votre branche sur le s'engager juste avant. Maintenant, il ne vous reste que ce que vous ne vouliez pas cacher.
J'utiliserais git stash save --patch. Je ne trouve pas l'interactivité ennuyeuse car il y a des options pour appliquer l'opération souhaitée à des fichiers entiers.
Je l'ai essayé mais rien ne se passe. Quand je git applyn'ai aucune erreur mais que les changements ne sont pas non plus rapportés
ClementWalter
Le fichier de correctif que vous avez généré dans / tmp a probablement été supprimé. Vous avez peut-être redémarré entre le diff et l'application. Essayez un autre emplacement plus permanent. Ça marche. Vérifiez également le contenu du fichier de correctif.
Christophe Fondacci
4
J'ai examiné les réponses et les commentaires à ce sujet et un certain nombre de fils similaires. N'oubliez pas qu'aucune des commandes suivantes n'est correcte dans le but de pouvoir stocker des fichiers spécifiques suivis / non suivis :
git stash -p (--patch): sélectionnez les morceaux manuellement, à l'exclusion des fichiers non suivis
git stash -k (--keep-index): stockez tous les fichiers suivis / non suivis et conservez-les dans le répertoire de travail
git stash -u (--include-untracked): cache tous les fichiers suivis / non suivis
git stash -p (--patch) -u (--include-untracked): commande non valide
Actuellement, la méthode la plus raisonnable pour pouvoir stocker des fichiers spécifiques suivis / non suivis consiste à:
Validez temporairement les fichiers que vous ne voulez pas cacher
Pour ranger un seul fichier, utilisez git stash --patch [file].
Cela va rapidement: Stash this hunk [y,n,q,a,d,j,J,g,/,e,?]? ?. Tapez simplement a(cachez ce morceau et tous les morceaux suivants dans le fichier) et tout va bien.
@FilipeEsperandio pushne fonctionne que dans les versions plus récentes de Git, autrefois save. Dans les deux cas pushou savesont implicites en appelant stash: "Appeler git stash sans aucun argument équivaut à git stash push", docs
patrick
2
Situation similaire. Je me suis engagé et j'ai réalisé que ce n'était pas bien.
git commit -a -m "message"
git log -p
Sur la base des réponses, cela m'a aidé.
# revert to previous state, keeping the files changed
git reset HEAD~
#make sure it's ok
git diff
git status
#revert the file we don't want to be within the commit
git checkout specs/nagios/nagios.spec
#make sure it's ok
git status
git diff
#now go ahead with commit
git commit -a -m "same|new message"
#eventually push tu remote
git push
Je ne sais pas comment le faire en ligne de commande, en utilisant uniquement SourceTree. Supposons que vous ayez modifié le fichier A et que vous ayez deux morceaux de modification dans le fichier B. Si vous souhaitez ne cacher que le deuxième morceau dans le fichier B et laisser tout le reste intact, procédez comme suit:
Tout mettre en scène
Apportez des modifications à votre copie de travail qui annulent toutes les modifications du fichier A. (par exemple, lancez l'outil de diff externe et faites correspondre les fichiers.)
Faites en sorte que le fichier B ressemble à si seule une deuxième modification lui est appliquée. (par exemple, lancez l'outil de diff externe et annulez le premier changement.)
Créez une cachette à l'aide de "Conserver les modifications par étapes".
git add . //stage all the files
git reset <pathToFileWillBeStashed> //unstage file which will be stashed
git stash //stash the file(s)
git reset . // unstage all staged files
git stash pop // unstash file(s)
Eh bien, vous ne devriez pas faire ça. La réponse devrait fournir une solution à la question. Vous pouvez simplement poser votre propre question.
L_J
cette solution est l'une des réponses les plus simples à cette question. lisez la question, comparez toutes les réponses et la mienne alors si vous avez le moindre doute que cette réponse n'est ni une solution applicable ni des informations insuffisantes sur la question, alors nous pouvons reparler.
celikz
Cela ne fonctionnera pas, car la troisième commande, "git stash" n'honorera pas les fichiers intermédiaires. Les fichiers intermédiaires et non intermédiaires iront à la cachette. La question demande spécifiquement comment cacher un seul fichier
CyberProdigy
0
Une façon compliquée serait de tout d'abord commettre:
git add -u
git commit // creates commit with sha-1 A
Réinitialisez le commit d'origine mais récupérez le_one_file du nouveau commit:
git reset --hard HEAD^
git checkout A path/to/the_one_file
Maintenant, vous pouvez cacher le_one_file:
git stash
Nettoyage en enregistrant le contenu validé dans votre système de fichiers tout en réinitialisant le commit d'origine:
git stash --keep-index
conserve l'index, mais il cache tout - à la fois dans l'index et à l'extérieur.git diff -- *filename* > ~/patch
puisgit checkout -- *filename*
et plus tard, vous pouvezgit apply ~/patch
git stash push [--] [<pathspec>...]
.Réponses:
Avertissement : la réponse suivante est pour git avant git 2.13. Pour git 2.13 et plus, consultez une autre réponse plus bas .
Attention
Comme indiqué dans les commentaires, cela met tout dans la cachette, à la fois mis en scène et non mis en scène. --Keep-index laisse juste l'index seul une fois le stash terminé. Cela peut entraîner des conflits de fusion lorsque vous ouvrez ultérieurement la réserve.
Cela stockera tout ce que vous n'avez pas ajouté précédemment. Juste
git add
ce que vous voulez garder, puis exécutez-le.Par exemple, si vous souhaitez diviser un ancien commit en plusieurs changements, vous pouvez utiliser cette procédure:
git rebase -i <last good commit>
edit
.git reset HEAD^
git add <files you want to keep in this change>
git stash --keep-index
git add
les modifications.git commit
git stash pop
git rebase --continue
la source
git stash save -k
, oui, l'index (en vertgit stat
) est conservé, mais l' ensemble des modifications (à la fois vert et rouge) va dans la cachette. Cela viole la demande du PO, "ne cache que quelques modifications". Je veux ranger juste une partie du rouge (pour une utilisation future).git stash -p
est exactement ce que je cherchais. Je me demande si ce commutateur n'a été ajouté que récemment.git stash --keep-index
est cassé. Si vous apportez plus de modifications, essayezgit stash pop
ensuite d'obtenir des conflits de fusion car la cachette comprend les fichiers modifiés que vous avez conservés, pas seulement ceux que vous n'avez pas conservés. Par exemple: je modifie les fichiers A et B, puis je stocke B, car je veux tester les modifications dans A; Je trouve un problème avec A que je corrige ensuite; Je commets A; Maintenant, je ne peux pas déchausser car une ancienne version de A est dans la cachette sans raison valable, provoquant un conflit de fusion. Dans la pratique, A et B peuvent avoir de nombreux fichiers, peut-être même des images binaires ou quelque chose, donc je dois essentiellement abandonner et perdre B.Vous pouvez également utiliser
git stash save -p "my commit message"
. De cette façon, vous pouvez sélectionner quels morceaux doivent être ajoutés à la stash, des fichiers entiers peuvent également être sélectionnés.Vous serez invité avec quelques actions pour chaque morceau:
la source
stash -p
. J'attribue cette réponse car elle reste la plus interactive / conviviale.git stash save -p my stash message
:; puisque l'ordre de l'argumenst n'est pas très intuitif ...git log -p
, je pense que le-p
drapeau doit signifier "fais la chose cool que je veux mais je ne sais pas comment l'exprimer".Étant donné que git consiste fondamentalement à gérer tout le contenu et l'index du référentiel (et non un ou plusieurs fichiers)
git stash
, il n'est pas surprenant queavec le répertoire de travail.En fait, depuis Git 2.13 (Q2 2017), vous pouvez cacher des fichiers individuels, avec
git stash push
:Exemple simplifié:
Le scénario de test pour cette fonctionnalité montre quelques options supplémentaires désactivées:
La réponse originale (ci-dessous, juin 2010) concernait la sélection manuelle de ce que vous souhaitez ranger.
Commentaires de Casebash :
bukzor de réponse (upvoted, Novembre 2011) propose une solution plus pratique, basée sur
git add
+git stash --keep-index
.Allez voir et voter pour sa réponse, qui devrait être la réponse officielle (au lieu de la mienne).
À propos de cette option, chhh souligne un autre workflow dans les commentaires:
(Réponse originale juin 2010: plan de travail manuel)
Pourtant, cela
git stash save --patch
pourrait vous permettre d'obtenir le stockage partiel que vous recherchez:Cependant, cela enregistrera l'index complet (qui peut ne pas être ce que vous voulez car il peut inclure d'autres fichiers déjà indexés) et un arbre de travail partiel (qui pourrait ressembler à celui que vous souhaitez ranger).
pourrait être un meilleur ajustement.
Si
--patch
cela ne fonctionne pas, un processus manuel peut:Pour un ou plusieurs fichiers, une solution intermédiaire serait de:
(En fait, eleotlecram propose une alternative intéressante )
git stash
git stash
# cette fois, seuls les fichiers que vous souhaitez sont cachésgit stash pop stash@{1}
# réappliquez toutes vos modifications de fichiersgit checkout -- afile
# réinitialiser le fichier au contenu HEAD, avant toute modification localeÀ la fin de ce processus plutôt lourd, vous n'aurez qu'un ou plusieurs fichiers cachés.
la source
git reset
(mixte)git is fundamentally about managing a all repository content and index and not one or several files
- cette mise en œuvre éclipse le problème résolu; c'est une explication, mais pas une justification. Tout système de contrôle de source consiste à "gérer plusieurs fichiers". Regardez simplement quels commentaires sont les plus votés.Quand
git stash -p
(ougit add -p
avecstash --keep-index
) serait trop encombrant, je l'ai trouvé plus facile à utiliserdiff
,checkout
etapply
:Pour «cacher» un fichier / répertoire particulier uniquement:
Puis après
la source
git add -p
j'ai mentionnée dans ma propre réponse ci-dessus. +1.git diff > file.diff
etgit apply
sont mes outils habituels stash partiels. Je devrais peut-être envisager de passer àgit stash -p
des ensembles de modifications plus importants.patch = log --pretty=email --patch-with-stat --reverse --full-index --binary
. Notez cependant que cela nécessite vos modifications pour que le correctif soit validé.../../foo/bar.txt
. Le correctif génère OK, mais je dois ensuite passer à la racine du référentiel pour appliquer le correctif. Donc, si vous rencontrez des problèmes avec cela - assurez-vous de le faire à partir du répertoire racine du référentiel.Utilisez
git stash push
, comme ceci:Par exemple:
Ceci est disponible depuis Git 2.13, sorti au printemps 2017.
la source
git stash push
déjà dans ma réponse ci-dessus en mars dernier, il y a 5 mois. Et j'ai détaillé cette nouvelle commande Git 2.13 ici: stackoverflow.com/a/42963606/6309 .git stash apply
pour récupérer les modifications cachées?Disons que vous avez 3 fichiers
et vous ne voulez cacher que b.rb et c.rb mais pas a.rb
vous pouvez faire quelque chose comme ça
Et vous avez terminé! HTH.
la source
Une autre façon de procéder:
Je l'ai trouvé après être (encore une fois) venu sur cette page et je n'ai pas aimé les deux premières réponses (la première réponse ne répond tout simplement pas à la question et je n'aimais pas vraiment travailler avec le
-p
mode interactif).L'idée est la même que ce que @VonC a suggéré d'utiliser des fichiers en dehors du référentiel, vous enregistrez les modifications que vous voulez quelque part, supprimez les modifications que vous ne voulez pas dans votre stash, puis réappliquez les modifications que vous avez déplacées. Cependant, j'ai utilisé la cachette git comme "quelque part" (et en conséquence, il y a une étape supplémentaire à la fin: supprimer les obstacles que vous avez mis dans la cachette, car vous les avez également déplacés).
la source
Mise à jour (14/02/2015) - J'ai un peu réécrit le script, pour mieux gérer le cas des conflits, qui devraient maintenant être présentés comme des conflits non fusionnés plutôt que des fichiers .rej.
Je trouve souvent plus intuitif de faire l'inverse de l'approche de @ bukzor. C'est-à-dire, pour mettre en scène certains changements, puis ne cacher que ces changements par étapes.
Malheureusement, git n'offre pas de cachette git --only-index ou similaire, j'ai donc préparé un script pour le faire.
Vous pouvez enregistrer le script ci-dessus
git-stash-index
quelque part sur votre chemin, puis l'invoquer en tant que git stash-indexMaintenant, la cachette contient une nouvelle entrée qui ne contient que les modifications que vous aviez mises en scène, et votre arborescence de travail contient toujours toutes les modifications non mises en scène.
Dans certains cas, les modifications de l'arborescence de travail peuvent dépendre des modifications d'index, donc lorsque vous planifiez les modifications d'index, les modifications de l'arborescence de travail ont un conflit. Dans ce cas, vous obtiendrez les conflits non fusionnés habituels que vous pouvez résoudre avec git merge / git mergetool / etc.
la source
pushd
placecd
etpopd
à la fin du script, donc si le script réussit, l'utilisateur se retrouve dans le même répertoire qu'avant de l'exécuter.Si vous ne souhaitez pas spécifier un message avec vos modifications cachées, passez le nom de fichier après un double tiret.
S'il s'agit d'un fichier non suivi / nouveau, vous devrez d'abord le mettre en scène.
Cette méthode fonctionne dans les versions git 2.13+
la source
Étant donné que la création de branches dans Git est triviale, vous pouvez simplement créer une branche temporaire et y archiver les fichiers individuels.
la source
Vous pouvez simplement faire ceci:
ou avec un message optionnel
la source
Enregistrez le code suivant dans un fichier, par exemple, nommé
stash
. L'utilisation eststash <filename_regex>
. L'argument est l'expression régulière du chemin complet du fichier. Par exemple, pour ranger un / b / c.txt,stash a/b/c.txt
oustash .*/c.txt
, etc.Code à copier dans le fichier:
la source
Juste au cas où vous voudriez dire supprimer les changements chaque fois que vous utilisez
git stash
(et n'utilisez pas vraiment git stash pour le ranger temporairement), dans ce cas, vous pouvez utiliser[ NOTE ]
C'est
git stash
juste une alternative plus rapide et simple à la ramification et à la réalisation de tâches.la source
Le problème avec la solution `` intermédiaire '' de VonC de copier des fichiers vers l'extérieur du référentiel Git est que vous perdez les informations de chemin, ce qui rend la copie d'un tas de fichiers plus tard un peu compliquée.
A trouver plus facile d'utiliser tar (des outils similaires le feront probablement) au lieu de copier:
la source
checkout -f
n'est pas nécessaire,checkout
(sans-f
) suffit, j'ai mis à jour la réponse.Parfois, j'ai effectué un changement sans rapport avec ma branche avant de l'avoir validé, et je veux le déplacer vers une autre branche et le valider séparément (comme master). Je fais ça:
Notez que le premier
stash
&stash pop
peut être éliminé, vous pouvez reporter toutes vos modifications à lamaster
succursale lors de votre paiement, mais uniquement s'il n'y a pas de conflits. De plus, si vous créez une nouvelle branche pour les modifications partielles, vous aurez besoin de la cachette.Vous pouvez le simplifier en supposant qu'aucun conflit et aucune nouvelle branche:
La cachette n'est même pas nécessaire ...
la source
Cela peut être fait facilement en 3 étapes en utilisant SourceTree.
Tout cela peut être fait en quelques secondes dans SourceTree, où vous pouvez simplement cliquer sur les fichiers (ou même les lignes individuelles) que vous souhaitez ajouter. Une fois ajoutés, il suffit de les valider dans un commit temporaire. Ensuite, cochez la case pour ajouter toutes les modifications, puis cliquez sur cachette pour tout cacher. Avec les changements cachés, jetez un œil à votre liste de commit et notez le hachage pour le commit avant votre commit temporaire, puis exécutez 'git reset hash_b4_temp_commit', ce qui revient à "sauter" le commit en réinitialisant votre branche sur le s'engager juste avant. Maintenant, il ne vous reste que ce que vous ne vouliez pas cacher.
la source
J'utiliserais
git stash save --patch
. Je ne trouve pas l'interactivité ennuyeuse car il y a des options pour appliquer l'opération souhaitée à des fichiers entiers.la source
git stash -p
vous permet de cacher un fichier entier rapidement et de quitter ensuite.Chaque réponse ici est tellement compliquée ...
Qu'en est-il de "cacher":
Ceci pour faire revenir le changement de fichier:
Exactement le même comportement que de cacher un fichier et de le réinsérer.
la source
git apply
n'ai aucune erreur mais que les changements ne sont pas non plus rapportésJ'ai examiné les réponses et les commentaires à ce sujet et un certain nombre de fils similaires. N'oubliez pas qu'aucune des commandes suivantes n'est correcte dans le but de pouvoir stocker des fichiers spécifiques suivis / non suivis :
git stash -p (--patch)
: sélectionnez les morceaux manuellement, à l'exclusion des fichiers non suivisgit stash -k (--keep-index)
: stockez tous les fichiers suivis / non suivis et conservez-les dans le répertoire de travailgit stash -u (--include-untracked)
: cache tous les fichiers suivis / non suivisgit stash -p (--patch) -u (--include-untracked)
: commande non valideActuellement, la méthode la plus raisonnable pour pouvoir stocker des fichiers spécifiques suivis / non suivis consiste à:
J'ai écrit un script simple pour cette procédure dans une réponse à une autre question , et il existe des étapes pour effectuer la procédure dans SourceTree ici .
la source
Solution
Changements locaux:
Pour créer un stash "my_stash" avec seulement les modifications sur file_C :
Terminé.
Explication
Vous pouvez utiliser git status entre les étapes pour voir ce qui se passe.
la source
Lorsque vous essayez de basculer entre deux branches, cette situation se produit.
Essayez d'ajouter les fichiers à l'aide de "
git add filepath
".Exécutez plus tard cette ligne
la source
Pour ranger un seul fichier, utilisez
git stash --patch [file]
.Cela va rapidement:
Stash this hunk [y,n,q,a,d,j,J,g,/,e,?]? ?
. Tapez simplementa
(cachez ce morceau et tous les morceaux suivants dans le fichier) et tout va bien.la source
push
comme dansgit stash push --patch [file]
push
ne fonctionne que dans les versions plus récentes de Git, autrefoissave
. Dans les deux caspush
ousave
sont implicites en appelantstash
: "Appeler git stash sans aucun argument équivaut à git stash push", docsSituation similaire. Je me suis engagé et j'ai réalisé que ce n'était pas bien.
Sur la base des réponses, cela m'a aidé.
la source
Dans cette situation, je
git add -p
(interactif),git commit -m blah
puis ranger ce qui reste si nécessaire.la source
Je ne sais pas comment le faire en ligne de commande, en utilisant uniquement SourceTree. Supposons que vous ayez modifié le fichier A et que vous ayez deux morceaux de modification dans le fichier B. Si vous souhaitez ne cacher que le deuxième morceau dans le fichier B et laisser tout le reste intact, procédez comme suit:
la source
la source
Une façon compliquée serait de tout d'abord commettre:
Réinitialisez le commit d'origine mais récupérez le_one_file du nouveau commit:
Maintenant, vous pouvez cacher le_one_file:
Nettoyage en enregistrant le contenu validé dans votre système de fichiers tout en réinitialisant le commit d'origine:
Ouais, un peu maladroit ...
la source
Je n'ai trouvé aucune réponse à ce dont j'avais besoin et c'est aussi simple que:
Cela cache exactement un fichier.
la source
Réponse rapide
Pour rétablir un fichier modifié spécifique dans git, vous pouvez faire la ligne suivante:
Voici un exemple réel:
la source
Si vous voulez cacher des fichiers modifiés, simplement
Il stockera tous les fichiers modifiés non mis en scène
la source