web-dev-qa-db-fra.com

Pourquoi la réserve ne peut-elle pas être appliquée au répertoire de travail?

Je ne peux pas appliquer stash au répertoire de travail.

Petite histoire:

J'ai d'abord essayé de pousser certaines modifications engagées, mais il était écrit: "non, vous ne pouvez pas, commencez par tirer" ... OK, alors, je vais extraire des éléments de GitHub, puis appuyer sur Mes modifications. Quand j'ai essayé de tirer, il a dit que j'avais des modifications qui seraient écrasées et que je devais cacher mes modifications. OK, j'ai caché les modifications ... fait le pull, et poussez les modifications validées. Mais maintenant, je ne peux pas restaurer les modifications non validées sur lesquelles je travaillais.

C'est l'erreur:

MyPath/File.cs already exists, no checkout
Could not restore untracked files from stash

Bien sûr, je ne comprends pas encore tous les concepts de git, ils me confondent un peu… peut-être que j'ai fait quelque chose de mal.

Ce serait formidable si quelqu'un pouvait m'aider à résoudre ce problème ... Je recherche Google et tout depuis plus d'une heure maintenant et je ne suis pas encore parvenu à une solution.

L'aide est très appréciée. Merci!

87
Miguel Angelo

Il semble que votre cachette comprenne un fichier non suivi qui a été ajouté au référentiel par la suite. Lorsque vous essayez de vérifier, git refuse à juste titre car il écraserait un fichier existant.

Pour résoudre ce problème, vous pouvez, par exemple, supprimer ce fichier (ça va, il est toujours dans le référentiel), appliquer votre réserve, puis remplacer la version stockée du fichier par la version stockée, selon le cas.

Edit: Il est également possible que le fichier n'ait été créé que dans l'arborescence de travail sans que ait été ajouté au référentiel. Dans ce cas, ne supprimez pas simplement le fichier local, mais plutôt:

  1. déplacez-le ailleurs
  2. appliquer la cachette
  3. fusionner manuellement les deux versions de fichier (arbre de travail vs déplacé).
72
blahdiblah

Le moyen le plus sûr et le plus simple serait probablement de ranger les choses:

git stash -u             # This will stash everything, including unstaged files
git stash pop stash@{1}  # This will apply your original stash

Ensuite, si vous êtes satisfait du résultat, vous pouvez appeler

git stash drop

pour enlever votre cachette "sûre".

55
Koraktor

Comme mentionné par @blahdiblah, vous pouvez supprimer manuellement les fichiers dont il se plaint, changer de branche, puis les rajouter manuellement. Mais personnellement, je préfère rester "au sein de git".

La meilleure façon de le faire est de convertir la réserve en une branche. Une fois qu’il s’agit d’une branche, vous pouvez travailler normalement dans git en utilisant les techniques/outils normaux liés aux branches que vous connaissez et aimez. C'est en fait une technique générale utile pour travailler avec des stash, même si vous n'avez pas l'erreur répertoriée. Cela fonctionne bien, car une cachette est vraiment un commit sous les couvertures (voir PS).

Conversion d'une réserve en une branche

Ce qui suit crée une branche basée sur le HEAD quand la cachette a été créée) puis applique la cachette (elle ne la commet pas).

git stash branch STASHBRANCH

Travailler avec la "branche stash"

Ce que vous ferez ensuite dépend de la relation entre la réserve et l'emplacement actuel de votre branche cible (que j'appellerai ORIGINALBRANCH).

Option 1 - Rebaser la branche stash normalement (beaucoup de modifications depuis stash)

