DevOps

Git na Prática: Commits, Branches e Merges sem Medo Já leu

7 min de leitura

Git na Prática: Commits, Branches e Merges sem Medo
Antes do Git, equipes de desenvolvimento compartilhavam código por e-mail, pen drives ou pastas em servidores de rede. Cada mudança era um risco.

Antes do Git, equipes de desenvolvimento compartilhavam código por e-mail, pen drives ou pastas em servidores de rede. Cada mudança era um risco. Desfazer algo era manual e impreciso. Trabalhar em paralelo era um pesadelo de conflitos.

O Git resolveu tudo isso de forma elegante: ele rastreia cada mudança em cada arquivo, permite que múltiplas pessoas trabalhem simultaneamente no mesmo projeto e oferece um histórico completo e auditável de tudo que aconteceu. Em DevOps, o Git não é apenas uma ferramenta de desenvolvimento — é a base sobre a qual pipelines, deploys e automações são construídos. Nenhum pipeline de CI/CD existe sem um repositório Git na origem.

Este artigo cobre o que se usa no dia a dia: commits, branches e merges. Sem teoria desnecessária, direto ao fluxo real de trabalho.


Configuração Inicial

Antes de qualquer coisa, é necessário informar ao Git quem está fazendo as alterações. Essa informação aparece em cada commit:

git config --global user.name "Ricardo Matos"
git config --global user.email "ricardo@exemplo.com"

# Define o VSCode como editor padrão (opcional)
git config --global core.editor "code --wait"

# Define 'main' como nome padrão da branch principal
git config --global init.defaultBranch main

Para verificar todas as configurações:

git config --list

Iniciando um Repositório

Dentro do diretório do projeto:

mkdir meu-projeto
cd meu-projeto
git init

O comando git init cria um diretório oculto .git que armazena todo o histórico e configurações do repositório. Esse diretório não deve ser modificado manualmente.

Para clonar um repositório existente do GitHub:

git clone https://github.com/usuario/repositorio.git

# Clona para uma pasta com nome diferente
git clone https://github.com/usuario/repositorio.git meu-nome-local

O Ciclo Fundamental: Status, Add, Commit

O fluxo básico do Git envolve três estados para cada arquivo: não rastreado (novo arquivo que o Git ainda não conhece), staged (preparado para o próximo commit) e committed (salvo no histórico).

# Verifica o estado atual do repositório
git status

Cria-se um arquivo e observa-se o que o Git reporta:

echo "# Meu Projeto DevOps" > README.md
git status
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        README.md

Adiciona-se ao stage e faz-se o commit:

# Adiciona um arquivo específico
git add README.md

# Adiciona todos os arquivos modificados
git add .

# Confirma o que está no stage
git status

# Faz o commit com uma mensagem descritiva
git commit -m "feat: adiciona README inicial do projeto"

A mensagem do commit deve descrever o que foi feito e por quê — não o como. Mensagens vagas como "atualização" ou "fix" são problemáticas em projetos com múltiplos colaboradores.


Visualizando o Histórico

# Histórico completo
git log

# Formato compacto — um commit por linha
git log --oneline

# Com gráfico de branches
git log --oneline --graph --all

# Últimos 5 commits
git log --oneline -5

Para ver o que mudou em um commit específico:

git show abc1234

Para ver as diferenças entre o estado atual e o último commit:

git diff

Trabalhando com Branches

Uma branch é uma linha independente de desenvolvimento. O uso de branches permite trabalhar em uma nova funcionalidade sem afetar o código principal, testar mudanças com segurança e colaborar em paralelo com outros desenvolvedores.

# Lista todas as branches
git branch

# Cria uma nova branch
git branch feature/configurar-nginx

# Muda para a branch criada
git checkout feature/configurar-nginx

# Atalho: cria e já muda para a branch
git checkout -b feature/configurar-nginx

# Forma moderna (Git 2.23+)
git switch -c feature/configurar-nginx

Trabalhando na nova branch:

# Cria um arquivo de configuração fictício
mkdir config
echo "server { listen 80; }" > config/nginx.conf

