git stash: como guardar alterações temporariamente e recuperá-las
O git stash guarda as alterações não commitadas em um armazenamento separado e devolve o diretório de trabalho ao último commit, para que você possa mudar para outra tarefa. Para recuperar as alterações, use git stash pop (aplica e remove do armazenamento) ou git stash apply (aplica e mantém); não existe um comando git unstash.
Para que serve o git stash
Situação típica: você está no meio de uma tarefa, os arquivos estão alterados, ainda é cedo para commitar — e de repente pedem uma correção urgente de bug em outra branch. Não dá para trocar de branch, ou você tem medo de perder as alterações. O git stash coloca todas as alterações não commitadas "no bolso" e devolve o diretório de trabalho ao estado do último commit.
$ git stash
Saved working directory and index state WIP on feature/login: 3f2a1c4 Formulário de login
$ git status
On branch feature/login
nothing to commit, working tree clean
Agora você pode trocar de branch, corrigir o bug, voltar e recuperar o que guardou. Cada salvamento é uma entrada na pilha do stash; internamente o Git a guarda como um commit especial, então os dados são confiáveis e não dependem da branch.
Como guardar alterações: as principais opções
Com uma descrição clara
A descrição padrão "WIP on branch" não vai dizer nada daqui a uma semana. Dê um nome:
git stash push -m "validação do formulário, falta o e-mail"
git stash sem argumentos é um atalho para git stash push. A forma antiga git stash save "mensagem" ainda funciona, mas em novos cenários use push -m.
Incluindo arquivos novos
Por padrão, o stash leva só os arquivos rastreados — alterados e adicionados ao índice. Arquivos novos que nunca passaram por git add ficam no diretório de trabalho. Essa é uma surpresa frequente.
git stash -u # --include-untracked: inclui arquivos não rastreados
git stash -a # --all: inclui também arquivos do .gitignore
Cuidado com -a: vão para o bolso também o node_modules, os builds e as configs locais. Normalmente -u é suficiente.
Só parte das alterações
git stash push -m "config" src/config.js # só os arquivos indicados
git stash -p # escolher trechos de forma interativa
git stash --staged # só o que está no índice (Git 2.35+)
git stash --keep-index # guardar tudo, mas manter o índice na pasta
O --keep-index é útil antes de um commit: você deixa no diretório de trabalho só o que vai commitar, roda os testes e confirma que o commit se sustenta sozinho.
Como recuperar as alterações (git unstash)
O comando git unstash não existe no Git — geralmente é assim que as pessoas procuram como recuperar o que guardaram. Para isso há dois comandos.
| Comando | O que faz | Entrada na pilha |
|---|---|---|
git stash pop | Aplica as últimas alterações guardadas | É removida, se aplicada sem conflitos |
git stash apply | Aplica as últimas alterações guardadas | Permanece |
git stash pop stash@{2} | Aplica uma entrada específica | É removida |
git stash apply --index | Restaura também a separação entre índice e diretório de trabalho | Permanece |
$ git stash pop
On branch feature/login
Changes not staged for commit:
modified: src/auth.js
modified: src/form.js
Dropped refs/stash@{0} (8c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d)
Atenção: por padrão, até o que estava no índice no momento do stash volta como alteração comum. Se for importante manter o índice preparado, adicione --index.
pop ou apply
No dia a dia, o pop é prático: recuperou e esqueceu. Prefira o apply quando quiser aplicar as mesmas alterações em várias branches ou não tiver certeza de que tudo vai correr bem — a entrada fica como seguro, e você pode removê-la depois com git stash drop.
Gerenciando a lista do stash
$ git stash list
stash@{0}: On feature/login: validação do formulário, falta o e-mail
stash@{1}: WIP on main: 9b7e0d2 Atualizar dependências
stash@{2}: On feature/api: experimento com cache
A pilha segue o princípio "último a entrar, primeiro a sair": stash@{0} é sempre a entrada mais recente, e os números mudam a cada push e drop.
| Comando | Para que serve |
|---|---|
git stash show | Estatística resumida das alterações da última entrada |
git stash show -p stash@{1} | Diff completo de uma entrada específica |
git stash drop stash@{1} | Remover uma entrada |
git stash clear | Remover todas as entradas de uma vez |
git stash branch nome stash@{0} | Criar uma branch a partir do commit em que o stash foi feito, aplicar a entrada e removê-la |
Para que o git stash show mostre por padrão o diff completo, e não a estatística, e inclua também os arquivos não rastreados, existem as configurações stash.showPatch e stash.showIncludeUntracked.
Passo a passo: bug urgente no meio de uma tarefa
- Guarde o trabalho atual junto com os arquivos novos:
git stash push -u -m "login: rascunho". - Vá para a branch principal e crie uma branch para a correção:
git switch main,git pull,git switch -c hotfix/null-email. - Corrija o bug, faça o commit e envie para review.
- Volte para a tarefa:
git switch feature/login. - Recupere as alterações:
git stash pop. Confira comgit status— está tudo lá.
Hoje muita gente usa git worktree nesse cenário: uma segunda pasta de trabalho para o mesmo repositório dispensa guardar qualquer coisa. Mas para uma troca rápida de cinco minutos, o stash continua mais simples.
Conflitos ao aplicar o stash
Se depois do stash as mesmas linhas foram alteradas na branch, a aplicação termina em conflito:
$ git stash pop
Auto-merging src/auth.js
CONFLICT (content): Merge conflict in src/auth.js
The stash entry is kept in case you need it again.
Nesse caso a entrada não é removida, mesmo com pop. Resolva o conflito no arquivo normalmente, depois rode git add para marcar a resolução (ou git restore --staged, se não quiser deixar as alterações no índice) e remova a entrada que não é mais necessária com git stash drop.
Se o conflito for complicado, há um atalho: git stash branch tmp-login. O Git cria uma branch a partir do mesmo commit em que você fez o stash — ali as alterações se aplicam sem conflito, e você as integra à branch principal depois com um merge comum.
Como recuperar um stash apagado por engano
Rodou git stash drop ou clear por engano? Nem tudo está perdido. A entrada era um commit e, enquanto o garbage collector não o remover, dá para encontrá-lo entre os objetos "soltos" (dangling):
git fsck --no-reflog | grep "dangling commit"
git show 8c1d2e3 # conferir se é o stash certo
git stash apply 8c1d2e3
Se você acabou de remover a entrada com drop ou pop, o hash aparece na própria saída do comando — na linha Dropped refs/stash@{0} (...). Basta passá-lo para git stash apply.
Como o stash funciona por dentro
Entender a estrutura tira o medo de perder dados. Cada entrada do stash é um commit comum, apontado pela referência refs/stash. Ele tem dois pais: o commit HEAD em que você estava e um commit separado com o estado do índice. Com -u, entra um terceiro pai com os arquivos não rastreados. A lista stash@{N} é simplesmente o log (reflog) da referência refs/stash.
Daí algumas consequências práticas. Você pode passar um stash para qualquer comando que aceite um commit: git diff stash@{0}, git show stash@{0}:src/auth.js (o conteúdo de um arquivo da entrada) ou git checkout stash@{0} -- src/auth.js, para pegar um arquivo sem aplicar a entrada inteira. E uma entrada removida continua no banco de objetos até o garbage collector limpá-la.
Stash e outros comandos do Git
Alguns comandos sabem guardar alterações sozinhos. git rebase --autostash e git pull --rebase --autostash guardam as alterações não commitadas antes de começar e as devolvem no final. Para ativar esse comportamento de forma permanente, use as configurações rebase.autoStash true e merge.autoStash true. Se houver conflito na devolução, o Git salva a entrada na pilha normal do stash e avisa.
Trocar de branch com git switch também nem sempre exige stash: se as suas alterações não se cruzam com arquivos que diferem entre as branches, o Git simplesmente as leva junto. O stash é necessário quando o Git responde "Your local changes would be overwritten by checkout" ou quando você não quer levar as alterações para a outra branch.
Erros comuns
- Os arquivos novos "não foram guardados". Eles não são rastreados; é preciso
-u. - Stash como armazenamento de longo prazo. Um mês depois há dez "WIP on main" sem nome na lista, e ninguém lembra o que tem neles. Para trabalhos longos, faça um commit em uma branch separada — pelo menos dá para enviar ao servidor.
- Esquecer que a entrada ficou depois de um conflito e aplicá-la de novo tempos depois. Depois de resolver o conflito, faça sempre
drop. - O stash não é sincronizado com o servidor. Ele fica só no seu repositório local; o
git pushnão o envia. Se você apagar a pasta do projeto, o stash some. - Aplicar a entrada errada. Antes do
pop, confiragit stash listegit stash show -p.
Resumo
O git stash é uma forma rápida de liberar o diretório de trabalho sem perder alterações não commitadas: git stash push -u -m "descrição" para guardar e git stash pop para recuperar. Use apply quando quiser um seguro, git stash list e show -p para não se perder, e não transforme o stash em depósito — para o que é longo existem commits e branches. A troca entre tarefas com stash é praticada no curso de Git.
Perguntas frequentes
Dá para aplicar um stash em outra branch?
Sim, o stash não está preso a uma branch: mude para a branch desejada e rode git stash pop ou apply. Se as alterações não encaixarem, surge um conflito comum.
O git stash guarda as alterações do índice?
Guarda, mas com pop ou apply normais tudo volta como alterações não preparadas. Para restaurar também o índice, use git stash apply --index.
Quantas entradas dá para manter no stash?
Não há limite fixo, mas entradas mais antigas que o prazo de retenção do reflog podem ser removidas pelo garbage collector. Na prática, mantenha na pilha no máximo um par de entradas recentes.
Como fazer stash de um único arquivo?
Indique o caminho depois de dois hifens ou logo depois do push: git stash push -m descrição -- src/config.js. Só esse arquivo vai para o stash; as demais alterações ficam no diretório de trabalho.
Qual a diferença entre stash e um commit temporário?
O commit fica em uma branch, pode ser enviado ao servidor e ajustado depois com amend ou rebase. O stash fica só localmente, em uma pilha separada, e é prático para trocas rápidas.
Este tema é abordado em profundidade, com prática, no curso “Git do zero ao desenvolvedor confiante”.
Ir para o curso