Git diff contra um stash

1359

Como posso ver as alterações que a remoção do stashing fará na árvore de trabalho atual? Gostaria de saber quais alterações serão feitas antes de aplicá-las!

James
fonte
12
possível duplicação de É possível visualizar o aplicativo stash no git?
quazgar
1
Post relacionado aqui .
RBT 25/09

Respostas:

1872

Veja o esconderijo mais recente:

git stash show -p

Veja um esconderijo arbitrário:

git stash show -p stash@{1}

Das git stashpáginas de manual:

Por padrão, o comando mostra o diffstat, mas aceita qualquer formato conhecido pelo git diff (por exemplo, git stash show -p stash @ {1} para exibir o segundo stash mais recente no formato de patch).

Âmbar
fonte
72
stash@{0}é o padrão; você só precisa de um argumento se quiser examinar os stashes anteriores.
Cascabel
52
Direita. Eu apenas o forneci para que ficasse claro como olhar para outros esconderijos {0}.
22611 Amber
74
Isso não mostrará a diferença entre o stash e o diretório de trabalho atual, mas entre o stash e seu pai original. Direita? Na página de manual: "Mostre as alterações registradas no stash como uma diferença entre o estado stashed e seu pai original".
Magne
14
@ Amber - Verdade, embora se sua árvore de trabalho atual estiver suja, isso importa e a torna um pouco mais complicada. Cheguei a esse ponto e encontrei um procedimento que compartilhei na minha resposta abaixo.
Magne
6
o que -psignifica?
Gerald
308

Para ver o esconderijo mais recente:

git stash show -p

Para ver um estoque arbitrário:

git stash show -p stash@{1}

Além disso, eu uso o git diff para comparar o esconderijo com qualquer ramo.

Você pode usar:

git diff stash@{0} master

Ver todas as alterações comparadas ao mestre da filial.


Ou você pode usar:

git diff --name-only stash@{0} master

Para encontrar facilmente apenas nomes de arquivos alterados.

czerasz
fonte
10
Isso não responde à pergunta específica. Se você criou o stash a partir do mestre (para salvar o trabalho para mais tarde), faça algumas confirmações para outro trabalho no mestre e, em seguida git diff stash@{0} master, obtenha um diff do seu stash em relação ao mestre atual (que inclui o trabalho realizado no mestre após o stash foi feita), não os arquivos / linhas que o stash alteraria, e é disso que se trata a questão.
Tom De Leu
52
Ainda bem que você respondeu à pergunta, mesmo que não fosse uma resposta exata. Ele forneceu mais informações e acho ótimo saber como obter uma diferença entre um ramo e qualquer outro ramo com o qual você queira comparar. Eu também gostava de aprender o sinalizador só de --name :)
Rebekah Waterbury
6
isso também permite observar as diferenças usando um visualizador de diferenças personalizado, por exemplogit difftool --tool=... stash@{0} HEAD
Andre Holzner
9
@TomDeLeu Boa observação e um ponto importante. Para comparar um item de estoque com seu pai, isso parece funcionar:git diff stash@{0}^ stash@{0}
erikprice
1
Além disso, você pode adicionar o nome do arquivo git diff stash@{0} master -- filenamepara obter as alterações em um arquivo específico.
David
104

Se o ramo em que as alterações armazenadas em cache são baseadas foi alterado, esse comando pode ser útil:

git diff stash@{0}^!

Isso compara o stash com o commit em que ele se baseia.

t.heintz
fonte
tão bom que eu adicionado um alias para ~/.gitconfig:laststash = diff stash@{0}^!
sbeam
5
Par perfeito: git difftool stash^!para diff do último esconderijo contra a comprometer-se com base em, git difftool stash HEADpor diff do último esconderijo contra a corrente commit (esconderijo @ {n} para esconderijos anteriores)
ChrisV
17
Para aqueles que eram como eu e nunca viram o ^! antes: commit ^! é um especificador de intervalo que significa: esse commit, mas nenhum de seus pais.
Jonathan Gawrych 03/02
"git diff stash @ {0} ^!" resume-se a "git diff stash @ {0} ^ stash @ {0} ~ 1 ^ stash @ {0} ~ 2 .......", mas como o git diff leva apenas 2 commits, mostra o diff entre stash @ {0} e ^ stash @ {0} ~ 1 e parece que o ^ no início do 2º commit não faz diferença e o git o ignora.
Naga Kiran
Prefiro que esta versão seja capaz de usar minha ferramenta diff preferida (além da comparação, é claro!). Isso também mostra a mudança nesse stash, que acredito ser a pergunta original, em oposição a uma alternativa mencionada nos comentários acima "git diff stash @ {X} ^ stash @ {X}", que mostra mais do que apenas o diff armazenado.
user107172
44

