Dans git, existe-t-il un moyen d'afficher les fichiers cachés non suivis sans appliquer la cachette?

100

Si je cours git stash -u, je peux cacher les fichiers non suivis. Cependant, lesdits fichiers non suivis n'apparaissent pas du tout avec git stash show stash@{0}. Existe-t-il un moyen d'afficher les fichiers cachés non suivis sans appliquer la cachette?

Max Nanasy
la source

Réponses:

121

Les fichiers non suivis sont stockés dans le troisième parent d'un commit de stash. (Ce n'est pas vraiment documenté, mais c'est assez évident à partir du commit qui a introduit la fonctionnalité -u, 787513 ... , et de la façon dont le reste de la documentation pour lesgit-stash phrases choses ... ou simplement en faisant git log --graph stash@{0})

Vous pouvez afficher uniquement la partie "non suivie" de la réserve via:

git show stash@{0}^3

ou, simplement l'arbre "non suivi" lui-même, via:

git show stash@{0}^3:

ou, un fichier "non suivi" particulier dans l'arborescence, via:

git show stash@{0}^3:<path/to/file>

Il n'y a, malheureusement, aucun bon moyen d'obtenir un résumé des différences entre tous les états mis en scène + non mis en scène + non suivi et "actuel". ie: git show stash@{0}ne peut pas être fait pour inclure les fichiers non suivis. Cela est dû au fait que l'objet d'arborescence de la validation de stash lui-même, appelé stash@{0}:, n'inclut aucune modification par rapport au troisième parent "sans étape".

Ceci est dû à la façon dont les stashes sont réappliqués: les fichiers suivis peuvent être facilement appliqués comme correctifs, alors que les fichiers non suivis ne peuvent être appliqués, en théorie, que comme des "fichiers entiers".

Will Palmer
la source
Ainsi, les parents du commit stash sont (1. Le stash de validation est fait contre 2. Index 3. Copie de travail non suivie), et le commit de stash lui-même contient la copie de travail suivie? git stash showsemble montrer la différence entre la copie de travail et # 1 (code pertinent de git-stash.sh:, git diff ${FLAGS:---stat} $b_commit $w_commitdans lequel $ b_commit est # 1 et $ w_commit est le commit stash); existe-t-il un moyen intégré pour git stash showinclure également # 3?
Max Nanasy
Comme vous le dites, je ne l' ai pas trouvé un moyen d'obtenir une seule vue synthétique d'une planque, mais vous pouvez voir ses informations complète en une seule commande avec: git log --graph --topo-order -m -u. matthewlmcclure.com/s/2014/01/10/…
Matt McClure
4
Notez que vous obtenez une erreur moche ( fatal: ambiguous argument 'stash@{0}^3': unknown revision or path not in the working tree.) si vous n'avez pas de fichiers non suivis dans cette cachette (mais que vous pensiez l'avoir fait).
Randall
2
@antak: Nope, git stash showne pas afficher les fichiers non suivis (vrai pour au moins git 2.7.4):
Norbert BERCI
1
Remarque (2.13.2-linux): git stash popessaiera d'abord de restaurer les fichiers non suivis, puis tentera de restaurer les fichiers suivis. Si la dernière opération échoue (par exemple, un conflit), la première opération n'est pas annulée (le fichier caché non suivi restera tel quel mais les fichiers ne sont pas supprimés du disque), donc même si vous corrigez le conflit, le pop suivant échouera en tous cas.
Marinos An
22

Vous pouvez lister tous les commits stash avec la commande suivante:

git rev-list -g stash

Étant donné que les stashes sont représentés comme un commit de fusion à 3 voies de HEAD, de l'index et d'un commit "racine" sans parent de fichiers non suivis, les stashes de fichiers non suivis peuvent être répertoriés en redirigeant la sortie ci-dessus dans ce qui suit:

git rev-list -g stash | git rev-list --stdin --max-parents=0

Applications utiles de ce qui précède:

Afficher uniquement les fichiers cachés non suivis

git rev-list -g stash | git rev-list --stdin --max-parents=0 | xargs git show --stat

Bien sûr, supprimez le --statpour voir le contenu des fichiers.

Trouver un fichier spécifique

git rev-list -g stash | xargs -n1 git ls-tree -r | sort -u | grep <pattern>

Grep fichiers non suivis

git rev-list -g stash | git rev-list --stdin --max-parents=0 | xargs git grep <pattern>

Lister tous les contenus de tous les stashes

git rev-list -g stash | git rev-list --stdin | xargs git show --stat
Steve
la source
10

Pour répertorier les fichiers non suivis dans la réserve:

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

Pour afficher une différence complète de tous les fichiers non suivis (avec contenu):

git show stash@{0}^3

Ces commandes lisent la dernière cachette (la plus récente). Pour les précédents stash, incrémentez le nombre derrière le "stash @", par exemple stash@{2}pour le deuxième du dernier stash.

La raison pour laquelle cela fonctionne est que git stashcrée un commit de fusion pour chaque stash, qui peut être référencé comme stash@{0}, stash@{1}etc. Le premier parent de ce commit est le HEAD au moment du stash, le second parent contient les modifications des fichiers suivis et troisième (qui peut ne pas exister) les modifications apportées aux fichiers non suivis.

Ceci est en partie expliqué dans la page de manuel sous "Discussion" .

wisbucky
la source
5

Pour voir tous les fichiers dans la cachette (à la fois suivis et non suivis), j'ai ajouté cet alias à ma configuration:

showstash = "!if test -z $1; then set -- 0; fi; git show --stat stash@{$1} && git show --stat stash@{$1}^3 2>/dev/null || echo No untracked files -"

Il ne prend qu'un seul argument dont vous souhaitez afficher la réserve. Notez qu'il le présentera toujours dans deux listes consécutives.

La if...fisection change l'argument bash $ 1 en 0 si aucun n'a été passé.

Randall
la source
5

Une solution de contournement: la mise en attente des fichiers avant de les cacher git stash show -pfonctionnera comme prévu.

git add .
git stash save

Remarque: De cette façon, vous pouvez également ajouter des portions interactives, voici comment .
Attention: assurez-vous que vous n'avez pas de travail mis en scène auparavant, sinon vous ne pourrez pas le distinguer.
Cela peut être utile.

weshouman
la source