Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Branches

Até agora trabalhamos apenas em uma linha reta de commits. Mas imagine que você quer experimentar uma nova funcionalidade sem arriscar quebrar o que já está funcionando. Ou que dois colegas querem trabalhar em funcionalidades diferentes ao mesmo tempo. É para isso que existem os branches (ramos).

Uma branch é uma linha independente de desenvolvimento. Quando você cria uma branch, está criando um espaço isolado onde pode fazer commits sem afetar a branch principal.

A branch padrão geralmente se chama main1. Vamos criar uma branch nova para adicionar uma página “sobre”:

$ git branch pagina-sobre

Esse comando criou a branch, mas ainda estamos na main. Para mudar para a nova branch, usamos git checkout:

$ git checkout pagina-sobre
Switched to branch 'pagina-sobre'

Existe um atalho que cria a branch e muda para ela de uma vez:

$ git checkout -b pagina-sobre
Switched to a new branch 'pagina-sobre'

Agora, qualquer commit que fizermos será registrado na branch pagina-sobre, sem afetar a main. Vamos criar o arquivo sobre.html e fazer um commit:

$ git add sobre.html
$ git commit -m "Adicionar página sobre com informações do projeto"
[pagina-sobre 7d8e9f0] Adicionar página sobre com informações do projeto
 1 file changed, 12 insertions(+)
 create mode 100644 sobre.html

Se voltarmos para a main, o arquivo sobre.html não existe:

$ git checkout main
Switched to branch 'main'
$ ls
index.html  style.css

O arquivo só existe na branch pagina-sobre. As duas branches têm históricos diferentes a partir do ponto onde divergiram.

Merge

Quando a funcionalidade na branch está pronta e testada, queremos incorporá-la à branch principal. Esse processo se chama merge (mesclagem).

Para mesclar a branch pagina-sobre na main, primeiro vamos para a main e depois executamos o merge:

$ git checkout main
Switched to branch 'main'
$ git merge pagina-sobre
Updating e4f5a6b..7d8e9f0
Fast-forward
 sobre.html | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 sobre.html

Agora a main contém tudo o que estava em pagina-sobre. O Git disse “Fast-forward” porque não houve alterações na main enquanto trabalhávamos na outra branch. Ele simplesmente avançou o ponteiro.

Após o merge, a branch pagina-sobre pode ser apagada:

$ git branch -d pagina-sobre
Deleted branch pagina-sobre (was 7d8e9f0).

Conflitos

Nem todo merge é tão simples. Quando duas branches alteram a mesma parte do mesmo arquivo, o Git não consegue decidir qual versão manter. Isso é um conflito.

Suponha que dois desenvolvedores, Maria e João, criaram branches separadas a partir da main. Maria alterou a saudação no index.html para “Olá, pessoal!” na branch saudacao-maria. João alterou a mesma linha para “Bem-vindos ao site!” na branch saudacao-joao.

Maria faz o merge primeiro. Tudo corre bem. Agora João tenta fazer o merge da sua branch:

$ git checkout main
$ git merge saudacao-joao
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.

O Git nos avisa que houve um conflito. Se abrirmos o index.html, veremos algo assim:

<!DOCTYPE html>
<html>
<head>
    <title>Meu Site</title>
</head>
<body>
<<<<<<< HEAD
    <h1>Olá, pessoal!</h1>
=======
    <h1>Bem-vindos ao site!</h1>
>>>>>>> saudacao-joao
    <p>Bem-vindo ao meu site.</p>
</body>
</html>

O trecho entre <<<<<<< HEAD e ======= é a versão que já está no main (a alteração da Maria). O trecho entre ======= e >>>>>>> saudacao-joao é a versão da branch do João. Para resolver o conflito, editamos o arquivo e escolhemos a versão final. Podemos manter uma, a outra, ou combinar as duas:

    <h1>Olá, pessoal! Bem-vindos ao site!</h1>

Depois de editar, removemos os marcadores de conflito (<<<<<<<, =======, >>>>>>>), adicionamos o arquivo à staging area e fazemos o commit:

$ git add index.html
$ git commit -m "Resolver conflito: combinar saudações de Maria e João"
[main b3c4d5e] Resolver conflito: combinar saudações de Maria e João

Conflitos são normais. Sempre que duas pessoas mexem no mesmo trecho, o Git não tenta adivinhar qual versão é a correta. Ele mostra as duas e deixa a decisão com você.


  1. Historicamente, a branch padrão se chamava master. Em 2020, o GitHub e outras plataformas mudaram o padrão para main. Ambos os nomes funcionam da mesma forma. A escolha é apenas de convenção. ↩