Se a sua árvore de trabalho estiver suja , você poderá compará-la com um stash confirmando primeiro a árvore de trabalho suja e comparando-a com o stash. Posteriormente, você pode desfazer o commit com a árvore de trabalho suja (já que você pode não querer ter esse commit sujo no log de confirmação).

Você também pode usar a abordagem a seguir para comparar dois stashes um com o outro (nesse caso, basta colocar um dos stashes primeiro).

  • Confirme sua árvore de trabalho suja:

    git add .
    git commit -m "Dirty commit"
    
  • Diff o stash com esse commit:

    git diff HEAD stash@{0}
    
  • Depois, você pode reverter o commit e colocá-lo novamente no diretório de trabalho:

    git reset --soft HEAD~1
    git reset .
    

Agora você diferenciou a árvore de trabalho suja com seu estoque e voltou para onde estava inicialmente.

Magne
fonte
Existe uma maneira de fazer isso, mas apenas ver um diff dos arquivos que seriam alterados pelo que está no esconderijo?
lagweezle # 03
Em 2020, isso é muito mais simples; confira minha resposta atualizada .
David Deprost
Interessante, eu não sabia git stash show -l . Difere o último esconderijo contra a cópia de trabalho (suja)? Como você o usa sem obter error: switch l requires a value?
Magne
Sim, de fato, ele difere da cópia de trabalho (possivelmente suja). Você o usa simplesmente inserindo git stash show -l. Quanto ao motivo pelo qual isso não funciona para você, só posso supor que você esteja em uma versão mais antiga do git? Estou no git v2.20.1 e funciona perfeitamente, sem erros.
David Deprost
25

A resposta de @ Magne é a única data (muito tarde) que responde à interpretação mais flexível / útil da pergunta, mas é um pouco mais complicada do que o necessário. Em vez de confirmar e redefinir, apenas armazene sua cópia de trabalho, compare e desinstale.

git stash save "temp"
git diff stash@{0} stash@{1}
git stash pop

Isso mostra as diferenças entre a parte superior da pilha stash e sua pasta de trabalho, transformando temporariamente as alterações da pasta de trabalho na parte superior da pilha stash (stash @ {0}), movendo a parte superior original para baixo (stash @ {1} ), comparando usando a parte superior original na posição 'novo conjunto' para ver as alterações que resultariam da aplicação na parte superior do seu trabalho atual.

"Mas e se eu não tiver nenhum trabalho atual?" Então você está no caso chato normal. Basta usar a resposta de @ Amber

git stash show

ou a resposta de @ czerasz

git diff stash@{0}

ou admitir que esconder e desmascarar é rápido e fácil de qualquer maneira, basta descartar as alterações e inspecioná-las. Se você não os quiser no momento, jogue-os fora (o índice atual / pasta de trabalho muda). Na íntegra isso é

git stash apply
git diff
git reset
git checkout
SensorSmith
fonte
3
Essa abordagem simples (esconder e comparar com outra) é segura e fácil de entender. Para alguns casos de uso, você também pode git stash save -u
ocultar
19

Isso funciona para mim no git versão 1.8.5.2:

git diff stash HEAD
Rimian
fonte
2
Enganador! A pergunta é: como posso ver as alterações que a remoção do stashing fará na árvore de trabalho atual? Isso mostra a diferença entre o stash e o HEAD, que pode ser MUITO diferente do que será aplicado git stash apply.
11136 MikeJansen
Por favor, leia mais sobre a questão "Gostaria de saber quais alterações serão feitas antes de aplicá-las!". Estou fornecendo uma resposta rápida para isso.
yerlilbilgin
Além disso, você pode ver que todas as outras respostas são de alguma forma relacionadas à diferença do cabeçote atual (ou conjunto de trabalho) contra o esconderijo. Por que apenas minha resposta é enganosa? Isso não é justo.
yerlilbilgin
@yerlilbilgin Veja minha resposta na sua resposta abaixo.
21716 MikeJansen
Podemos omitir HEAD, é por padrão, não é?
Al.G.
10

Por precaução, para comparar um arquivo na árvore de trabalho e no stash, use o comando abaixo

git diff stash@{0} -- fileName (with path)
Pramod BR
fonte
9

Se você possui ferramentas para diff (como além da comparação)