git add config/nginx.conf
git commit -m "feat: adiciona configuração base do Nginx"

Neste momento, a branch main não tem esse arquivo. As mudanças existem apenas na branch feature/configurar-nginx.


Merge: Integrando o Trabalho

Quando o trabalho em uma branch está pronto, integra-se de volta à branch principal:

# Volta para a branch principal
git checkout main

# Integra as mudanças da feature branch
git merge feature/configurar-nginx

O Git tentará fazer o merge automaticamente. Se não houver conflitos, o resultado é um fast-forward (quando a branch principal não teve nenhum commit novo desde que a feature foi criada) ou um merge commit (quando ambas as branches avançaram).

Após o merge, a branch de feature pode ser removida:

git branch -d feature/configurar-nginx

Resolvendo Conflitos

Conflitos acontecem quando dois commits modificam a mesma linha do mesmo arquivo de formas diferentes. O Git não decide qual versão é a correta — ele marca o conflito e aguarda resolução manual.

O arquivo conflitante terá a seguinte aparência:

<<<<<<< HEAD
server { listen 80; server_name localhost; }
=======
server { listen 8080; }
>>>>>>> feature/porta-alternativa

A seção entre <<<<<<< HEAD e ======= é o conteúdo da branch atual. Entre ======= e >>>>>>> é o conteúdo da branch sendo integrada. Edita-se o arquivo manualmente, remove-se os marcadores e deixa-se o resultado desejado:

server { listen 80; server_name localhost; }

Depois:

git add config/nginx.conf
git commit -m "merge: resolve conflito de configuração de porta"

Desfazendo Coisas

Uma das maiores vantagens do Git é a capacidade de desfazer. As situações mais comuns:

# Desfaz mudanças não commitadas em um arquivo
git checkout -- arquivo.txt

# Remove um arquivo do stage (sem perder as mudanças)
git restore --staged arquivo.txt

# Desfaz o último commit, mantendo as mudanças no stage
git reset --soft HEAD~1

# Desfaz o último commit e descarta as mudanças — irreversível
git reset --hard HEAD~1

# Cria um novo commit que inverte um commit anterior (seguro para histórico compartilhado)
git revert abc1234

A diferença entre reset --hard e revert é fundamental: o reset reescreve o histórico — perigoso quando o código já foi enviado para um repositório remoto. O revert cria um novo commit de desfazimento, preservando o histórico intacto.


Conectando ao GitHub

# Adiciona o repositório remoto
git remote add origin https://github.com/usuario/meu-projeto.git

# Verifica os remotos configurados
git remote -v

# Envia a branch main para o repositório remoto
git push -u origin main

# Nos envios seguintes, basta
git push

# Baixa e integra as mudanças do remoto
git pull

Referências para Aprofundamento

Documentação oficial

Referência rápida

  • Git Cheat Sheet — GitHub Education — PDF com os comandos mais usados do Git. Útil nos primeiros meses até que os comandos se tornem automáticos.
  • Oh Shit, Git! — Guia direto em português para as situações em que algo deu errado e é preciso desfazer. Prático e bem-humorado.

Prática interativa

  • Learn Git Branching — Simulador visual e interativo de branches e merges no navegador. É o melhor recurso disponível para desenvolver intuição sobre o modelo de branches do Git.
  • GitHub Skills — Cursos práticos do próprio GitHub ensinando Git e GitHub com repositórios reais.
Comentários

Mais em DevOps

Geradores de Senhas Seguras: Implementações em 5 Linguagens de Programação
Geradores de Senhas Seguras: Implementações em 5 Linguagens de Programação

A geração de senhas fortes é um dos pilares da segurança da informação. Uma s...

Protegendo Branches e Revisando Código com Pull Requests
Protegendo Branches e Revisando Código com Pull Requests

Em equipes sem processo de revis&atilde;o, &eacute; comum encontrar c&oacute;...

O Terminal Não é o Inimigo
O Terminal Não é o Inimigo

Quando se fala para alunos que o primeiro m&ecirc;s inteiro ser&aacute; dedic...