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ê.
-
Historicamente, a branch padrão se chamava
master. Em 2020, o GitHub e outras plataformas mudaram o padrão paramain. Ambos os nomes funcionam da mesma forma. A escolha é apenas de convenção. ↩