1. O que são branches e por que elas existem?
Trabalhar com branches no Git — é um dos aspectos-chave do versionamento que permite manter várias linhas de desenvolvimento em paralelo dentro do mesmo repositório. Branching torna o Git uma ferramenta poderosa para colaboração, experimentos e gerenciamento de diferentes versões do projeto.
gitGraph
commit id: "Initial setup"
commit id: "Add base features"
branch feature/new-idea
checkout feature/new-idea
commit id: "Implement new logic"
commit id: "Refactor the logic"
checkout main
commit id: "Urgent bugfix on main"
merge feature/new-idea
commit id: "Prepare for release"
main sai uma nova branch,
feature/new-idea, para desenvolvimento seguro. Depois de terminar o trabalho ela é mesclada de volta em
main.
Imagine que você quer refatorar algo grande no seu projeto ou fazer um experimento arriscado. Como você faria sem Git? Muito provavelmente copiaria todo o projeto para uma nova pasta e trabalharia lá. Se o resultado agradar — transferiria para a pasta principal. Se não — simplesmente excluiria a cópia.
Branches no Git funcionam pelo mesmo princípio, só que de forma muito mais elegante. Vamos ver um exemplo usando a escrita de um livro:
- Você tem um manuscrito pronto (essa é sua branch principal
main). - Você quer escrever um final alternativo (cria uma nova branch, por exemplo
feature/new-idea). - Você escreve o novo final sem tocar no texto principal do manuscrito (trabalha na nova branch).
- Se o novo final for melhor, você o incorpora ao antigo (faz o merge das branches —
merge). - O rascunho com o final antigo que não serve mais pode ser deletado (remove-se a branch).
2. Criando uma nova branch e trabalhando nela
Passo 1. Abra o menu de controle de branches.
No painel superior da IDE tem um widget que mostra o nome da branch atual (por padrão — main). Clique nele e escolha + New Branch.
Passo 2. Nome da nova branch.
Boa prática — nomear branches de acordo com a tarefa que você está resolvendo. Por exemplo, feature/add-usage-examples.
Depois de criar a branch a IDE vai automaticamente mudar para ela. Você verá o novo nome no mesmo widget.
Passo 3. Faça mudanças e commit.
Agora você está na sua "caixa de areia". Vamos adicionar no arquivo README.md uma nova seção com exemplos de uso. Faça as mudanças e dê um commit, como você aprendeu na palestra anterior.
3. Alternando entre branches
Suas mudanças com exemplos de uso agora estão guardadas com segurança na branch feature/add-usage-examples. Vamos voltar para a branch principal main e ver como estão as coisas por lá.
Passo 1. Clique de novo no widget com o nome da branch atual.
Passo 2. Na lista Local ou Recent escolha a branch main, e no submenu que aparecer clique em Checkout.
Passo 3. Verifique o resultado.
Assim que você trocar, abra o arquivo README.md. Você verá que a seção com os exemplos de uso não está lá! Ela ficou na outra branch. Assim você pode desenvolver novas funcionalidades sem tocar na versão estável em main.
4. Merge de branches
O comando merge pega todos os commits da branch feature/add-examples (neste caso, o commit C3) e junta com a branch atual main, criando um novo commit de merge.
gitGraph
commit id: "C1"
commit id: "C2"
branch feature/add-examples
checkout feature/add-examples
commit id: "C3: Add new section"
checkout main
merge feature/add-examples
Então, você terminou sua tarefa na branch feature/add-usage-examples e quer adicionar essas mudanças ao projeto principal.
Passo 1. Mude para a branch alvo.
Garanta que você está na branch para a qual você quer trazer as mudanças. No nosso caso é main.
Passo 2. Execute o merge.
Clique de novo no widget de gerenciamento de branches. Na lista selecione a branch de ONDE você quer pegar as mudanças (feature/add-usage-examples), e no submenu escolha Merge feature/add-usage-examples into main.
Passo 3. Verifique o resultado.
Agora no arquivo README.md da branch main apareceu sua nova seção com exemplos. Você conseguiu mesclar seu trabalho com a versão principal do projeto!
5. Conflitos no merge: não se assuste, isso é normal!
Às vezes, ao mesclar branches surgem conflitos. Isso acontece quando em ambas as branches as mesmas linhas do mesmo arquivo foram alteradas. O Git não consegue decidir sozinho qual versão está certa e pede sua ajuda.
gitGraph
commit id: "C1: Common base"
branch feature/new-title
checkout main
commit id: "C2: Change in main"
checkout feature/new-title
commit id: "C3: Change in feature"
main e
feature/new-title, têm novos commits (C2 e C3) que são baseados num ancestral comum (C1). Isso garante que haverá conflito ao mesclar.
Vamos simular um conflito:
- Garanta que você está na branch
maine que não há mudanças não salvas. - Crie imediatamente uma nova branch
feature/new-title, mas não mude para ela ainda. Verifique que a checkbox Checkout branch está desmarcada. - Agora, estando na branch
main, altere a primeira linha emREADME.mdpara "My Awesome Project" e faça umcommit. - Troque para a branch
feature/new-title. Você vai ver que a primeira linha emREADME.mdpermaneceu antiga: esse é o estado do arquivo no momento da criação da branch. Mude essa mesma linha para "My Super Project" e faça umcommit. - Volte para a branch
maine faça o merge comfeature/new-title.
Agora o Git verá que ambas as branches têm histórias novas divergentes a partir do ancestral comum. Em ambas as histórias a mesma linha foi alterada, então o Git não vai conseguir escolher qual versão é a correta e vai mostrar a janela para resolver o conflito.
Merge Revision
O que você vê aqui:
- À esquerda (Your changes): a versão do arquivo da sua branch atual (
main). - À direita (Changes from branch...): a versão do arquivo da branch que você está mesclando.
- No centro (Result): a versão final do arquivo que você deve montar.
Você pode clicar nas setas >> ou << para aceitar totalmente uma ou outra versão.
Quando o resultado no painel central te agradar, clique em Apply. A IDE vai criar o commit de merge sozinha e o conflito será resolvido.
Por que às vezes não acontece conflito?
Pode acontecer de você seguir todos os passos e não aparecer conflito. Na maioria das vezes isso acontece porque o Git conseguiu fazer um fast-forward merge, já que a história de uma branch simplesmente continuou a história da outra. Para garantir um conflito, as histórias das branches precisam divergir a partir do ancestral comum.
Exemplo:
- Você tem um commit em
main(digamos, C1). - Você faz um novo commit em
maincom o texto "My Awesome Project". A branchmainagora aponta para o commit C2 (main -> C1 -> C2). - Você cria a branch
feature/new-titlea partir da posição atual de main. Isso significa que a nova branch também começa no commit C2. - Você faz um commit em
feature/new-titlecom o texto "My Super Project". Essa branch "vai pra frente" e agora aponta para o commit C3 (feature/new-title -> C1 -> C2 -> C3). - Você volta para
main(que ainda está no commit C2) e manda mesclar feature/new-title.
O Git analisa e vê que a branch main é um antecessor direto da branch feature/new-title. Na história do main não houve novos commits enquanto você trabalhava na outra branch. O Git pensa: "Ah, aqui só precisa avançar o ponteiro do main até o commit C3. Não há conflitos". E ele simplesmente move o ponteiro main para o commit C3.
gitGraph
commit id: "C1"
commit id: "C2"
branch feature/new-title
checkout feature/new-title
commit id: "C3"
checkout main
merge feature/new-title
6. Visualizando o histórico de mudanças
Para entender melhor o que está acontecendo no seu projeto, é útil olhar para o histórico.
Abra a aba Git na parte inferior da IDE e escolha Log. Você verá uma representação gráfica de todas as suas branches e commits. Isso ajuda a acompanhar visualmente de qual branch outra foi criada e onde elas foram mescladas.
Aqui você pode clicar em qualquer commit para ver quais mudanças ele traz, quem e quando o fez. É uma verdadeira máquina do tempo pro código!
GO TO FULL VERSION