Artigo original: The Ultimate Guide to Git Merge and Git Rebase
Boas-vindas ao nosso guia definitivo para os comandos git merge
e git rebase
. Este tutorial ensinará a você tudo o que você precisa saber sobre combinar várias branches usando o Git.
Git Merge
O comando git merge
fará a junção das alterações feitas à base de código em uma branch separada à sua branch atual como um novo commit.
A sintaxe do comando é a seguinte:
git merge NOME-DA-BRANCH
Por exemplo, se você está trabalhando atualmente em uma branch chamada dev
e gostaria de fazer o merge de alterações feitas em uma branch chamada new-features
, o comando teria esta sintaxe:
git merge new-features
Observação: se houver alterações cujo commit não foi realizado em sua branch atual, o Git não permitirá fazer o merge até que todas as alterações de sua branch atual sejam passadas por commit. Para lidar com essas alterações, você pode:
Criar uma nova branch e fazer o commit das alterações
git checkout -b novo-nome-da-branch
git add .
git commit -m "<sua mensagem de commit>"
Faça o stash das alterações
git stash # adiciona as mudanças ao stash
git merge new-features # faz o merge
git stash pop # obtém as alterações de sua árvore de trabalho
Abandonar todas as alterações
git reset --hard # remove todas as alterações pendentes
Git Rebase
Fazer o rebase de uma branch no Git é uma maneira de mover toda uma branch para outro ponto da árvore. O exemplo mais simples é mover uma branch mais para cima na árvore. Digamos que temos uma branch que esteja divergente da branch master/main no ponto A:
/o-----o---o--o-----o--------- branch
--o-o--A--o---o---o---o----o--o-o-o--- master/main
Ao fazer o rebase, podemos movê-la assim:
/o-----o---o--o-----o------ branch
--o-o--A--o---o---o---o----o--o-o-o master/main
Para fazer o rebase, certifique-se de ter todos os commits que deseja usar no rebase em sua branch master/main. Confira a branch da qual você quer fazer o rebase e digite git rebase master/main
(onde master/main é a branch na qual você quer fazer o rebase).
Também é possível fazer um rebase em uma branch diferente. Então, por exemplo, uma branch que foi baseada em outra branch (vamos chamá-la de feature) passa pelo rebase na branch master/main:
/---o-o branch
/---o-o-o-o---o--o------ feature
----o--o-o-A----o---o--o-o-o--o--o- master/main
Após git rebase master/main branch
ou git rebase master/main
, quando você conferir a branch, terá o seguinte:
/---o-o-o-o---o--o------ feature
----o--o-o-A----o---o--o-o-o--o--o- master/main
\---o-o branch
Git rebase interativo no console
Para usar git rebase
no console com uma lista de commits que você pode selecionar, editar ou excluir do rebase:
- Digite
git rebase -i HEAD~5
, com o último número sendo o número de commits anteriores mais recentes que você quer revisar. - No vim, pressione
esc
, ei
para começar a editar o teste. - No lado esquerdo, você pode sobrescrever o
pick
com um dos comandos abaixo. Se quiser fazer o squash de um commit em outro commit anterior e descarte a mensagem de commit, digitef
no lugar dopick
do commit. - Salve e saia de seu editor de texto.
- Quando o rebase for interrompido, faça os ajustes necessários, depois use
git rebase --continue
até que o rebase tenha êxito. - Se o rebase tiver sucesso, você precisará fazer o force push de suas alterações com
git push -f
para adicionar a versão colocada em rebase em seu repositório remoto. - Se houver um conflito de merge, há várias maneiras de se consertar isso, incluindo seguir as sugestões deste guia (em inglês). Uma maneira é abrir os arquivos em um editor de texto e excluir as partes do código que você não quer. Depois, use
git add <nome do arquivo>
seguido porgit rebase --continue
. Você pode saltar o commit com o conflito inserindogit rebase --skip
e parar o rebase executandogit rebase --abort
em seu console.
pick 452b159 <mensagem deste commit>
pick 7fd4192 <mensagem deste commit>
pick c1af3e5 <mensagem deste commit>
pick 5f5e8d3 <mensagem deste commit>
pick 5186a9f <mensagem deste commit>
# Rebase 0617e63..5186a9f em 0617e63 (30 comandos)
#
# Comandos:
# p, pick = usa o commit
# r, reword = usa o commit, mas interrompe para editar a mensagem do commit.
# e, edit = usa o commit, mas interrompe para consertar ou adicionar o commit.
# s, squash = usa o commit, une no commit anterior e interrompe para editar a mensagem de commit.
# f, fixup = como em "squash", mas descarta a mensagem de log desse commit e, portanto, não interrompe.
# x, exec = executa o comando (o resto da linha) usando shell
# d, drop = remove o commit
#
# Essas linhas podem ser reordenadas; eles são executados de cima para baixo.
#
# Se você remover uma linha aqui ESSE COMMIT SERÁ PERDIDO.
#
# Porém, se remover tudo, o rebase será cancelado.
#
# Observe que os commits vazios estão comentados para não aparecerem
Conflitos de merge
Um conflito de merge ocorre quando fazemos commits em branches separados que alteram a mesma linha de modos que causam conflito. Se isso acontecer, o Git não saberá qual versão do arquivo deve ser mantida e enviará uma mensagem de erro semelhante a esta:
CONFLICT (content): Merge conflict in resumé.txt Automatic merge failed; fix conflicts and then commit the result.
Se examinar o arquivo resumé.txt
em seu editor de código, poderá ver onde o conflito aconteceu:
<<<<<<< HEAD
Address: 808 South Street
=======
Address: 505 North Street
>>>>>>> updated_address
O Git adicionou algumas linhas a mais ao arquivo:
<<<<<<< HEAD
=======
>>>>>>> updated_address
Pense nos =======
como a linha divisória do conflito. Tudo o que está entre <<<<<<< HEAD
e =======
é o conteúdo da branch atual para o qual a referência HEAD está apontando. Por outro lado, tudo entre =======
e >>>>>>> updated_address
é o conteúdo na branch de que se está fazendo o merge, ou seja, updated_address
(o endereço atualizado).
Git merge x Git rebase
git merge
e git rebase
são comandos muito úteis. Um não é "melhor" que o outro. Porém, há algumas diferenças bastante importantes entre os dois comandos que você e sua equipe devem levar em consideração.
Sempre que git merge
é executado, um commit de merge a mais é criado. Sempre que estiver trabalhando em seu repositório local, fazer muitos commits de merge pode tornar confuso o histórico de commits. Uma maneira de se evitar o commit de merges é usar git rebase
e, seu lugar.
git rebase
é um recurso muito poderoso. Dito isso, saiba que ele também é arriscado se não for usado da maneira correta. git rebase
altera o histórico de commits. Por isso, use-o com cuidado. Se o rebase for feito no repositório remoto, ele pode criar diversos problemas quando outros desenvolvedores tentarem fazer o pull das alterações mais recentes do código do repositório remoto. Lembre-se de executar o git rebase
somente em um repositório local.
Isso era o que você precisava saber sobre os comandos merge e rebase, com a melhor forma de se utilizar a ambos.