0%
Tutorial 4 de 10
40% concluído

Branches e merge

Aprenda a criar branches para trabalhar em diferentes funcionalidades e a mesclá-las no seu código principal.

Branches e merge

As branches são um dos recursos mais poderosos do Git. Elas permitem desenvolver funcionalidades em paralelo, experimentar sem riscos e manter um histórico limpo. Este tutorial ensinará você a dominar as branches e as técnicas de merge.

O que é uma branch?

Uma branch do Git é um ponteiro móvel para um commit específico. Ela permite divergir da linha principal de desenvolvimento e trabalhar em funcionalidades isoladas.

mainfeature-bInitialFeature AFeature B-1Feature B-2HotfixRelease

Conceitos fundamentais

HEAD é um ponteiro para o commit atual (geralmente o último commit da branch atual).

Branch padrão

  • Historicamente: master
  • Atualmente: main
  • Configurável de acordo com suas preferências

Gerenciamento de branches

Listar as branches

# Branches locais
git branch

# Todas as branches (locais e remotas)
git branch -a

# Somente branches remotas
git branch -r

# Com informações detalhadas
git branch -v

Criar uma branch

# Criar uma nova branch
git branch nouvelle-fonctionnalite

# Criar e mudar para a nova branch
git checkout -b nouvelle-fonctionnalite

# Com Git 2.23+ (recomendado)
git switch -c nouvelle-fonctionnalite

# Criar uma branch a partir de um commit específico
git branch nouvelle-branche abc1234

Alternar entre branches

# Método tradicional
git checkout nom-branche

# Método moderno (Git 2.23+)
git switch nom-branche

# Voltar para a branch anterior
git switch -

# Alternar criando a branch caso ela não exista
git switch -c nouvelle-branche

Renomear uma branch

# Renomear a branch atual
git branch -m nouveau-nom

# Renomear outra branch
git branch -m ancien-nom nouveau-nom

Excluir uma branch

# Excluir uma branch já mesclada
git branch -d nom-branche

# Forçar a exclusão (mesmo sem merge)
git branch -D nom-branche

# Excluir uma branch remota
git push origin --delete nom-branche

Workflow com branches

Exemplo prático: desenvolvimento de uma funcionalidade

# 1. Partir da branch principal
git switch main
git pull origin main

# 2. Criar uma branch para a funcionalidade
git switch -c feature/login-system

# 3. Desenvolver a funcionalidade
echo "function login() { /* code */ }" > login.js
git add login.js
git commit -m "feat: add basic login function"

# 4. Continuar o desenvolvimento
echo "function logout() { /* code */ }" >> login.js
git add login.js
git commit -m "feat: add logout function"

# 5. Voltar para a main para fazer o merge
git switch main

Tipos de merge

Fast-Forward Merge

Quando a branch principal não evoluiu:

git merge feature/login-system
mainfeatureABCD

Three-Way Merge

Quando as duas branches evoluíram:

git merge feature/login-system
mainfeatureABCDEMerge

Merge com mensagem personalizada

git merge feature/login-system -m "Merge login system feature"

No-Fast-Forward Merge

Forçar a criação de um commit de merge:

git merge --no-ff feature/login-system

Rebase: alternativa ao merge

O rebase reescreve o histórico ao mover os commits:

# Fazer rebase da branch atual sobre a main
git rebase main

# Rebase interativo para modificar o histórico
git rebase -i HEAD~3

Diferença entre Merge e Rebase

Merge:

  • Preserva o histórico exato
  • Cria commits de merge
  • Histórico mais complexo, porém completo

Rebase:

  • Histórico linear e limpo
  • Reescreve o histórico
  • Pode complicar a colaboração
mainfeatureABCDEC'D'

Resolução de conflitos

O que é um conflito?

Um conflito ocorre quando o Git não consegue mesclar automaticamente as modificações.

Exemplo de conflito

# Arquivo com conflito
<<<<<<< HEAD
function greet() {
    return "Hello World!";
}
=======
function greet() {
    return "Bonjour le monde!";
}
>>>>>>> feature/french-translation

Resolver um conflito

# 1. Identificar os arquivos em conflito
git status

# 2. Editar os arquivos para resolver os conflitos
# Remover os marcadores <<<<<<<, =======, >>>>>>>
# Manter o código desejado

# 3. Marcar como resolvido
git add fichier-resolu.js

# 4. Finalizar o merge
git commit

Ferramentas para resolver conflitos

# Configurar uma ferramenta de merge
git config --global merge.tool vimdiff

# Iniciar a ferramenta de resolução
git mergetool

# Cancelar um merge em andamento
git merge --abort

Estratégias de branches

Git Flow

