No git, existe uma maneira de mostrar arquivos ocultos não rastreados sem aplicar o estoque?

100

Se eu correr git stash -u, posso esconder arquivos não rastreados. No entanto, esses arquivos não rastreados não aparecem com git stash show stash@{0}. Existe alguma maneira de mostrar arquivos ocultos não rastreados sem aplicar o estoque?

Max Nanasy
fonte

Respostas:

121

Arquivos não rastreados são armazenados no terceiro pai de um commit stash. (Isso não está realmente documentado, mas é bastante óbvio pelo commit que introduziu o recurso -u, 787513 ... , e a forma como o resto da documentação paragit-stash coisas de frases ... ou apenas fazendo git log --graph stash@{0})

Você pode ver apenas a parte "não rastreada" do estoque via:

git show stash@{0}^3

ou, apenas a própria árvore "não rastreada", via:

git show stash@{0}^3:

ou um determinado arquivo "não rastreado" na árvore, por meio de:

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

Infelizmente, não existe uma boa maneira de obter um resumo das diferenças entre todos os estados encenado + não-encenado + não-controlado vs "atual". ie: git show stash@{0}não pode ser feito para incluir os arquivos não rastreados. Isso ocorre porque o objeto de árvore do próprio commit stash, referido como stash@{0}:, não inclui nenhuma mudança do terceiro pai "não testado".

Isso se deve ao modo como os stashes são reaplicados: arquivos rastreados podem ser facilmente aplicados como patches, enquanto arquivos não rastreados podem ser aplicados, em teoria, como "arquivos inteiros".

Will Palmer
fonte
Então os pais do commit do stash são (1. O stash do commit é feito contra 2. Índice 3. Cópia de trabalho não rastreada), e o commit do stash em si contém a cópia de trabalho rastreada? git stash showparece mostrar a diferença entre a cópia de trabalho e # 1 (código relevante de git-stash.sh:, git diff ${FLAGS:---stat} $b_commit $w_commitno qual $ b_commit é # 1 e $ w_commit é o commit stash); existe alguma maneira embutida de git stash showincluir também o nº 3?
Max Nanasy 01 de
Como você disse, eu não encontrei uma maneira de obter uma visão única resumo de um stash, mas você pode ver a sua informação completa em um comando com: git log --graph --topo-order -m -u. matthewlmcclure.com/s/2014/01/10/…
Matt McClure
4
Observe que você obterá um erro feio ( fatal: ambiguous argument 'stash@{0}^3': unknown revision or path not in the working tree.) se na verdade não tiver arquivos não rastreados naquele esconderijo (mas pensei que sim).
Randall
2
@antak: Não, git stash shownão não mostrar os arquivos untracked (true por pelo menos git 2.7.4):
Norbert BERCI
1
Nota (2.13.2-linux): git stash poptentará primeiro restaurar arquivos não rastreados e, em seguida, tentará restaurar arquivos rastreados. Se a última operação falhar (por exemplo, conflito), a primeira operação não será revertida (arquivo não rastreado permanecerá como está, mas os arquivos não serão removidos do disco), então, mesmo se você corrigir o conflito, o próximo pop falhará de qualquer forma.
Marinos em
22

Você pode listar todos os commits de stash com o seguinte comando:

git rev-list -g stash

Como os stashes são representados como um commit de mesclagem de 3 vias de HEAD, o índice e um commit "raiz" sem pai de arquivos não rastreados, os stashes de arquivos não rastreados podem ser listados canalizando a saída acima para o seguinte:

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

Aplicações úteis dos itens acima:

Mostrar apenas arquivos não rastreados e armazenados

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

Claro, remova o --statpara ver o conteúdo dos arquivos.

Encontre um arquivo específico

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

Arquivos não rastreados Grep

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

Liste todo o conteúdo de todos os stashes

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

Para listar os arquivos não rastreados no stash:

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

Para mostrar uma comparação completa de todos os arquivos não rastreados (com conteúdo):

git show stash@{0}^3

Esses comandos lêem o último (mais recente) stash. Para stashes anteriores, aumente o número atrás do "stash @", por exemplo, stash@{2}para o segundo do último stash.

O motivo pelo qual isso funciona é que git stashcria um commit de mesclagem para cada stash, que pode ser referenciado como stash@{0}, stash@{1}etc. O primeiro pai desse commit é o HEAD no momento do stash, o segundo pai contém as mudanças nos arquivos rastreados, e o terceiro (que pode não existir) as alterações em arquivos não rastreados.

Isso é parcialmente explicado na página de manual em "Discussão" .

wisbucky
fonte
5

Para ver todos os arquivos no stash (rastreados e não rastreados), adicionei este alias à minha configuração:

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

Leva um único argumento de qual stash você deseja visualizar. Observe que ele ainda o apresentará em duas listas consecutivas.

A if...fiseção muda o argumento bash $ 1 para 0 se nenhum foi passado.

Randall
fonte
5

Uma solução alternativa: preparar os arquivos antes de armazená-los git stash show -pfuncionará conforme o esperado.

git add .
git stash save

Nota: Esta forma dá o poder de adicionar partes interativas também, aqui está como .
Cuidado: certifique-se de não ter um trabalho encenado anteriormente, ou você não será capaz de distingui-lo.
Isso pode ser útil.

weshouman
fonte