git difftool stash HEAD
yerlilbilgin
fonte
1
Enganador! A pergunta é: como posso ver as alterações que a remoção do stashing fará na árvore de trabalho atual? Isso mostra a diferença entre o stash e o HEAD, que pode ser MUITO diferente do que será aplicado git stash apply.
11136 MikeJansen
1
Se você acha que isso é enganoso, verifique todas as outras respostas. Isso não é justo!
23616 Yerlilbilgin
1
Você notará que copiei o mesmo comentário para a outra resposta, que era igualmente enganosa (praticamente a mesma resposta). Outras respostas que já tiveram um comentário semelhante, deixei em paz. Se você entender como o git stash funciona, você perceberá que não é a aplicação do stash contra o HEAD (que é o que o OP pede). O "stash" real é a diferença entre o commit do stash e o que havia antes dele. Este patch é aplicado ao HEAD. Portanto, se você quiser saber o que o OP pediu, você deve mostrar a diferença entre o stash e o commit antes dele, o que as respostas corretas fazem.
23416 MikeJansen
1
Isso responde à pergunta mais diretamente do que qualquer outra (desnecessariamente) resposta longa e faz exatamente o que o OP pediu, sem ser removido HEAD. Eu poderia modificar a resposta de @erlilbilgin para remover o HEAD, mas acho que qualquer pessoa que use o git pode descobrir essa parte e me prolongar a resposta tornaria menos legível. Não há culpa em @yerlibilgin.
Sridhar Sarnobat
4

Uma maneira de fazer isso sem mover nada é tirar vantagem do fato de que você patchpode ler os git diffs (diffs unificados basicamente)

git stash show -p | patch -p1 --verbose --dry-run

Isso mostrará uma visualização passo a passo do que o patch normalmente faria. O benefício adicional disso é que o patch também não impedirá a gravação do patch na árvore de trabalho. Se, por algum motivo, você realmente precisar do git para calar a boca sobre cometer antes da modificação, vá em frente e remova --dry- execute e siga as instruções detalhadas.

xenithorb
fonte
2

Combinando o que aprendi neste tópico e neste , quando quero ver "o que há dentro do esconderijo", primeiro executo:

git stash show stash@{0}

Isso mostrará quais arquivos foram modificados. Então, para obter um bom visual diff em um difftool, eu faço:

git difftool --dir-diff stash@{0} stash@{0}^

Isso exibirá todas as diferenças de uma vez do estoque fornecido contra seu pai.

Você pode configurar a ferramenta diff ~/.gitconfig, por exemplo, com Meld :

...
[diff]
    tool = meld
Ferrard
fonte
1

FWIW Isso pode ser um pouco redundante para todas as outras respostas e é muito semelhante à resposta aceita no local; mas talvez ajude alguém.

git stash show --helplhe dará tudo que você precisa; incluindo informações sobre o show stash.

mostre [<stash>]

Mostre as alterações registradas no stash como uma diferença entre o estado stashed e seu pai original. Quando não é dado, mostra o mais recente. Por padrão, o comando mostra o diffstat, mas aceita qualquer formato conhecido pelo git diff (por exemplo, git stash show -p stash @ {1} para exibir o segundo stash mais recente no formato de patch). Você pode usar as variáveis ​​de configuração stash.showStat e / ou stash.showPatch para alterar o comportamento padrão.

Rockin4Life33
fonte
1

Ela a lista de esconderijo

git stash list 
stash@{0}: WIP on feature/blabla: 830335224fa Name Commit
stash@{1}: WIP on feature/blabla2: 830335224fa Name Commit 2

Portanto, obtenha o número do stash e faça:

Você pode fazer:

 git stash show -p stash@{1}

Mas se você quiser um diff (isso é diferente para mostrar o stash, é por isso que escrevo esta resposta. DiffConsidere o código atual em seu ramo e showapenas mostre o que você aplicará )

Você pode usar:

git diff stash@{0}

ou

git diff stash@{0} <branch name>

Outra coisa interessante a fazer é:

git stash apply
git stash apply stash@{10}

Isso aplica o stash sem removê-lo da lista, você pode git checkout .remover essas alterações ou, se estiver feliz git stash drop stash@{10}em remover um stash da lista.

A partir daqui, nunca recomendo usar git stash pope usar uma combinação de git stash applye git stash dropSe você aplicar um esconderijo no ramo errado ... bem, às vezes é difícil recuperar seu código.

Raúl Martín
fonte
1

Dependendo do que você deseja comparar o stash (árvore de trabalho local / commit pai / head commit), na verdade existem vários comandos disponíveis, entre os quais o bom git diffe o mais específico git stash show:

╔══════════════════════╦═══════════════════════════════╦═══════════════════╗
║ Compare stash with ↓ ║ git diff                      ║ git stash show    ║
╠══════════════════════╬═══════════════════════════════╬═══════════════════╣
║ Local working tree   ║ git diff stash@{0}            ║ git stash show -l ║
║----------------------║-------------------------------║-------------------║
║ Parent commit        ║ git diff stash@{0}^ stash@{0} ║ git stash show -p ║
║----------------------║-------------------------------║-------------------║
║ HEAD commit          ║ git diff stash@{0} HEAD       ║   /               ║
╚══════════════════════╩═══════════════════════════════╩═══════════════════╝

Embora git stash showpareça mais amigável à primeira vista, git diffé realmente mais poderoso, pois permite especificar nomes de arquivos para uma comparação mais focada. Pessoalmente, configurei aliases para todos esses comandos no meu plugin zsh git .

David Deprost
fonte