Como Squash Commits no Git para Manter Seu Histórico Limpo
Quando você está trabalhando com o Git, é uma boa ideia se comprometer com frequência, então você sempre pode voltar ao estado do código se bagunçar. No entanto, comprometer todas essas mini-alterações no branch principal nem sempre é uma boa ideia. Isso torna a história confusa e difícil de seguir.
Git fornece uma maneira de esmagar um monte de seus commits usando o comando rebase. Depois de ter feito localmente suas alterações em um arquivo específico ou para um recurso específico, você sempre pode usar o método squash para combinar as alterações antes de se comprometer com o branch principal. Isso ajudará outras pessoas a entender melhor suas mudanças.
Aviso: Mesmo que você possa extrair de repositórios externos e squash commits juntos, é uma má ideia. Pode criar conflitos e confusão. Evite mudar a história que já é pública. Limite-se apenas a eliminar os commits locais para o seu trabalho.
Vamos trabalhar com um caso de exemplo.
Suponha que temos dois arquivos um.py e b.py. Vamos primeiro passar pelo processo de criação dos arquivos e fazer as modificações:
$ mkdir meuprojeto$ cd myproject /
$ git init
$ echo "print (" hello A ")"> a.py
$ git add -A && git commit -m "Adicionou um.py "
$ echo "print (" hello B ")"> b.py
$ git add -A && git commit -m "Adicionado b.py "
$ echo "print (" hello BB ")"> b.py
$ git add -A && git commit -m "b.Modificação py 1 "
$ echo "print (" hello BBB ")"> b.py
$ git add -A && git commit -m "b.Modificação py 2 "
Se verificarmos o histórico de commits, veremos o seguinte:
$ git log --oneline --graph --decorate* dfc0295 (HEAD -> master) b.Modificação py 2
* ce9e582 b.Modificação py 1
* 7a62538 Adicionado b.py
* 952244a Adicionado um.py
Depois de terminarmos nosso trabalho, decidimos colocar todas as alterações no b.py em um único commit para maior clareza. Contamos que existem 3 commits em b.py da CABEÇA. Emitimos o seguinte comando:
git rebase -i HEAD ~ 3A opção -i diz ao Git para usar o modo interativo.
Deve aparecer uma janela no seu editor de texto Git:
pick 7a62538 Adicionado b.pyescolher ce9e582 b.Modificação py 1
escolher dfc0295 b.Modificação py 2
# Rebase 952244a… dfc0295 em 952244a (3 comandos)
#
# Comandos:
# p, pick = use commit
# r, reword = use commit, mas edite a mensagem de commit
# e, edit = use commit, mas pare para emendar
# s, squash = usar commit, mas mesclar com commit anterior
# f, fixup = como "squash", mas descarte a mensagem de log deste commit
# x, exec = run command (o resto da linha) usando shell
#
# Essas linhas podem ser reordenadas; eles são executados de cima para baixo.
#
# Se você remover uma linha aqui ESSE COMPROMISSO SERÁ PERDIDO.
#
# No entanto, se você remover tudo, o rebase será abortado.
#
# Observe que os commits vazios são comentados
~
Os commits são listados cronologicamente no topo, do mais antigo ao mais recente. Você pode escolher qual commit “escolher” e qual commitar para squash. Para simplificar, vamos escolher o primeiro commit e espremer o resto nele. Portanto, vamos modificar o texto assim:
pick 7a62538 Adicionado b.pysquash ce9e582 b.Modificação py 1
squash dfc0295 b.Modificação py 2
# Rebase 952244a… dfc0295 em 952244a (3 comandos)
#
# Comandos:
# p, pick = use commit
# r, reword = use commit, mas edite a mensagem de commit
# e, edit = use commit, mas pare para emendar
# s, squash = usar commit, mas mesclar com commit anterior
# f, fixup = como "squash", mas descarte a mensagem de log deste commit
# x, exec = run command (o resto da linha) usando shell
#
# Essas linhas podem ser reordenadas; eles são executados de cima para baixo.
#
# Se você remover uma linha aqui ESSE COMPROMISSO SERÁ PERDIDO.
#
# No entanto, se você remover tudo, o rebase será abortado.
#
# Observe que os commits vazios são comentados
Assim que você salvar e fechar o arquivo de texto, outra janela de texto deverá aparecer com a seguinte aparência:
# Esta é uma combinação de 3 commits.# A mensagem do primeiro commit é:
Adicionado b.py
# Esta é a segunda mensagem de confirmação:
b.Modificação py 1
# Esta é a terceira mensagem de confirmação:
b.Modificação py 2
# Por favor, insira a mensagem de confirmação para suas alterações. Linhas começando
# com '#' será ignorado, e uma mensagem vazia aborta o commit.
#
# Date: Fri Mar 30 21:09:43 2018 -0700
#
# rebase em andamento; para 952244a
# No momento você está editando um commit enquanto rebase o branch 'master' em '952244a'.
#
# Mudanças a serem confirmadas:
# Novo arquivo: b.py
#
Salve e feche este arquivo também. Você deve ver algo assim:
$ git rebase -i HEAD ~ 3[separado HEAD 0798991] Adicionado b.py
Data: Sex. 30 de março 21:09:43 2018 -0700
1 arquivo alterado, 1 inserção (+)
modo de criação 100644 b.py
Refs / heads / master rebaseados e atualizados com sucesso.
Se você verificar o histórico de commits agora:
$ git log --oneline --graph --decorate* 0798991 (HEAD -> mestre) Adicionado b.py
* 952244a Adicionado um.py
Todos os commits para b.py foram comprimidos em um commit. Você pode verificar olhando para b.arquivo py:
$ cat b.pyimprimir ("olá BBB")
Possui o conteúdo da Modificação 2.
Conclusão
O rebase é um comando poderoso. Isso pode ajudá-lo a manter seu histórico limpo. Mas evite usá-lo para commits públicos, pois pode causar conflitos e confusão. Use-o apenas para o seu próprio repositório local.
Um estudo mais aprofundado:
- https: // git-scm.com / docs / git-rebase
- https: // git-scm.com / book / en / v2 / Git-Branching-Rebasing
- https: // git-scm.com / book / en / v2 / Git-Tools-Rewriting-History