Qual é o caso de uso pretendido para git stash?

142

Se eu trabalho no branch A e de repente preciso trabalhar no branch B antes de estar pronto com um commit no branch A, eu escondo minhas mudanças em A, checkout B, faço meu trabalho lá, então registro A e aplico o stash.

Se eu trabalhar em A e quiser parar de trabalhar durante o dia, devo esconder meu trabalho e aplicá-lo no dia seguinte (quando eu retomar meu trabalho), ou devo apenas deixar as coisas como estão - arquivos modificados não confirmados no diretório de trabalho? Não vejo por que eu precisaria usar o stash neste caso, exceto se houver algum benefício de segurança.

Além disso, outro cenário: eu trabalho tanto no trabalho quanto em casa. Se eu não estiver pronto com um commit quando quiser ir para casa, posso esconder meu trabalho, enviá-lo para o GitHub e depois puxar para casa?

Alexandre
fonte
3
amplamente dependente das políticas da sua empresa, se houver. Como você escolherá a resposta "aceita"?
Daemon Painter
1
Esta questão, conforme formulada, é apenas pedir opiniões (devo usar o git desta ou daquela forma?) E, portanto, deve ser fechada ou editada.
TylerH 01 de

Respostas:

161

Stash é apenas um método de conveniência. Já que branches são tão baratos e fáceis de gerenciar no git, eu pessoalmente quase sempre prefiro criar um novo branch temporário do que stash, mas é principalmente uma questão de gosto.

O único lugar que eu gosto de esconder é se eu descobrir que esqueci algo em meu último commit e já comecei a trabalhar no próximo no mesmo branch:

# Assume the latest commit was already done
# start working on the next patch, and discovered I was missing something

# stash away the current mess I made
git stash save

# some changes in the working dir

# and now add them to the last commit:
git add -u
git commit --amend

# back to work!
git stash pop
Mureinik
fonte
2
Aquilo que você adicionou que estava faltando é mesclado com o stash assim que você remove o stash? (Ainda estou inseguro sobre como a linha do tempo funciona no git - presumo que você esteja sobrescrevendo o histórico ??)
Kiki Jewell
As alterações pop-up de @KikiJewell são aplicadas ao índice - elas não são confirmadas. então, se você fizer git stash popduas vezes, perderá a distinção entre esses dois conjuntos de mudanças.
Mureinik
No final de outubro de 2017, houve uma ampla discussão na lista de e-mails do Git, em que o comando git stash save está sendo preterido em favor da alternativa existente git stash push. A principal razão para isso é que git stash pushintroduz a opção de esconder pathspecs selecionados , algo git stash savenão compatível.
Krishna Gupta
39

Vou quebrar a resposta em três parágrafos.

Parte 1:

git stash(Para salvar suas alterações não confirmadas em um "esconderijo". Observação: isso remove as alterações da árvore de trabalho!)

git checkout some_branch(mude para o ramo pretendido - neste caso some_branch)

git stash list (lista stashes)

Você pode ver:
stash @ {0}: WIP em {branch_name}: {SHA-1 do último commit} {último commit de seu branch}
stash @ {0}: WIP no mestre: modificação 085b095c6 para teste

git stash apply (para aplicar o estoque à árvore de trabalho no ramo atual)

git stash apply stash@{12}(se você tiver muitos esconderijos, você pode escolher o que será aplicado - neste caso, aplicamos o estoque 12)

git stash drop stash@{0}(para remover da lista de estoque - neste caso, estoque 0)

git stash pop stash@{1} (para aplicar o estoque selecionado e retirá-lo da lista de estoque)

Parte 2:
Você pode ocultar suas alterações com este comando, mas não é necessário.
Você pode continuar no dia seguinte sem esconder.
Este comandos para esconder suas mudanças e trabalhar em diferentes branches ou para implementação alguma realização de seu código e salvar em stashes sem branches e commits ou seu caso personalizado!
E depois você pode usar alguns dos stashes e verificar qual é o melhor.

Parte 3:
Comando Stash para local ocultar suas alterações.
Se você quiser trabalhar remotamente, deve confirmar e enviar.

Alexander Yushko
fonte
10

A ideia principal é

Guarde as mudanças em um diretório de trabalho sujo

Portanto, o comando Basicallly Stash mantém suas algumas alterações que você não precisa ou deseja no momento; mas você pode precisar deles.

Use git stash quando quiser registrar o estado atual do diretório de trabalho e do índice, mas quiser voltar para um diretório de trabalho limpo. O comando salva suas modificações locais e reverte o diretório de trabalho para corresponder ao commit HEAD .

