En git, ¿hay alguna forma de mostrar archivos ocultos sin seguimiento sin aplicar el alijo?

100

Si corro git stash -u, puedo guardar archivos sin seguimiento. Sin embargo, dichos archivos sin seguimiento no aparecen en absoluto con git stash show stash@{0}. ¿Hay alguna forma de mostrar archivos ocultos sin seguimiento sin aplicar el alijo?

Max Nanasy
fuente

Respuestas:

121

Los archivos sin seguimiento se almacenan en el tercer padre de una confirmación oculta. (Esto en realidad no está documentado, pero es bastante obvio a partir de The commit que introdujo la función -u, 787513 ... , y la forma en que el resto de la documentación paragit-stash frases cosas ... o simplemente haciendo git log --graph stash@{0})

Puede ver solo la parte "sin seguimiento" del alijo a través de:

git show stash@{0}^3

o, solo el árbol "sin seguimiento" en sí, a través de:

git show stash@{0}^3:

o un archivo "sin seguimiento" en particular en el árbol, a través de:

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

Desafortunadamente, no existe una buena manera de obtener un resumen de las diferencias entre todos los estados por etapas + sin etapas + sin seguimiento y el estado "actual". es decir: git show stash@{0}no se puede hacer para incluir los archivos sin seguimiento. Esto se debe a que el objeto de árbol de la confirmación de alijo en sí mismo, al que se stash@{0}:hace referencia como , no incluye ningún cambio del tercer padre "sin etapas".

Esto se debe a la forma en que se vuelven a aplicar los alijos: los archivos con seguimiento se pueden aplicar fácilmente como parches, mientras que los archivos sin seguimiento solo se pueden aplicar, en teoría, como "archivos completos".

Will Palmer
fuente
Entonces, los padres de la confirmación de alijo son (1. El alijo de confirmación se realiza contra 2. Índice 3. Copia de trabajo sin seguimiento), y ¿la confirmación de alijo contiene la copia de trabajo con seguimiento? git stash showparece mostrar la diferencia entre la copia de trabajo y el # 1 (código relevante de git-stash.sh : git diff ${FLAGS:---stat} $b_commit $w_commit, en el que $ b_commit es el # 1 y $ w_commit es el compromiso de alijo); ¿Hay alguna forma incorporada para git stash showincluir también el n. ° 3?
Max Nanasy
Como usted dice, no he encontrado una manera de obtener una visión única resumen de un escondite, pero se puede ver su información completa con sólo una orden: git log --graph --topo-order -m -u. matthewlmcclure.com/s/2014/01/10/…
Matt McClure
4
Tenga en cuenta que obtiene un error feo ( fatal: ambiguous argument 'stash@{0}^3': unknown revision or path not in the working tree.) si en realidad no tiene archivos sin seguimiento en ese alijo (pero pensó que sí).
Randall
2
@antak: git stash showno , no muestra los archivos sin seguimiento (verdadero para al menos git 2.7.4):
Norbert Bérci
1
Nota (2.13.2-linux): git stash popprimero intentará restaurar los archivos no rastreados, luego intentará restaurar los archivos rastreados. Si la última operación falla (por ejemplo, un conflicto), la primera operación no se revierte (el almacenamiento de archivos sin seguimiento permanecerá como está, pero los archivos no se eliminarán del disco), por lo que incluso si soluciona el conflicto, la siguiente ventana emergente fallará. de todas formas.
Marinos An
22

Puede enumerar todas las confirmaciones ocultas con el siguiente comando:

git rev-list -g stash

Dado que las reservas se representan como una combinación de confirmación de 3 vías de HEAD, el índice y una confirmación "raíz" sin padres de archivos sin seguimiento, las reservas de archivos sin seguimiento se pueden enumerar canalizando la salida anterior a lo siguiente:

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

Aplicaciones útiles de lo anterior:

Mostrar solo archivos ocultos sin seguimiento

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

Por supuesto, elimine el --statpara ver el contenido de los archivos.

Encuentra un archivo específico

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

Archivos sin seguimiento de grep

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

Enumere todo el contenido de todos los alijos

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

Para enumerar los archivos sin seguimiento en el alijo:

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

Para mostrar una diferencia completa de todos los archivos sin seguimiento (con contenido):

git show stash@{0}^3

Estos comandos leen el último (más reciente) alijo. Para alijos anteriores, incremente el número detrás del "alijo @", por ejemplo, stash@{2}para el segundo desde el último alijo.

La razón por la que esto funciona es que git stashcrea una confirmación de fusión para cada alijo, a la que se puede hacer referencia como stash@{0}, stash@{1}etc. El primer padre de esta confirmación es el HEAD en el momento del alijo, el segundo padre contiene los cambios en los archivos rastreados y el tercero (que puede no existir) los cambios en los archivos sin seguimiento.

Esto se explica en parte en la página de manual en "Discusión" .

Wisbucky
fuente
5

Para ver todos los archivos en el alijo (tanto con seguimiento como sin seguimiento), agregué este alias a mi configuración:

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 -"

Se necesita un solo argumento del alijo que desea ver. Tenga en cuenta que todavía lo presentará en dos listas consecutivas.

La if...fisección cambia el argumento de bash $ 1 a 0 si no se pasó ninguno.

Randall
fuente
5

Una solución alternativa: organizar los archivos antes de guardarlos hará que git stash show -pfuncione como se esperaba.

git add .
git stash save

Nota: De esta manera también se da el poder de agregar partes interactivas, así es como se hace .
Precaución: asegúrese de no tener un trabajo preparado previamente, o no podrá distinguirlo.
Esto puede ser de utilidad.

Weshouman
fuente