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?

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


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

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


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.


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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.