nzrytmn
fonte
7

Você pode usar os seguintes comandos:

  • Para salvar suas alterações não confirmadas

    git stash

  • Para listar seus estoques salvos

    git stash list

  • Para aplicar / recuperar as alterações não confirmadas onde x é 0,1,2 ...

    git stash apply stash@{x}

Nota:

  • Para aplicar um estoque e removê-lo da lista de estoque

    git stash pop stash@{x}

  • Para aplicar um stash e mantê-lo na lista de stash

    git stash apply stash@{x}

Anushil Kumar
fonte
4

Se você acertar git stashquando tiver mudanças na cópia de trabalho (não na área de teste), o git criará um objeto escondido e o empurrará para a pilha de esconderijos (exatamente como você fez, git checkout -- .mas você não perderá as alterações). Mais tarde, você pode saltar do topo da pilha.

Gyorgyabraham
fonte
2

O comando stash irá esconder todas as mudanças que você fez desde seu último commit. No seu caso, não há motivo para esconder se você vai continuar trabalhando nisso no dia seguinte. Eu só usaria o stash para desfazer as alterações que você não deseja confirmar.

Severin
fonte
2
Não, git stashnão vai mudar o seu ramo. Em especial, ele não "reverterá" quaisquer alterações confirmadas. Ele irá apenas (temporariamente) descartar quaisquer alterações não confirmadas em seus arquivos. - Pode parecer exigente, mas esse tipo de palavra tem um significado muito especial no contexto do git. Você realmente não deve misturar isso.
michas
Obrigado por apontar isso. Eu mudei minha resposta de acordo.
Severin
No git, um "branch" é definido como uma série de commits. git stashnão afetará nenhum commit e, portanto, não modificará nenhum branch. Ele não "removerá" nada de um branch e não o "redefinirá" de forma alguma. A ramificação permanece a mesma, apenas os arquivos na árvore de trabalho mudam. - Essas são duas coisas totalmente diferentes.
michas
Ele não vai descartar, mas "esconder" suas alterações! Git mantém uma estrutura LIFO para stashes, então um stash é na verdade um push e você pode estourar de cima dele. A palavra "descartar" significa que você perderá qualquer coisa, mas não.
gyorgyabraham
1

Sei que StackOverflow não é o lugar para respostas baseadas em opinião, mas na verdade tenho uma boa opinião sobre quando arquivar alterações com um estoque.

Você não quer comprometer suas alterações experimentais

Quando você faz mudanças em sua área de trabalho / árvore de trabalho, se você precisa realizar qualquer operação baseada em ramificação, como mesclar, enviar, buscar ou puxar, você deve estar em um ponto de confirmação limpo. Portanto, se você tiver alterações no espaço de trabalho, precisará confirmá-las. Mas e se você não quiser cometê-los? E se eles forem experimentais? Algo que você não quer fazer parte do seu histórico de commits? Algo que você não quer que outras pessoas vejam ao enviar para o GitHub?

Você não quer perder as alterações locais com um hard reset

Nesse caso, você pode fazer uma reinicialização a frio. Mas se você fizer uma reinicialização a frio, você perderá todas as alterações da árvore de trabalho local porque tudo será sobrescrito para onde estava no momento do último commit e você perderá todas as suas alterações.

Então, quanto à resposta de 'quando você deve esconder', a resposta é quando você precisa voltar a um ponto de confirmação limpo com uma árvore / índice / confirmação sincronizada, mas você não quer perder suas mudanças locais em o processo. Apenas arquive suas mudanças em um estoque e você estará bem.

E uma vez que você tenha feito seu stash e então mesclado ou puxado ou empurrado, você pode apenas stash pop ou aplicar e você está de volta ao ponto de partida.

Git stash e GitHub

O GitHub está constantemente adicionando novos recursos, mas a partir de agora, agora há uma maneira de salvar um estoque lá. Novamente, a ideia de um esconderijo é que seja local e privado. Ninguém mais pode espiar seu estoque sem acesso físico à estação de trabalho. Da mesma forma que o git reflog é privado e o git log é público. Provavelmente não seria privado se fosse enviado ao GitHub.

Um truque pode ser fazer um diff em seu espaço de trabalho, verificar o diff em seu repositório git, fazer um commit e então enviar. Então você pode fazer um pull de casa, pegar o diff e depois desenrolar. Mas essa é uma maneira bastante complicada de alcançar esses resultados.

git diff > git-dif-file.diff

estourar o estoque

Cameron McKenzie
fonte