Si vous avez apporté beaucoup de modifications à votre ORIGINALBRANCH, vous traiterez probablement mieux STASHBRANCH comme n'importe quelle succursale locale. Validez vos modifications dans STASHBRANCH, refaites-le sur ORIGINALBRANCH, puis passez à ORIGINALBRANCH et rebasez/fusionnez les modifications apportées par STASHBRANCH. S'il y a des conflits, gérez-les normalement (l'un des avantages de cette approche est que vous pouvez voir et résoudre les conflits).

Option 2 - Réinitialiser la branche d'origine pour qu'elle corresponde à la dissimulation (modifications limitées depuis la dissimulation)

Si vous vous contentez de stocker certaines modifications planifiées, puis de les valider et que tout ce que vous voulez, c'est obtenir les modifications supplémentaires que vous n'avez pas encore stockées, vous pouvez procéder comme suit. Il reviendra à votre branche et index d'origine sans changer votre copie de travail. Le résultat final sera vos changements de cache supplémentaires dans votre copie de travail.

git symbolic-ref HEAD refs/heads/ORIGINALBRANCH
git reset

Contexte

Les stash sont des commits, comme des branches/tags (et non des patchs)

PS, il est tentant de considérer une réserve comme un correctif (tout comme il est tentant de considérer un commit comme un correctif), mais une cachette est en fait un commit contre le HEAD quand il Lorsque vous appliquez/pop, vous effectuez quelque chose de similaire à la sélection sélective dans votre branche actuelle. N'oubliez pas que les branches et les balises ne sont en réalité que des références à des commits; façons de désigner un commit (et son histoire).

Parfois nécessaire même lorsque vous n'avez pas modifié le répertoire de travail

PPS, vous pouvez avoir besoin de cette technique après avoir simplement utilisé stash avec --patch et/ou --include-untracked. Même sans modifier les répertoires de travail, ces options peuvent parfois créer une réserve que vous ne pouvez pas simplement appliquer. Je dois avouer que je ne comprends pas très bien pourquoi. Voir http://git.661346.n2.nabble.com/stash-refuses-to-pop-td7453780.html pour en savoir plus.

52
studgeek

La solution: Vous devez supprimer le fichier en question, puis essayer de stocker à nouveau le fichier pop/apply et il devrait être traité. Ne supprimez pas d'autres fichiers, juste ceux mentionnés par l'erreur.

Le problème: Git craint parfois. Lorsque vous exécutez git stash -u il inclut les fichiers non suivis (cool!) mais ne le fait pas supprime ces fichiers non suivis et ne le fait pas sais comment appliquer les fichiers non suivis cachés au-dessus des restes (non cool!), ce qui rend le -u option assez inutile.

39
qwertzguy

Pour appliquer les différences de code dans la stash en tant que correctif, utilisez la commande suivante:

git stash show --patch | patch -p1
23
ciphersimian

Mon opération pop bloquée de la même manière était due aux fichiers ignorés (voir le fichier .gitignore). Le statut Git m'a montré suivi et non suivi, mais mes activités n'ont pas nettoyé les fichiers ignorés.

Détails: J'avais utilisé git stash save -a, extrait le maître pour compiler et voir le comportement original, puis tente de tout remettre en place pour continuer l’édition. Lorsque j'ai vérifié ma branche et essayé de faire apparaître des fichiers, mes fichiers ignorés étaient toujours là avant la sauvegarde stash. En effet, l'extraction du maître n'a affecté que les fichiers validés - elle n'a pas effacé les fichiers ignorés. Donc, la pop a échoué, en disant essentiellement qu'il ne voulait pas restaurer mes fichiers cachés ignorés au-dessus des fichiers qui étaient toujours là. Il est regrettable que je n’aie pas trouvé le moyen de commencer une session de fusion avec eux.

Finalement, j'ai utilisé git clean -f -d -x pour supprimer les fichiers ignorés. Fait intéressant, de mes ~ 30, 4 fichiers sont restés après le nettoyage (enterrés dans des sous-répertoires). Je vais devoir comprendre dans quelle catégorie ils se trouvent, qu'ils devaient être supprimés manuellement.

Puis ma pop a réussi.

0
deasserted

Essaye ça:

git checkout stash -.

0
Nalan Madheswaran

Cela m'est arrivé à plusieurs reprises, j'ai caché des fichiers non suivis avec git stash -u qui finit par être ajouté au repo et je ne peux plus appliquer les modifications cachées.

Je ne pouvais pas trouver un moyen de forcer git stash pop/apply pour remplacer les fichiers, donc je commence par supprimer les copies locales des fichiers non suivis qui ont été stockés (faites attention car cela supprimera toutes les modifications non validées), puis appliquerai les modifications stockées :

rm `git ls-tree -r stash@{0}^3 --name-only`
git stash apply

Enfin, j'utilise git status, git diff et d’autres outils permettant de vérifier et d’ajouter des parties des fichiers supprimés s’il manque quelque chose.


Si vous souhaitez conserver des modifications non validées, vous pouvez d'abord créer une validation temporaire:

git add --all
git commit -m "dummy"
rm `git ls-tree -r stash@{0}^3 --name-only`
git stash apply

Utilisez les outils de votre choix pour fusionner les modifications précédemment validées dans les fichiers locaux et supprimez le commit factice:

git reset HEAD~1
0
Helder Pereira