Workflow estruturado com branches especializadas:

  • main: código de produção
  • develop: integração das funcionalidades
  • feature/*: novas funcionalidades
  • release/*: preparação das versões
  • hotfix/*: correções urgentes
# Exemplo de Git Flow
git switch develop
git switch -c feature/user-profile
# ... desenvolvimento ...
git switch develop
git merge feature/user-profile

GitHub Flow

Workflow simplificado:

  • main: código de produção
  • feature/*: todas as modificações
# Exemplo de GitHub Flow
git switch main
git switch -c feature/new-header
# ... desenvolvimento ...
git push origin feature/new-header
# ... Pull Request no GitHub ...

Trunk-Based Development

Desenvolvimento diretamente na branch principal, com branches de curta duração.

Comandos avançados

Cherry-pick

Aplicar um commit específico de outra branch:

# Aplicar um commit específico
git cherry-pick abc1234

# Aplicar vários commits
git cherry-pick abc1234 def5678

Stash com branches

# Salvar as modificações
git stash

# Mudar de branch
git switch autre-branche

# Aplicar o stash na nova branch
git stash pop

Comparar branches

# Ver as diferenças entre branches
git diff main..feature/login

# Ver os commits exclusivos de uma branch
git log main..feature/login

# Ver os arquivos modificados
git diff --name-only main..feature/login

Exercícios práticos

Exercício 1: workflow básico com branches

# 1. Inicializar um projeto
mkdir git-branches-demo
cd git-branches-demo
git init
echo "# Projet Demo" > README.md
git add README.md
git commit -m "Initial commit"

# 2. Criar uma branch de feature
git switch -c feature/add-calculator
echo "function add(a, b) { return a + b; }" > calculator.js
git add calculator.js
git commit -m "feat: add calculator function"

# 3. Voltar para a main e criar outra branch
git switch main
git switch -c feature/add-styles
echo "body { font-family: Arial; }" > styles.css
git add styles.css
git commit -m "style: add basic styles"

# 4. Fazer o merge das branches
git switch main
git merge feature/add-calculator
git merge feature/add-styles

# 5. Limpar
git branch -d feature/add-calculator
git branch -d feature/add-styles

Exercício 2: gerenciamento de conflitos

# 1. Criar um conflito intencional
git switch main
echo "Version main" > conflict.txt
git add conflict.txt
git commit -m "Add conflict file from main"

git switch -c feature/conflict-test
echo "Version feature" > conflict.txt
git add conflict.txt
git commit -m "Modify conflict file from feature"

# 2. Tentar o merge (conflito esperado)
git switch main
git merge feature/conflict-test

# 3. Resolver o conflito
# Editar conflict.txt para resolver
echo "Version fusionnée" > conflict.txt
git add conflict.txt
git commit -m "Resolve conflict"

Exercício 3: Rebase vs Merge

# Preparar o ambiente
git switch main
echo "Line 1" > file.txt
git add file.txt
git commit -m "Add line 1"

# Branch com merge
git switch -c branch-merge
echo "Line 2 from merge" >> file.txt
git add file.txt
git commit -m "Add line 2 via merge"

git switch main
echo "Line 3 from main" >> file.txt
git add file.txt
git commit -m "Add line 3 from main"

git merge branch-merge

# Branch com rebase
git switch -c branch-rebase
echo "Line 4 from rebase" >> file.txt
git add file.txt
git commit -m "Add line 4 via rebase"

git switch main
echo "Line 5 from main" >> file.txt
git add file.txt
git commit -m "Add line 5 from main"

git switch branch-rebase
git rebase main
git switch main
git merge branch-rebase

# Comparar os históricos
git log --oneline --graph

Boas práticas

Nomenclatura das branches

# Convenções comuns
feature/user-authentication
bugfix/login-error
hotfix/security-patch
release/v1.2.0
experiment/new-algorithm

Workflow recomendado

  1. Sempre partir da main atualizada

    git switch main
    git pull origin main
  2. Criar branches curtas e focadas

    git switch -c feature/specific-task
  3. Commits frequentes e atômicos

    git commit -m "feat: add specific functionality"
  4. Testar antes de fazer o merge

    # Tests, linting, etc.
  5. Limpar após o merge

    git branch -d feature/completed-task

Evitar erros comuns

  1. Não desenvolver diretamente na main
  2. Sempre verificar a branch atual
  3. Resolver os conflitos com atenção
  4. Não forçar o push após um rebase
  5. Comunicar os rebases à equipe

Ferramentas e interfaces

Ferramentas de linha de comando

# Ver a árvore de branches
git log --oneline --graph --all

# Alias útil
git config --global alias.tree 'log --oneline --graph --all'

Ferramentas gráficas

  • GitKraken: excelente visualização das branches
  • SourceTree: interface completa
  • VS Code: extensão Git Graph
  • GitHub Desktop: simples e eficiente

Solução de problemas

HEAD desanexado (Detached HEAD)

# Se você estiver em HEAD desanexado
git switch -c nouvelle-branche-sauvegarde
git switch main

Desfazer um merge

# Desfazer o último merge
git reset --hard HEAD~1

# Ou, se o merge ainda não foi commitado
git merge --abort

Recuperar uma branch excluída

# Encontrar o commit da branch excluída
git reflog

# Recriar a branch
git branch branche-recuperee abc1234

Recursos adicionais

Documentação

Ferramentas interativas

Conclusão

Dominar as branches e o merge é essencial para um desenvolvimento eficiente com Git. Esses conceitos permitem que você trabalhe em paralelo, experimente sem riscos e mantenha um histórico limpo.

No próximo tutorial, vamos conhecer o GitHub, a plataforma que revolucionou a colaboração em torno do Git.


Tempo de leitura estimado: 30 minutos
Nível: Intermediário
Etapa anterior: Comandos Git essenciais
Próxima etapa: Introdução ao GitHub