W3docs

git rebase -i (interativo)

Aprenda o rebase interativo com git rebase -i para combinar, renomear, editar, descartar e reordenar commits antes de compartilhá-los.

O que é o rebase interativo

O rebase interativo, executado com git rebase -i, permite que você reescreva uma série de commits antes de compartilhá-los. Ele abre uma "lista de tarefas" editável de commits onde você decide, linha por linha, o que acontece com cada um — mantê-lo, renomear sua mensagem, mesclá-lo com outro, dividi-lo, reordená-lo ou descartá-lo. Ele se baseia no git rebase simples, mas coloca você no controle de cada etapa.

Esta página cobre como iniciar um rebase interativo, cada comando que você pode colocar na lista de tarefas, os fluxos de trabalho mais comuns (squashing, renomeação, reordenação, descarte e divisão de commits), como se recuperar quando algo dá errado, e a única regra que o mantém seguro.

Uma lista de tarefas de rebase interativo combinando e renomeando commits

Um commit é um instantâneo salvo do seu trabalho; HEAD é um ponteiro para o commit em que você está atualmente. "Reescrever o histórico" significa produzir novos commits para substituir os existentes — o Git nunca edita um commit no lugar, portanto cada commit reescrito recebe um hash completamente novo.

Iniciando um rebase interativo

Aponte o comando para o commit anterior ao primeiro que você deseja editar — o rebase repetirá tudo que vier depois dele. Para revisitar os três últimos commits:

git rebase -i HEAD~3

HEAD~3 significa "três commits antes de HEAD". Você também pode nomear um commit explícito (git rebase -i a1b2c3d) ou, em um branch, fazer o rebase de tudo desde que ele foi separado de outro branch (git rebase -i main).

O Git abre o editor configurado com uma linha por commit, o mais antigo no topo (o inverso do git log):

pick a1b2c3d add login form
pick b2c3d4e fix typo
pick c3d4e5f more css tweaks

Abaixo da lista, o Git inclui uma folha de referência comentada de cada comando. Você muda a palavra no início de cada linha para escolher uma ação, opcionalmente reordena as linhas, depois salva e fecha. O Git repete os commits de cima para baixo de acordo com suas instruções. Se você salvar o arquivo sem alterações (ou excluir todas as linhas), o rebase não fará nada e encerrará.

Os comandos da lista de tarefas

Cada linha começa com um comando. Estes são os que você usa com mais frequência:

ComandoAbreviaçãoEfeito
pickpUsa o commit como está.
rewordrUsa o commit, mas edita sua mensagem.
editePausa no commit para que você possa alterar seu conteúdo (corrigir, dividir ou adicionar arquivos).
squashsCombina com o commit anterior, mesclando ambas as mensagens.
fixupfComo squash, mas descarta a mensagem deste commit.
dropdRemove o commit completamente (excluir a linha tem o mesmo efeito).
execxExecuta um comando shell (por exemplo, testes) naquele ponto do rebase.

Não existe um comando reorder — você reordena os commits simplesmente movendo as linhas para cima ou para baixo na lista de tarefas. As linhas são aplicadas de cima para baixo, portanto a ordem que você deixar é a ordem que o Git cria.

Combinando commits com squash

Uma limpeza comum é dobrar vários commits pequenos em um só. Marque o primeiro como pick e os demais como squash (ou fixup para descartar suas mensagens):

pick a1b2c3d add login form
squash b2c3d4e fix typo
fixup c3d4e5f more css tweaks

squash/fixup sempre mescla para cima, no commit da linha anterior. Ao salvar, o Git combina os três em um único commit. Como b2c3d4e foi combinado com squash, o Git abre um segundo editor mostrando ambas as mensagens de commit para que você possa escrever uma mensagem limpa; o fixup de c3d4e5f contribui com suas alterações, mas descarta sua mensagem silenciosamente.

Se tudo que você quer é dobrar pequenos commits "oops" em um anterior, veja git commit --fixup (consulte git commit --amend e git rebase -i --autosquash), que marca as linhas para você automaticamente.

