web-dev-qa-db-fra.com

Comment puis-je extraire un seul fichier (ou les modifications apportées à un fichier) à partir d'une réserve git?

J'aimerais savoir s'il est possible d'extraire un seul fichier ou un diff d'un fichier à partir d'une réserve git sans supprimer le groupe de modifications de la réserve.

Quelqu'un pourrait-il être en mesure de fournir des suggestions/idées à ce sujet?

680
Danny

Sur la page de manuel git stash , vous pouvez lire (dans la section "Discussion", juste après la description "Options") que:

Un stash est représenté comme un commit dont l'arborescence enregistre l'état du répertoire de travail et son premier parent est le commit à HEAD lors de la création du stash.

Vous pouvez donc traiter le stash (par exemple, stash@{0} est le premier/le plus haut stash) comme un commit de fusion et utiliser:

$ git diff stash@{0}^1 stash@{0} -- <filename>

Explication: stash@{0}^1 désigne le premier parent de la réserve, qui, comme expliqué dans l'explication ci-dessus, correspond à la validation à laquelle les modifications ont été stockées. Nous utilisons cette forme de "git diff" (avec deux commits) parce que stash@{0}/refs/stash est un commit de fusion et nous devons dire à git quel parent nous voulons comparer. Plus cryptique:

$ git diff stash@{0}^! -- <filename>

devrait également fonctionner (voir git rev-parse page de manuel pour une explication de la syntaxe rev^!, dans la section "Spécification des plages").

De même, vous pouvez utiliser git checkout pour extraire un seul fichier de la réserve:

$ git checkout stash@{0} -- <filename>

ou pour le sauvegarder sous un autre nom de fichier:

$ git show stash@{0}:<full filename>  >  <newfile>

ou

$ git show stash@{0}:./<relative filename> > <newfile>

( note qu'ici <nom de fichier complet> est le chemin complet d'un fichier par rapport au répertoire principal d'un projet (pensez: par rapport à stash@{0}) ).


Vous devrez peut-être protéger stash@{0} de l'expansion du shell, c'est-à-dire utiliser "stash@{0}" ou 'stash@{0}'.

1000
Jakub Narębski

Si vous utilisez git stash apply plutôt que git stash pop, il appliquera le stash à votre arbre de travail tout en conservant le stash.

Ceci fait, vous pouvez add/commit le fichier souhaité, puis réinitialiser les modifications restantes.

41
Tim Henigan

Réponse courte

Pour voir le fichier entier: git show stash@{0}:<filename>

Pour voir le diff: git diff stash@{0}^1 stash@{0} -- <filename>

21
Luboš Turek

Il existe un moyen simple d’obtenir des modifications de toutes les branches, y compris les caches:

$ git checkout --patch stash@{0} path/to/file

Vous pouvez omettre la spécification de fichier si vous souhaitez appliquer plusieurs correctifs. Ou omettez patch (mais pas le chemin) pour obtenir toutes les modifications dans un seul fichier. Remplacez 0 par le numéro de cachette de git stash list, si vous en avez plusieurs. Notez que cela ressemble à diff, et vous propose d’appliquer tous différences entre les branches. Pour obtenir les modifications d'un seul commit/stash, jetez un œil à git cherry-pick --no-commit.

19
Walf
$ git checkout stash@{0} -- <filename>

Remarques:

  1. Assurez-vous de mettre après le "-" et le paramètre de nom de fichier

  2. Remplacez zéro (0) par votre numéro de cachette spécifique. Pour obtenir une liste cachée, utilisez:

    git stash list
    

Basé sur réponse de Jakub Narębski - Version plus courte

12
Ram

Vous pouvez obtenir le diff pour un stash avec "git show stash@{0}" (ou quel que soit le numéro du stash; voir "git stash list"). Il est facile d'extraire la section de la diff pour un seul fichier.

10
Nathan Kitchen

Le concept le plus simple à comprendre, bien que peut-être pas le meilleur, est que trois fichiers ont été modifiés et que vous souhaitez stocker un fichier.

Si vous faites git stash pour les cacher tous, git stash apply pour les ramener, puis git checkout f.c sur le fichier en question pour le réinitialiser.

Lorsque vous souhaitez supprimer ce fichier, exécutez un git reset --hard puis relancez git stash apply, en tirant parti du fait que git stash apply ne supprime pas le diff de la pile de stockage.

5
Philluminati

Si les fichiers stockés doivent fusionner avec la version actuelle, utilisez les méthodes précédentes en utilisant diff. Sinon, vous pouvez utiliser git pop pour les stocker, git add fileWantToKeep pour stocker votre fichier et faire un git stash save --keep-index pour tout stocker sauf ce qui est sur scène. Rappelez-vous que la différence entre les versions précédentes et les versions précédentes réside dans le fait que le fichier est extrait du fichier stash. Les réponses précédentes le conservent git checkout stash@{0} -- <filename> afin qu’il soit adapté à vos besoins.