Comment planifiez-vous un fichier non suivi?

1437

J'ai apporté des modifications à un fichier, plus un nouveau fichier, et j'aimerais utiliser git stash pour les ranger pendant que je passe à une autre tâche. Mais git stash en lui-même ne cache que les modifications apportées au fichier existant; le nouveau fichier reste dans mon arbre de travail, encombrant mon futur travail. Comment puis-je cacher ce fichier non suivi?

skiphoppy
la source
27
Sachez que si vous n'avez que des fichiers non suivis dans votre stash, cela ressemblera à un fichier vide, car dans git stash showne retourne rien et vous pourriez être tenté de le supprimer (comme je viens de le faire alors qu'il contenait un script utile que j'ai écrit il y a quelques mois) → comment récupérer une réserve perdue )
Maxime R.

Réponses:

1925

Pour ranger votre répertoire de travail, y compris les fichiers non suivis (en particulier ceux qui sont dans le .gitignore), alors vous voudrez probablement utiliser cette cmd:

git stash --include-untracked

Plus de détails:

Mise à jour du 17 mai 2018:

Les nouvelles versions de git ont désormais git stash --allqui stocke tous les fichiers, y compris les fichiers non suivis et ignorés.
git stash --include-untrackedne touche plus les fichiers ignorés (testé sur git 2.16.2).

Réponse originale ci-dessous:

Attention, cela supprimera définitivement vos fichiers si vous avez des entrées de répertoire / * dans votre fichier gitignore.

Depuis la version 1.7.7, vous pouvez utiliser git stash --include-untrackedou git stash save -upour cacher des fichiers non suivis sans les mettre en scène.

Ajoutez ( git add) le fichier et commencez à le suivre. Puis planque. Étant donné que le contenu entier du fichier est nouveau, il sera caché et vous pourrez le manipuler si nécessaire.

sykora
la source
4
Pourquoi stash cache-t-il toujours les fichiers existants modifiés même si ces modifications n'ont pas été mises en scène?
Alan Christensen
6
@ alan-christensen Lisez la DESCRIPTION de kernel.org/pub/software/scm/git/docs/git-stash.html . Le but est d'avoir un arbre de travail propre après le stockage.
Kelvin
3
@Kelvin, ce que je voulais dire dans mon commentaire, c'est qu'il ne stocke pas de nouveaux fichiers à moins qu'ils aient été mis en scène, mais il cache des fichiers existants même s'ils n'ont pas été mis en scène. Cela me semble incohérent.
Alan Christensen
11
@AlanChristensen, le but est de cacher des choses qui pourraient être écrasées par le paiement d'une autre succursale.
jwg
3
Comme vous avez la meilleure réponse ici, je vous demanderais de faire une liste git stash --include-untrackedavant git stash --alldans votre réponse pour deux raisons. D'abord, il répond mieux à la question du PO maintenant en 2019 et ensuite parce que --tout fait quelque chose que la plupart des utilisateurs ne veulent probablement pas en ce qu'il supprime tous les fichiers qui sont .gitignored
Daniel Flippance
411

Depuis git 1.7.7, git stashaccepte l' --include-untrackedoption (ou raccourci -u). Pour inclure des fichiers non suivis dans votre stash, utilisez l'une des commandes suivantes:

git stash --include-untracked
git stash -u

Attention, cela supprimera définitivement vos fichiers si vous avez des entrées de répertoire / * dans votre fichier gitignore.

John Kary
la source
15
Cool - cela fonctionne enfin comme décrit dans la page de manuel. Ne pas ranger (et nettoyer) de nouveaux fichiers est un comportement défectueux.
Steve Bennett
1
ma version de git est 1.9.1 et même si ce que j'ai en .gitignoreressemble à ceci ignoredDirectoryet non, ignoredDirectory/*il supprime toujours ceux qui ne sont pas suivis. Même les fichiers non suivis, pas seulement les répertoires.
theUnknown777
22
Pouvez-vous expliquer l'avertissement? Pourquoi supprimerait-il ces fichiers? Les supprime-t-il et ne les cache-t-il pas? J'ai utilisé Git pendant un certain temps et je n'ai pas rencontré ce problème.
Aleksandr Dubinsky du
L'avertissement s'applique-t-il également aux *.extensionentrées?
arekolek
3
@ aleksandr-dubinsky, @arekolek - L' option git1.8.3 -u( --include-untracked) peut bien cacher et pop les fichiers non suivis mais git stash showne répertorie pas les fichiers non suivis qui sont dans la réserve
xilef
77

