O git stash é específico para o branch ou para todo o repositório?

97

Entrei em uma filial e fiz alguns trabalhos. Eu queria ir para outro branch, mas não queria me comprometer, então eu fiz git stash. Então eu fiz git checkout <otherbranch>. Fiz alguns trabalhos lá e, assim como no primeiro branch, queria sair dele antes de comprometer o trabalho. Então eu fiz git stashlá também. Voltei para o primeiro branch e tentei removê-lo ( git stash pop) pensando que ele iria obter o stash daquele branch específico. Fiquei surpreso com o fato de que ele removeu o estoque de <otherbranch>(mais recente). Fiquei com a impressão de que o stash é específico do branch, mas esse comportamento indica que há apenas um stash para todo o repositório local.

É git stashespecífico do ramo ou para todo o repositório? Se for para todo o repositório, posso passar opções para torná-lo específico para o branch?

anfibiente
fonte

Respostas:

43

Para ver a pilha atual do estoque:

git stash list

Para escolher um estoque específico da pilha, consulte-o pelo mostrado acima.stash@{number}

Se você quiser que o comportamento seja por branch, você pode apenas fazer um commit (ou vários commits) no branch. Você sempre pode "desfazer" o (s) commit (s) mais tarde (por exemplo, com git reset, --softou --mixed; consulte a documentação de redefinição do git ; ou comgit rebase -i para manter apenas os eventuais commit (s) "reais" enquanto descarta os temporários).

(Para realmente emular git stashvocê precisa de pelo menos dois commits, um para o estado do índice e um para o estado da árvore de trabalho. Se você não está planejando salvar e restaurar o estado do índice, entretanto, você pode apenas git add -Atodo o estado da árvore de trabalho e colocá-lo no commit temporário. Alternativamente, git stashé um script de shell para que você possa copiá-lo e modificá-lo facilmente para fazê-lo funcionar por ramo por padrão, usando, por exemplo, como seu espaço de nomes de trabalho, ao invés do único global para todo o repo. Você ainda seria capaz de trazer um stash de um branch para outro, nomeando-o explicitamente.)refs/pb-stash/branchrefs/stash

Torek
fonte
você sabe como exibir a lista de arquivos de cada stash listitem além de apenas uma descrição?
anfibiente
2
git stash show(ou git stash show stash@{<number>}para algo diferente da @{0}versão) dá a você um diff --stat; adicione -ppara obter uma diferença maior. Nota: isso compara a "árvore de trabalho" na "bolsa de armazenamento" com o commit de onde ela está pendurada; não há interface de front-end para ver o que está no "índice" no pacote de armazenamento fornecido.
Torek
56

Não e Não. Git stash é por repositório.

Aqui está uma boa página sobre como usá-lo.

Abasterfield
fonte
o segundo estoque sobrescreve o primeiro? IOW, se eu fizer dois stashes, mas nenhum no meio, eu perco o primeiro stash?
anfibiente
1
Não, você recebe uma pilha (último a entrar, primeiro a sair) de stashes. Você empurra um estoque para o seu estoque, depois outro e depois o segundo e depois o primeiro, etc.
abasterfield
18

git stash não é por ramo.

  • Em vez de git stash(que pode ser perdido facilmente quando você tem muitos esconderijos e branches)
  • Eu sugiro fazer um git commitpara salvar o código inacabado em seu branch e quando você estiver pronto para terminar o código faça um git reset ${COMMIT_HASH_VALUE}para obter o código inacabado de volta
  • git commite git resetquando usados juntos corretamente podem simular um git stashpara um ramo específico

Aqui está um cenário comum da vida real que demonstra o valor e o uso dos comandos commite reset:

  • você está trabalhando no branch de recurso X e seu código nem mesmo compila ou passa nos testes
  • há um bug que tem maior prioridade do que o novo recurso atual e você deve começar a trabalhar imediatamente na correção do bug
  • ao invés de fazer um git stash (e o stash se perde na mistura porque você tem muitos stashes e muitos branches)
  • você pode fazer um git commitbranch X no recurso
    • escreva COMMIT_HASH_VALUEpara mais tarde
  • verifique um novo branch Y para o hot fix
  • termine o hot fix no branch Y (faça uma solicitação de mesclagem para obter o hot fix na linha de base e exclua o branch do hot fix)
  • em seguida, verifique o branch de recursos X novamente
  • para exibir seu trabalho inacabado que não compilou ou passou no teste -> apenas faça um git reset ${COMMIT_HASH_VALUE}

(Para sua informação, o padrão git reseté --mixed)

Trevor Boyd Smith
fonte
2
Um atalho útil para redefinir neste cenário é git reset HEAD~1.
Sam A. Horvath-Hunt
1
@samHH Já tive muitas instâncias com git reset HEAD ^ 1 acidentalmente sendo atingido duas vezes ... então escolhi não usar HEAD^1ou HEAD~1.
Trevor Boyd Smith,
12

Não tenho certeza de por que todas as respostas aqui sugerem emular o estoque com commit+ reset. O Stash é perfeitamente adequado para uso, especialmente ao trabalhar em vários ramos. Eu também não quero fazer commit quando trabalho em vários branches, porque quero que todas as mudanças modificadas ainda estejam destacadas no meu editor quando eu retornar.

Então, aqui está o fluxo de trabalho do stash:

Sempre que você tiver que trocar de branch e não estiver pronto para submeter, salve suas alterações na pilha

git stash save "Your custom stash message"

Quando você retornar a uma filial, verifique o estoque

git stash list

insira a descrição da imagem aqui

Se você estiver no ramo, FixIssue0203você poderia usar git stash popporque isso aplicará o topostash@{0} e o removerá do stash.

No entanto, se você estiver no ramo, ImproveReadmevocê deve primeiro aplicar o estoque 1 git stash apply stash@{1}e depois remover o estoque 1 da pilha git stash drop stash@{1}.

É isso aí!

Adão
fonte