Git stash
git stash
arquiva (ou faz o stash) de alterações que você fez na cópia de trabalho durante um determinado período, para que você possa trabalhar em outra coisa, depois voltar e fazer a reaplicação mais tarde. O stashing é útil quando você precisa alternar com rapidez o contexto e trabalhar em outra coisa, mas está no meio da alteração de código e não está pronto para fazer commit.
Fazer stash no trabalho
O comando git stash
salva as alterações sem commit (tanto as preparadas quanto as não preparadas) para uso posterior e as reverte da cópia de trabalho. Por exemplo:
$ git status
On branch main
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
$ git stash
Saved working directory and index state WIP on main: 5002d47 our new homepage
HEAD is now at 5002d47 our new homepage
$ git status
On branch main
nothing to commit, working tree clean
Material relacionado
Git Branch
VER SOLUÇÃO
Aprenda a usar o Git com o Bitbucket Cloud
Nesse ponto, você está livre para fazer alterações, criar novos commits, alternar ramificações e executar quaisquer outras operações do Git. Quando estiver terminado, volte e aplique mais uma vez seu stash quando estiver pronto.
Observe que o stash é local no seu repositório Git; stashes não são transferidos para o servidor quando você envia por push.
Reaplicar as alterações com stash
Você pode então aplicar mais uma vez as alterações que passaram por stashing antes com o git stash pop
:
$ git status
On branch main
nothing to commit, working tree clean
$ git stash pop
On branch main
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
Dropped refs/stash@{0} (32b3aa1d185dfe6d57b3c3cc3b32cbf3e380cc6a)
Executar o popping no stash remove as alterações no stash e as reaplica na cópia de trabalho.
Como outra opção, você pode aplicar mais uma vez as alterações à cópia de trabalho e manter no stash com o git stash apply
:
$ git stash apply
On branch main
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
É um recurso útil caso você queira aplicar as mesmas alterações de stashing a mais da ramificação.
Agora que você aprendeu o básico de stashing, existe uma ressalva com o git stash
que você precisa estar ciente: por padrão, o Git não vai fazer o stash de alterações feitas a arquivos ignorados ou não rastreados.
Fazer stash em arquivos ignorados ou não rastreados
Por padrão, executar o git stash
vai fazer o stash de:
- alterações que foram adicionadas ao seu índice (alterações preparadas)
- alterações feitas a arquivos que estão no momento rastreados pelo Git (alterações despreparadas)
No entanto, o stashing não vai ser realizado em:
- novos arquivos na cópia de trabalho que ainda não foram preparados
- arquivos que foram ignorados
Ou seja, se a gente adiciona um terceiro arquivo ao exemplo acima, mas não o prepara (por exemplo, sem executar o git add
), o git stash
não vai executar o stashing nele.
$ script.js
$ git status
On branch main
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
Untracked files:
script.js
$ git stash
Saved working directory and index state WIP on main: 5002d47 our new homepage
HEAD is now at 5002d47 our new homepage
$ git status
On branch main
Untracked files:
script.js
Adicionar a opção -u
(ou --include-untracked
) vai dizer ao git stash
para também fazer o stashing dos arquivos não rastreados:
$ git status
On branch main
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
Untracked files:
script.js
$ git stash -u
Saved working directory and index state WIP on main: 5002d47 our new homepage
HEAD is now at 5002d47 our new homepage
$ git status
On branch main
nothing to commit, working tree clean
Você também pode incluir alterações para arquivos ignorados, passando a opção -a
(ou --all
) ao executar o git stash
.
Gerenciar múltiplos stashes
Você não está limitado a um único stash. Você pode executar o git stash
mais da vez para criar múltiplos stashes e, então, usar o git stash list
para fazer uma visualização. Por padrão, os stashes são identificados apenas como "WIP" — work in progress (trabalho em progresso) — no topo da ramificação e commit dos quais você criou o stash. Depois de certo tempo, pode ser difícil lembrar o conteúdo de cada stash:
$ git stash list
stash@{0}: WIP on main: 5002d47 our new homepage
stash@{1}: WIP on main: 5002d47 our new homepage
stash@{2}: WIP on main: 5002d47 our new homepage
Para contextualizar melhor, é uma boa prática anotar uma descrição para seus stashes, usando o git stash save "mensagem"
:
$ git stash save "add style to our site"
Saved working directory and index state On main: add style to our site
HEAD is now at 5002d47 our new homepage
$ git stash list
stash@{0}: On main: add style to our site
stash@{1}: WIP on main: 5002d47 our new homepage
stash@{2}: WIP on main: 5002d47 our new homepage
Por padrão, git stash pop
vai reaplicar o stash criado mais há pouco tempo: stash@{0}
Você pode escolher qual stash aplicar mais uma vez, passando seu identificador como o último argumento, por exemplo:
$ git stash pop stash@{2}
Visualizar comparações de stash
Você pode visualizar um resumo do stash com o git stash show
:
$ git stash show
index.html | 1 +
style.css | 3 +++
2 files changed, 4 insertions(+)
Ou passar a opção -p
(ou --patch
) para visualizar a comparação completa do stash:
$ git stash show -p
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..d92368b
--- /dev/null
+++ b/style.css
@@ -0,0 +1,3 @@
+* {
+ text-decoration: blink;
+}
diff --git a/index.html b/index.html
index 9daeafb..ebdcbd2 100644
--- a/index.html
+++ b/index.html
@@ -1 +1,2 @@
+<link rel="stylesheet" href="style.css"/>
Stashes parciais
Também é possível escolher fazer o stashing no único arquivo, uma coleção de arquivos, ou mudanças individuais de dentro de arquivos. Se você passar a opção -p
(ou --patch
) ao git stash
, ele vai percorrer cada "fragmento" alterado na cópia de trabalho e perguntar se você quer fazer o stashing:
$ git stash -p
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..d92368b
--- /dev/null
+++ b/style.css
@@ -0,0 +1,3 @@
+* {
+ text-decoration: blink;
+}
Stash this hunk [y,n,q,a,d,/,e,?]? y
diff --git a/index.html b/index.html
index 9daeafb..ebdcbd2 100644
--- a/index.html
+++ b/index.html
@@ -1 +1,2 @@
+<link rel="stylesheet" href="style.css"/>
Stash this hunk [y,n,q,a,d,/,e,?]? n
Você pode digitar ? para obter uma lista completa de comandos de fragmento. Os mais úteis são:
Comando | Descrição |
---|---|
/ | Descrição pesquisar um fragmento por regex |
? | Descrição ajuda |
n | Descrição não fazer stashing neste fragmento |
q | Descrição sair (o stashing vai ser feito em quaisquer fragmentos que já foram selecionados) |
s | Descrição dividir este fragmento em fragmentos menores |
y | Descrição fazer stashing neste fragmento |
Não existe nenhum comando "abortar" explícito, no entanto, digitar CTRL-C
(SIGINT) vai abortar o processo de stashing.
Criar uma ramificação do stash
Se as alterações na ramificação divergirem das alterações no stash, você vai poder entrar em conflito ao fazer o popping ou aplicar o stash. Outra opção é usar o git stash branch
para criar uma nova ramificação para aplicar alterações com stashing:
$ git stash branch add-stylesheet stash@{1}
Switched to a new branch 'add-stylesheet'
On branch add-stylesheet
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
Dropped refs/stash@{1} (32b3aa1d185dfe6d57b3c3cc3b32cbf3e380cc6a)
Isto verifica uma nova ramificação com base no commit do qual você criou o stash e depois mostra as alterações com stashing nesta ramificação.
Limpar seu stash
Caso você decida que não precisa mais do stash em particular, você pode fazer a exclusão com o git stash drop
:
$ git stash drop stash@{1}
Dropped stash@{1} (17e2697fd8251df6163117cb3d58c1f62a5e7cdb)
Ou você pode excluir todos os seus stashes com:
$ git stash clear
Como o git stash funciona
Se o seu intuito era apenas o de aprender como usar o git stash
, você pode parar de ler aqui. No entanto, caso esteja curioso em saber como o Git (e o git stash
) funciona de fato, continue lendo!
Os stashes são codificados no repositório como objetos com commit. A ref especial em .git/refs/stash
aponta para seu stash mais recente criado e stashes criados antes são referenciados pelo reflog da ref do stash
. É por este motivo que você referencia os stashes com stash@{n}:
você está na verdade referenciando o número de entrada do reflog para a ref do stash
. Como um stash é apenas um commit, você pode examinar com o git log
:
Dependendo em que você fez stash, uma única operação de git stash
vai criar duas ou três novos commits. Os commits no diagrama acima são:
stash@{0}
, um novo commit para armazenar os arquivos rastreados que estavam na cópia de trabalho quando você executou ogit stash
- o primeiro pai do
stash@{0}
, o commit preexistente que estava no HEAD quando você executou ogit stash
- o segundo pai do
stash@{0}
, um novo commit representando o índice quando você executou ogit stash
- o terceiro pai do
stash@{0}
, um novo commit representando arquivos não rastreados que estavam na cópia de trabalho quando você executou ogit stash
. Este terceiro pai só é criado se:- a cópia de trabalho de fato continha arquivos não rastreados; e
- você especificou a opção
--include-untracked
ou--all
ao chamar ogit stash
.
Como o git stash
codifica a árvore de trabalho e índice como commits:
- Antes de fazer o stashing, sua árvore de trabalho pode conter alterações a arquivos rastreados, arquivos não rastreados e arquivos ignorados. Algumas destas alterações podem também estar preparadas no índice.
- Chamar o
git stash
vai codificar quaisquer alterações a arquivos rastreados como dois novos commits no DAG: uma para arquivos despreparados e outra para alterações preparadas no índice. A ref especialrefs/stash
é atualizada para direcionar a elas.
- O uso da opção
--include-untracked
também vai codificar quaisquer alterações para arquivos não rastreados como um commit adicional.
- O uso da opção
--all
inclui as alterações a quaisquer arquivos ignorados em conjunto com as alterações a arquivos não rastreados no mesmo commit.
Ao executar o git stash pop
, as alterações dos commits acima são usadas para atualizar a cópia de trabalho e índice, bem como o reflog do stash é embaralhado para remover o commit mostrado. Observe que os commits mostrados não são excluídos no mesmo instante, mas se tornam candidatos para futura coleta de lixo.
Compartilhar este artigo
Próximo tópico
Leitura recomendada
Marque esses recursos para aprender sobre os tipos de equipes de DevOps ou para obter atualizações contínuas sobre DevOps na Atlassian.