Ajoutez le fichier à l'index:

git add path/to/untracked-file
git stash

L'intégralité du contenu de l'index, ainsi que toutes les modifications non mises en scène des fichiers existants, seront tous placés dans la cachette.

skiphoppy
la source
Que faire si vous ne souhaitez pas masquer les modifications déjà présentes dans l'index? Le stockage du nouveau fichier est-il toujours possible?
allyourcode
Validez l'index, cachez le nouveau fichier, puis annulez la validation et / ou extrayez les fichiers de la validation. C'est une solution délicate, mais cela devrait fonctionner.
Gdalya
git add .ne le prenait pas en considération pour une raison quelconque
TheBilTheory
53

Dans git bash, le stockage des fichiers non suivis est réalisé en utilisant la commande

git stash --include-untracked

ou

git stash -u

http://git-scm.com/docs/git-stash

git stash supprime tous les fichiers non suivis ou non engagés de votre espace de travail. Et vous pouvez rétablir git stash en utilisant les commandes suivantes

git stash pop

Cela replacera le fichier dans votre espace de travail local.

Mon expérience

J'ai dû effectuer une modification de mon fichier gitIgnore pour éviter le déplacement des fichiers .classpath et .project dans le référentiel distant. Je ne suis pas autorisé à déplacer ce .gitIgnore modifié dans le référentiel distant à partir de maintenant.

Les fichiers .classpath et .project sont importants pour eclipse - qui est mon éditeur java.

J'ai tout d'abord ajouté sélectivement le reste des fichiers et je me suis engagé pour la mise en scène. Cependant, la poussée finale ne peut pas être effectuée à moins que les fichiers .gitIgnore modifiés et les fichiers non suivis à savoir. .project et .classpath ne sont pas cachés.

j'ai utilisé

 git stash 

pour ranger le fichier .gitIgnore modifié.

Pour ranger les fichiers .classpath et .project, j'ai utilisé

git stash --include-untracked

et il a supprimé les fichiers de mon espace de travail. L'absence de ces fichiers enlève ma capacité de travailler sur mon lieu de travail dans Eclipse. J'ai poursuivi la procédure de transfert à distance des fichiers validés. Une fois que cela a été fait avec succès, j'ai utilisé

git stash pop

Cela a collé les mêmes fichiers dans mon espace de travail. Cela m'a redonné ma capacité à travailler sur le même projet dans Eclipse. J'espère que cela écarte les idées fausses.

DolphinJava
la source
2
Pourquoi n'utilisez-vous pas gitignore global pour les fichiers IDE? C'est à dire. utiliser ~/.gitignore.
Antti Pihlaja
20

Comme cela a été dit ailleurs, la réponse est au git adddossier. par exemple:

git add path/to/untracked-file
git stash

Cependant, la question se pose également dans une autre réponse: que faire si vous ne voulez pas vraiment ajouter le fichier? Pour autant que je sache, vous devez le faire. Et ce qui suit ne fonctionnera PAS :

git add -N path/to/untracked/file     # note: -N is short for --intent-to-add
git stash

cela échouera, comme suit:

path/to/untracked-file: not added yet
fatal: git-write-tree: error building trees
Cannot save the current index state

Alors que peux-tu faire? Eh bien, vous devez vraiment ajouter le fichier, cependant , vous pouvez effectivement le supprimer ultérieurement, avec git rm --cached:

git add path/to/untracked-file
git stash save "don't forget to un-add path/to/untracked-file" # stash w/reminder
# do some other work
git stash list
# shows:
# stash@{0}: On master: don't forget to un-add path/to/untracked-file
git stash pop   # or apply instead of pop, to keep the stash available
git rm --cached path/to/untracked-file

Et puis vous pouvez continuer à travailler, dans le même état que vous étiez avant le git add(à savoir avec un fichier non suivi appelé path/to/untracked-file; plus toutes les autres modifications que vous auriez pu avoir à suivre les fichiers).

Une autre possibilité pour un flux de travail à ce sujet serait quelque chose comme:

git ls-files -o > files-to-untrack
git add `cat files-to-untrack` # note: files-to-untrack will be listed, itself!
git stash
# do some work
git stash pop
git rm --cached `cat files-to-untrack`
rm files-to-untrack

[Remarque: Comme mentionné dans un commentaire de @mancocapac, vous souhaiterez peut-être ajouter --exclude-standardà la git ls-filescommande (donc, git ls-files -o --exclude-standard).]

