git rebase

Além do merge, é possível mover ou editar seus commits. O comando git rebase permite isso. Há dois tipos de rebase: o interativo e o não-interativo.

Rebase Não-Interativo

Um rebase não-interativo "desloca" os commits de uma branch para de tal forma que os commits de outra branch façam parte da história desta branch, preservando o conteúdo dos arquivos da primeira branch. Por exemplo, imagine o seguinte cenário:

master    teste
80ba4e4  b49a7ed <- HEAD
   |        |
   |     4b12d0a
   |    /
   |   /
ec49a96
   |
3c97506

Agora, suponha que queremos "fingir" que a branch começa no commit 80ba4e4 e não no commit ec49a96. Basta executarmos o seguinte:

git rebase master teste

O Resultado é:

          teste
         b49a7ed <- HEAD
            |
         4b12d0a
        /
master /
80ba4e4
   |
ec49a96
   |
3c97506

Rebase Interativo

Para iniciar um rebase interativo desde 3 commits atrás, basta executar:

git rebase -i HEAD~3

Isso abrirá um editor de texto (No Linux, o padrão é o vi) para escolher como você vai editar os commits. Você deve ver no editor um conteúdo similar a esse:

texto descrevendo um rebase interativo

A imagem por si só é bem descritiva. Note que você pode alterar a ordem também, como no rebase não-interativo. Mas como exemplo, tomemos a seguinte edição, onde juntaremos os dois primeiros commits em um (squash) e editaremos a mensagem do terceiro.

texto descrevendo um rebase interativo editado

Ao salvarmos e saírmos do editor, seremos requisitados para fornecer a mensagem dos commits que serão fundidos.

texto descrevendo um squash

Basta editar a área que não está comentada (isto é, que não inicia com "#"), e sair do editor.

texto descrevendo um squash editado

Depois, precisamos editar a mensagem terceiro commit do rebase. Para isso, basta executar:

git commit --amend

E um editor irá abrir para inserirmos a mensagem. Ele virá com a mensagem antiga, mas basta editar o texto de forma semelhante ao squash.

Para seguir em frente da edição do commit, basta executar:

git rebase --continue

Se em algum momento você quiser abortar o rebase, execute:

git rebase --abort