Renomeando uma mensagem de commit

Para corrigir um erro de digitação ou esclarecer uma mensagem sem tocar no código, marque a linha com reword:

pick a1b2c3d add login form
reword b2c3d4e fix tpyo
pick c3d4e5f more css tweaks

O Git repete a1b2c3d como está, depois pausa e abre um editor com a mensagem antiga de b2c3d4e para que você possa reescrevê-la, em seguida continua. As alterações do commit não são tocadas — apenas a mensagem (e seu hash) muda.

Reordenando e descartando commits

Para alterar a ordem, mova as linhas. Para excluir um commit, marque-o como drop ou exclua a linha. Esta lista de tarefas reordena a alteração de CSS antes da correção de digitação e descarta o commit de digitação completamente:

pick a1b2c3d add login form
pick c3d4e5f more css tweaks
drop b2c3d4e fix typo

Descartar ou reordenar pode causar conflitos se um commit posterior dependia do que você removeu ou moveu — o Git pausará e deixará você resolvê-los.

Dividindo um commit

Para dividir um commit grande em vários, marque-o como edit. O Git pausa naquele commit com ele já aplicado; você então desfaz o commit mantendo as alterações e faz novos commits em partes menores:

# rebase pauses on the commit marked 'edit'
git reset HEAD~          # move the commit's changes back to the working tree
git add login.js
git commit -m "add login form markup"
git add styles.css
git commit -m "style the login form"
git rebase --continue    # resume the rest of the rebase

git reset HEAD~ desfaz o último commit, mas deixa suas alterações nos seus arquivos (consulte git reset), para que você possa preparar e confirmá-las como commits separados e menores.

Concluindo ou abandonando

Se uma etapa causar um conflito, o Git pausa para que você possa resolvê-lo. Edite os arquivos com conflito, prepare as correções com git add e depois continue:

git rebase --continue

Se você decidir que um commit específico não deve ser aplicado ao pausar em um conflito, use git rebase --skip. Para abandonar todo o rebase e voltar exatamente ao ponto de partida:

git rebase --abort

Mesmo após a conclusão de um rebase, os commits originais não são perdidos imediatamente — eles permanecem acessíveis por meio do git reflog por algum tempo, que é a rede de segurança caso você faça um rebase e se arrependa.

Uma palavra de cautela

O rebase interativo reescreve o histórico — os commits resultantes têm novos hashes. Isso é perfeito para organizar seu próprio branch antes de abrir um pull request, mas nunca faça rebase de commits que outras pessoas já baixaram. Reescrever o histórico compartilhado força todos os outros a reconciliar cópias divergentes, e enviar o resultado requer um force push (git push --force-with-lease). A regra de ouro: rebase localmente, mescle publicamente.

Se você só precisa alterar o último commit, geralmente não precisa de um rebase completo — git commit --amend é mais simples. Para copiar um único commit de outro lugar para o seu branch, consulte git cherry-pick.

Um exemplo completo de squash

Aqui está uma sequência completa que você pode executar em uma pasta vazia para ver o squashing em ação. Ela cria quatro commits e depois dobra os três últimos em um:

git init -b main demo && cd demo
git config user.email [email protected]
git config user.name You

echo "init"  > base && git add base && git commit -m "initial commit"
echo "a"     > f    && git add f    && git commit -m "add login form"
echo -e "a\nb" > f  && git add f    && git commit -m "fix typo"
echo -e "a\nb\nc" > f && git add f  && git commit -m "more css tweaks"

git log --oneline      # four commits
git rebase -i HEAD~3   # mark line 2 'squash', line 3 'fixup', save
git log --oneline      # now: "initial commit" + one combined commit

Após o rebase, git log --oneline mostra apenas dois commits — o commit inicial e um único commit combinado — e o arquivo f ainda contém as três linhas (a, b, c). O trabalho é idêntico; apenas o histórico de commits está mais organizado.

Prática

Prática
Quais afirmações sobre o rebase interativo estão corretas?
Quais afirmações sobre o rebase interativo estão corretas?
Was this page helpful?