... qui pourrait également être facilement scripté - même les alias feraient l'affaire (présentés dans la syntaxe zsh; ajustez selon les besoins) [aussi, j'ai raccourci le nom du fichier pour qu'il tienne tout sur l'écran sans faire défiler cette réponse; n'hésitez pas à remplacer un autre nom de fichier de votre choix]:

alias stashall='git ls-files -o > .gftu; git add `cat .gftu`; git stash'
alias unstashall='git stash pop; git rm --cached `cat .gftu`; rm .gftu'

Notez que ce dernier pourrait être mieux comme un script shell ou la fonction, pour permettre les paramètres à fournir à git stash, au cas où vous ne voulez pas , popmais apply, et / ou si vous voulez être en mesure de spécifier une planque spécifique, plutôt que de prendre le dessus une. Peut-être que ceci (au lieu du deuxième alias ci-dessus) [espace blanc dépouillé pour tenir sans défilement; rajouter pour une lisibilité accrue]:

function unstashall(){git stash "${@:-pop}";git rm --cached `cat .gftu`;rm .gftu}

Remarque : Dans ce formulaire, vous devez fournir un argument d'action ainsi que l'identifiant si vous allez fournir un identifiant de stash, par exemple unstashall apply stash@{1}ouunstashall pop stash@{1}

Lequel bien sûr vous mettriez dans votre .zshrcou équivalent pour faire exister à long terme.

J'espère que cette réponse sera utile à quelqu'un, tout rassembler dans une seule réponse.

lindes
la source
1
git ls-files -o montre beaucoup plus de fichiers que ceux qui m'intéressent. Du statut git suivant , j'ai trouvé en ajoutant --exclude-standard works. git ls-files -o --exclude-standard. Mon point de vue est qu'il "n'inclut" que les fichiers non suivis que vous ne devriez pas ignorer normalement, c'est-à-dire n'affichez que les fichiers non suivis que votre .gitignore ne filtrerait pas
mancocapac
20

Sur git version 2.8.1: les travaux suivants me conviennent.

Pour enregistrer des fichiers modifiés et non suivis dans une cachette sans nom

git stash save -u

Pour enregistrer des fichiers modifiés et non suivis dans la cachette avec un nom

git stash save -u <name_of_stash>

Vous pouvez utiliser pop ou appliquer plus tard comme suit.

git stash pop

git stash apply stash@{0}
user1012513
la source
Cela n'a pas supprimé les fichiers non suivis de mon ordinateur, bien qu'ils ne soient plus répertoriés comme non suivis. git stash showne leur a pas montré. Lorsque j'ai essayé git stash apply, j'ai obtenu "erreur: impossible de restaurer les fichiers non suivis de la cachette". Cependant, les fichiers ont à nouveau été répertoriés comme non suivis, mais les modifications apportées aux fichiers suivis n'ont pas été restaurées. Je pense que ces fichiers pourraient être restaurés individuellement en les retirant de la cachette, mais cette solution n'était pas ce que j'espérais.
hBrent
9

J'ai pu cacher uniquement les fichiers non suivis en faisant:

git stash save "tracked files I'm working on"
git stash save -u "untracked files I'm trying to stash"
git stash pop stash@{1}

Le dernier fait apparaître la cachette des fichiers suivis, ne laissant ainsi que les fichiers non suivis cachés.

Oded
la source
git stash save -une sauvegarde pas seulement les untrackedfichiers, il enregistre à la fois le trackedet untracked. Je pense que la première sauvegarde que vous faites n'est pas nécessaire dans ce cas. Il y a un bon schéma atlassian.com/git/tutorials/saving-changes/...
Drenai
2
La question est de savoir comment cacher uniquement les fichiers non suivis. Si vous sautez la première cachette, que ferez-vous apparaître? L'idée est de: 1) Stash suivi. 2) Stash non suivi. 3) Pop suivi. Résultat: Untracked reste caché.
Oded
3

Si vous voulez cacher des fichiers non suivis, mais conserver des fichiers indexés (ceux que vous êtes sur le point de valider par exemple), ajoutez simplement l' -koption (garder l'index) à la-u

git stash -u -k
Tdy
la source
2

Vous pouvez simplement le faire avec la commande ci-dessous

git stash save --include-untracked

ou

git stash save -u

Pour en savoir plus sur git stash, visitez cet article (cliquez ici)

shubham mishra
la source
2

supposons que le fichier nouveau et non suivi s'appelle: "views.json". si vous souhaitez changer de branche en cachant l'état de votre application, je tape généralement:

git add views.json

Alors:

git stash

Et ce serait caché. Ensuite, je peux simplement changer de branche avec

git checkout other-nice-branch
martline1
la source
1

Il y a plusieurs réponses correctes ici, mais je voulais souligner que pour les nouveaux répertoires entiers, 'git add path'cela ne fonctionnera PAS . Donc, si vous avez un tas de nouveaux fichiers dans un chemin non suivi et faites ceci:

git add untracked-path
git stash "temp stash"

cela se cachera avec le message suivant:

Saved working directory and index state On master: temp stash
warning: unable to rmdir untracked-path: Directory not empty

et si le chemin non suivi est le seul chemin que vous planquez, le cache "temp stash" sera un cache vide. La bonne façon consiste à ajouter le chemin complet, pas seulement le nom du répertoire (c'est-à-dire terminer le chemin par un '/'):

git add untracked-path/
git stash "temp stash"
DrStrangepork
la source
Au moins sur mon système, votre hypothèse est fausse. Cela fonctionne sans barre oblique! Les répertoires vides sont de toute façon ignorés. (macos git 2.6.2)
phobie
0

J'ai pensé que cela pourrait être résolu en disant à git que le fichier existe, plutôt qu'en validant tout son contenu dans la zone de transit, puis en appelant git stash. Araqnid décrit comment faire le premier.

git add --intent-to-add path/to/untracked-file

ou

git update-index --add --cacheinfo 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 path/to/untracked-file

Cependant, ce dernier ne fonctionne pas:

$ git stash
b.rb: not added yet
fatal: git-write-tree: error building trees
Cannot save the current index state
Andrew Grimm
la source
1
Pour autant que je sache, le premier ne fonctionne pas non plus. Voir ma réponse pour une solution à ce problème.
lindes
0
git stash --include-untracked

mon préféré car il enregistre également les fichiers que vous avez ajoutés et ne les avez pas mis en scène.

Hovhannes Babayan
la source
0

J'ai rencontré un problème similaire lors de l'utilisation de Sourcetree avec des fichiers nouvellement créés (ils ne seraient pas non plus inclus dans la cachette).

Lorsque j'ai choisi pour la première fois «tout mettre en scène», puis ranger les composants nouvellement ajoutés où ils sont suivis et donc inclus dans la stash.

Ivo van Leeuwen
la source
Cette question a 11 ans et a déjà 14 réponses. Les avez-vous lus avant de poster?
Mickael B.
-7

J'avais l'habitude de réfléchir et de désirer la même fonctionnalité. Mais avec le temps, j'ai remarqué que ce n'était vraiment pas nécessaire. Lorsque vous planquez, vous pouvez laisser les nouveaux fichiers. Rien de "mauvais" ne peut leur arriver (lorsque vous extrayez quelque chose d'autre, git générera une erreur et n'écrasera pas le fichier non suivi existant)

Et comme généralement l'intervalle de temps entre le git stashet le git stash popest assez petit, vous aurez à nouveau rapidement besoin du fichier non suivi. Je dirais donc que l'inconvénient du fichier apparaissant pendant git statusque vous travaillez sur quelque chose d'autre (entre le git stashet le git stash pop) est plus petit que l'inconvénient causé par le travail et l'attention qu'il faudrait autrement pour essayer d'ajouter le fichier non suivi à votre cachette.

Dieter_be
la source
15
Cela depend du projet. Supposons que le fichier non suivi soit un test unitaire (à moitié écrit) et que le faisceau de tests exécute tous les tests unitaires dans le répertoire. Etc.
Steve Bennett
1
Un autre exemple est si vous travaillez sur deux ordinateurs et que vous êtes autorisé à déplacer des données de A vers B, mais pas de B vers A. Si vous créez un nouveau morceau de code pour résoudre un problème qui se produit d'abord sur B mais que vous voulez à la fois sur A et B, vous voulez pouvoir cacher le fichier sur B de sorte que lorsque vous recréez ce fichier sur A puis le placez dans un bundle, vous pouvez git diff la version cachée pour vérifier que vous n'avez pas faire une erreur.
Gdalya
7
Le fait qu'un fichier ne soit pas suivi dans une branche ne signifie pas qu'il n'entrera pas en conflit avec un fichier suivi dans une autre branche.
jwg
3
contre-exemple simple: fichier de configuration dans le répertoire .conf.d, ou tout autre qui, uniquement en étant là, modifie le comportement du logiciel.
fotanus
Bien sûr, la fonctionnalité est nécessaire. Il n'est pas possible, à titre d'exemple supplémentaire, de passer d'une branche à une autre si vous avez des fichiers localement non suivis que vous vouliez cacher.
Demitrian