FLUXOS DE TRABALHO AVANCADOS NO GIT Rebase Squash Reword rebase -i Bisect Busca Binaria Caca de Bugs bisect good/bad Hooks pre-commit commit-msg .git/hooks/ Reflog Recuperacao Desfazer Erros reflog expire Worktree Dev Paralelo Multi-branch worktree add git rebase | git bisect | git hooks | git reflog | git worktree Domine os comandos avancados do Git para fluxos de trabalho profissionais

A maioria dos desenvolvedores aprende git add, git commit e git push — e depois para por ai. Mas o Git e uma ferramenta extraordinariamente poderosa com comandos que podem economizar horas de trabalho, ajudar a rastrear bugs em segundos, automatizar a aplicacao de qualidade de codigo e recuperar-se de erros que de outra forma seriam catastroficos. Este guia cobre os fluxos de trabalho avancados do Git que separam usuarios cotidianos de usuarios avancados: rebase interativo, bisect, hooks, recuperacao com reflog, cherry-pick, worktrees e mais.

Para quem e isso: Este artigo assume que voce esta confortavel com as operacoes basicas do Git (commit, push, pull, branch, merge). Se ainda esta aprendendo esses fundamentos, comece por la primeiro e volte quando estiver pronto para subir de nivel.

Pre-requisitos

Antes de mergulhar nos fluxos de trabalho avancados, certifique-se de ter:

  • Git 2.23 ou posterior instalado (execute git --version para verificar)
  • Um repositorio com pelo menos 20-30 commits para praticar
  • Familiaridade com branching e merging basico
  • Um terminal com o qual voce esteja confortavel (Bash, Zsh, PowerShell)
# Verificar sua versao do Git
git --version

# Atualizar Git no Ubuntu/Debian
sudo apt update && sudo apt install git

# Atualizar Git no macOS
brew upgrade git

Dica: Crie um repositorio descartavel para praticar esses comandos. Muitos deles reescrevem o historico, e voce quer ganhar confianca antes de usa-los em codigo de producao.

Rebase Interativo

O rebase interativo e provavelmente a ferramenta de edicao de commits mais poderosa do Git. Permite reescrever, combinar, reordenar e excluir commits antes de fazer push para uma branch compartilhada.

Iniciando um Rebase Interativo

Para modificar os ultimos 5 commits:

git rebase -i HEAD~5

Isso abre seu editor com uma lista de commits, do mais antigo ao mais recente:

pick a1b2c3d Add user authentication
pick e4f5g6h Fix typo in login form
pick i7j8k9l Add password reset feature
pick m0n1o2p Fix lint errors
pick q3r4s5t Update README

Comandos de Rebase

Cada linha de commit comeca com um comando. Os mais uteis sao:

  • pick — Manter o commit como esta
  • reword — Manter o commit mas alterar a mensagem
  • squash — Combinar este commit com o anterior (mantem ambas as mensagens)
  • fixup — Combinar com o commit anterior (descarta a mensagem deste commit)
  • edit — Pausar o rebase neste commit para poder emenda-lo
  • drop — Remover este commit completamente

Combinando Commits (Squash)

O uso mais comum do rebase interativo e combinar multiplos commits pequenos em um significativo:

pick a1b2c3d Add user authentication
fixup e4f5g6h Fix typo in login form
pick i7j8k9l Add password reset feature
fixup m0n1o2p Fix lint errors
drop q3r4s5t Update README

Isso produz dois commits limpos em vez de cinco desorganizados.

Reordenando Commits

Simplesmente reorganize as linhas no seu editor para mudar a ordem dos commits:

pick i7j8k9l Add password reset feature
pick a1b2c3d Add user authentication

Aviso: Nunca faca rebase de commits que ja foram enviados para uma branch compartilhada. Reescrever historico compartilhado causa conflitos para todos na sua equipe. Apenas faca rebase dos seus commits locais nao enviados.

Autosquash com Commits de Correcao

Se voce sabe que um commit e uma correcao para um anterior, marque-o no momento do commit:

# Criar um commit fixup que se auto-combina com o commit alvo
git commit --fixup=a1b2c3d

# Depois, autosquash durante o rebase
git rebase -i --autosquash HEAD~10

O Git automaticamente reordena os commits fixup ao lado dos seus alvos e os marca com fixup.

Git Bisect: Busca Binaria para Bugs

Quando um bug aparece e voce nao sabe qual commit o introduziu, testar cada commit um por um e impraticavel. git bisect realiza uma busca binaria, encontrando o commit exato em O(log n) passos.

Bisect Manual

# Iniciar a biseccao
git bisect start

# Marcar o commit atual como ruim (tem o bug)
git bisect bad

# Marcar um commit bom conhecido (antes do bug existir)
git bisect good v2.0.0

# Git faz checkout do ponto medio -- teste-o
# Se este commit tem o bug:
git bisect bad

# Se este commit nao tem o bug:
git bisect good

# Repetir ate que o Git identifique o primeiro commit ruim
# Quando terminar:
git bisect reset

Para um intervalo de 1.024 commits, o bisect encontra o culpado em aproximadamente 10 passos.

Bisect Automatizado com um Script

Se voce tem um script de teste que retorna codigo de saida 0 para bom e diferente de zero para ruim:

git bisect start
git bisect bad HEAD
git bisect good v2.0.0

# Executar o teste automaticamente em cada passo
git bisect run ./test-script.sh

# Ou usar um comando de teste especifico
git bisect run npm test -- --grep "login feature"

O Git executa o script em cada ponto medio e identifica o commit culpado sem nenhuma intervencao manual.

Bisect com Criterios Complexos

# Pular commits que nao podem ser testados (ex., build quebrado)
git bisect skip

# Ver o log do bisect
git bisect log

# Reproduzir uma sessao de bisect a partir de um arquivo de log
git bisect replay bisect-log.txt

Estrategias de Cherry-Pick

Cherry-pick aplica um commit especifico de uma branch para outra sem fazer merge da branch inteira. E util para hotfixes, backporting e integracao seletiva de funcionalidades.

Cherry-Pick Basico

# Aplicar um unico commit na sua branch atual
git cherry-pick abc1234

# Aplicar multiplos commits
git cherry-pick abc1234 def5678 ghi9012

# Aplicar um intervalo de commits (excluindo o primeiro)
git cherry-pick abc1234..ghi9012

Cherry-Pick Sem Fazer Commit

# Preparar as mudancas mas nao fazer commit (util para combinar multiplos picks)
git cherry-pick --no-commit abc1234
git cherry-pick --no-commit def5678

# Revisar as mudancas combinadas, depois fazer commit
git commit -m "Backport: authentication fixes from develop"

Lidando com Conflitos de Cherry-Pick

# Se um conflito ocorrer durante o cherry-pick:
# 1. Resolver os conflitos nos arquivos afetados
# 2. Adicionar os arquivos resolvidos ao staging
git add resolved-file.js

# 3. Continuar o cherry-pick
git cherry-pick --continue

# Ou abortar todo o cherry-pick
git cherry-pick --abort

Cherry-Pick para Hotfixes

Um padrao comum para hotfixes em producao:

# Na branch main, corrigir o bug
git checkout main
git checkout -b hotfix/login-crash

# Fazer a correcao e commit
git commit -am "Fix: prevent null pointer in login handler"

# Fazer merge para main
git checkout main
git merge hotfix/login-crash

# Cherry-pick a correcao para a branch develop
git checkout develop
git cherry-pick <hotfix-commit-sha>

Git Hooks

Os Git hooks sao scripts que executam automaticamente em pontos especificos do ciclo de vida do Git. Aplicam qualidade de codigo, validam mensagens de commit e previnem que codigo defeituoso entre no repositorio.

Tipos de Hooks e Localizacoes

Os hooks ficam em .git/hooks/. Os hooks mais utilizados sao:

HookGatilhoUso Comum
pre-commitAntes de um commit ser criadoLinting, formatacao, testes
commit-msgApos a mensagem de commit ser digitadaValidar formato da mensagem
pre-pushAntes de fazer push para um remotoExecutar suite completa de testes
post-mergeApos um merge ser concluidoInstalar dependencias
pre-rebaseAntes de um rebase iniciarPrevenir rebase em branches compartilhadas

Hook Pre-Commit: Linting

#!/bin/sh
# .git/hooks/pre-commit

# Executar ESLint em arquivos JavaScript preparados
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.js$')

if [ -n "$STAGED_FILES" ]; then
    echo "Running ESLint on staged files..."
    npx eslint $STAGED_FILES
    if [ $? -ne 0 ]; then
        echo "ESLint failed. Fix errors before committing."
        exit 1
    fi
fi

# Executar verificacao do Prettier
STAGED_ALL=$(git diff --cached --name-only --diff-filter=ACM)
if [ -n "$STAGED_ALL" ]; then
    npx prettier --check $STAGED_ALL
    if [ $? -ne 0 ]; then
        echo "Prettier check failed. Run 'npx prettier --write .' first."
        exit 1
    fi
fi

exit 0

Hook Commit-Msg: Conventional Commits

#!/bin/sh
# .git/hooks/commit-msg

COMMIT_MSG_FILE=$1
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")

# Aplicar formato Conventional Commits
PATTERN="^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?: .{1,72}"

if ! echo "$COMMIT_MSG" | grep -qE "$PATTERN"; then
    echo "ERROR: Commit message does not follow Conventional Commits format."
    echo ""
    echo "Expected: <type>(<scope>): <description>"
    echo "Example:  feat(auth): add password reset endpoint"
    echo ""
    echo "Valid types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert"
    exit 1
fi

exit 0

Hook Pre-Push: Suite de Testes

#!/bin/sh
# .git/hooks/pre-push

echo "Running test suite before push..."
npm test

if [ $? -ne 0 ]; then
    echo "Tests failed. Push aborted."
    echo "Fix failing tests before pushing."
    exit 1
fi

echo "All tests passed. Pushing..."
exit 0

Compartilhando Hooks com Sua Equipe

Os hooks em .git/hooks/ nao sao rastreados pelo Git. Para compartilha-los:

# Opcao 1: Armazenar hooks em um diretorio rastreado
mkdir -p .githooks
cp .git/hooks/pre-commit .githooks/

# Configurar o Git para usar o diretorio rastreado
git config core.hooksPath .githooks

# Opcao 2: Usar Husky (projetos Node.js)
npx husky install
npx husky add .husky/pre-commit "npx lint-staged"

Git Reflog e Recuperacao

O reflog e sua rede de seguranca. Registra cada mudanca no HEAD — commits, rebases, resets, checkouts — por pelo menos 30 dias. Se voce perder commits, o reflog e como voce os recupera.

Visualizando o Reflog

# Ver o reflog
git reflog

# A saida se parece com:
# a1b2c3d HEAD@{0}: commit: Add new feature
# e4f5g6h HEAD@{1}: rebase -i (finish): returning to refs/heads/main
# i7j8k9l HEAD@{2}: rebase -i (squash): Add user auth
# m0n1o2p HEAD@{3}: reset: moving to HEAD~3

Recuperando Apos um Reset Incorreto

# Voce acidentalmente executou git reset --hard HEAD~3 e perdeu 3 commits
# Passo 1: Encontrar o commit perdido no reflog
git reflog

# Passo 2: O commit antes do reset esta em HEAD@{1}
git checkout HEAD@{1}

# Passo 3: Criar uma branch para salva-lo
git checkout -b trabalho-recuperado

# Ou fazer cherry-pick de commits especificos de volta
git cherry-pick a1b2c3d

Recuperando Apos um Rebase Incorreto

# Se um rebase deu errado, encontrar o estado antes do rebase
git reflog

# Procurar a entrada logo antes de "rebase -i (start)"
# Resetar para esse ponto
git reset --hard HEAD@{5}

Recuperando Branches Excluidas

# Voce excluiu uma branch com trabalho importante
git branch -D feature/trabalho-importante

# Encontrar a ponta da branch no reflog
git reflog | grep "trabalho-importante"

# Recriar a branch no SHA encontrado
git branch feature/trabalho-importante abc1234

Importante: As entradas do reflog expiram apos 90 dias (30 dias para commits inalcancaveis). Se voce descobrir trabalho perdido, recupere-o o mais rapido possivel. Voce pode configurar a expiracao com git config gc.reflogExpire.

Git Worktree: Desenvolvimento Paralelo

Os worktrees permitem ter multiplas branches abertas simultaneamente em diretorios separados. Sem mais stashing, committing ou troca de branches para revisar um pull request ou corrigir um hotfix.

Criando um Worktree

# Fazer checkout de uma branch em um novo diretorio
git worktree add ../hotfix-branch hotfix/login-fix

# Criar uma nova branch em um worktree
git worktree add -b feature/new-api ../new-api-work

# Listar todos os worktrees
git worktree list

Fluxo de Trabalho Pratico com Worktrees

# Seu diretorio principal de trabalho tem develop em checkout
# Um bug de producao aparece -- trabalhe nele sem interromper seu trabalho atual

git worktree add ../prod-fix main
cd ../prod-fix

# Corrigir o bug em uma nova branch
git checkout -b hotfix/critical-fix
# ... fazer mudancas, commit, push ...

# Retornar ao seu trabalho de funcionalidade
cd ../my-project
# develop esta exatamente onde voce o deixou

# Limpar quando terminar
git worktree remove ../prod-fix

Worktree para Revisao de Codigo

# Revisar o PR de um colega sem sair da sua branch atual
git fetch origin
git worktree add ../review-pr-42 origin/feature/user-dashboard

# Abrir o worktree no seu editor, revisar o codigo
# Quando terminar:
git worktree remove ../review-pr-42

Uso Avancado do Stash

Alem do basico git stash, ha opcoes poderosas para gerenciar mudancas em andamento.

Stashes com Nome

# Stash com uma mensagem descritiva
git stash push -m "WIP: refactoring auth middleware"

# Listar todos os stashes
git stash list
# stash@{0}: On develop: WIP: refactoring auth middleware
# stash@{1}: On develop: WIP: database migration script

Stash Parcial

# Fazer stash apenas de arquivos especificos
git stash push -m "stash auth changes" src/auth.js src/middleware.js

# Stash interativo -- escolher hunks individuais
git stash push -p -m "partial stash"

Stash Apply vs. Pop

# Apply mantem o stash na lista (seguro para tentar novamente)
git stash apply stash@{0}

# Pop aplica e remove o stash da lista
git stash pop stash@{0}

# Aplicar stash em uma branch diferente
git checkout feature/outra-branch
git stash apply stash@{0}

Criar uma Branch a Partir de um Stash

# Criar uma nova branch e aplicar o stash nela
git stash branch nova-branch-feature stash@{0}

Isso e particularmente util quando o stash tem conflitos com as mudancas na branch atual.

Git Blame e Forense de Log

Quando voce precisa entender por que uma linha de codigo existe ou rastrear quando uma mudanca foi introduzida, as ferramentas de forense do Git sao indispensaveis.

Git Blame

# Ver quem modificou cada linha por ultimo
git blame src/auth.js

# Blame de um intervalo de linhas especifico
git blame -L 10,20 src/auth.js

# Ignorar mudancas de espacos em branco
git blame -w src/auth.js

# Mostrar o commit que moveu ou copiou a linha de outro arquivo
git blame -C src/auth.js

Buscas Avancadas de Log

# Buscar em mensagens de commit por uma palavra-chave
git log --grep="authentication" --oneline

# Buscar mudancas em uma funcao especifica
git log -p -S "function loginUser" -- src/

# Buscar mudancas que correspondam a uma regex
git log -p -G "TODO|FIXME|HACK"

# Ver historico de um arquivo especifico
git log --follow --oneline -- src/auth.js

# Mostrar commits de um autor especifico em um intervalo de datas
git log --author="JC" --after="2025-01-01" --before="2025-12-31" --oneline

Formatos Visuais de Log

# Grafico compacto de branches
git log --oneline --graph --all --decorate

# Formato personalizado com data e autor
git log --pretty=format:"%h %ad | %s%d [%an]" --date=short

# Mostrar estatisticas por commit
git log --stat --oneline -10

Estrategias de Branching

Escolher a estrategia de branching correta afeta a velocidade e qualidade de codigo da sua equipe.

Git Flow

Git Flow usa branches de longa duracao para diferentes estagios:

# Branches principais
main        # Codigo pronto para producao
develop     # Branch de integracao para funcionalidades

# Branches de suporte
feature/*   # Novas funcionalidades (branch a partir de develop)
release/*   # Preparacao de lancamento (branch a partir de develop)
hotfix/*    # Correcoes de producao (branch a partir de main)
# Iniciar uma funcionalidade
git checkout develop
git checkout -b feature/user-dashboard

# Finalizar uma funcionalidade
git checkout develop
git merge --no-ff feature/user-dashboard
git branch -d feature/user-dashboard

Ideal para: Equipes com lancamentos programados e multiplos ambientes.

GitHub Flow

Uma alternativa mais simples com uma regra: tudo que esta em main e implantavel.

# Criar uma branch a partir de main
git checkout main
git checkout -b feature/add-search

# Trabalhar, fazer commit, push
git push -u origin feature/add-search

# Abrir um Pull Request, obter revisao, fazer merge para main
# O deploy acontece automaticamente a partir de main

Ideal para: Equipes que praticam deploy continuo com branches de curta duracao.

Desenvolvimento Baseado em Trunk

Todos os desenvolvedores fazem commit no main (o trunk) frequentemente, usando branches de funcionalidade de curta duracao de um a dois dias no maximo.

# Branch de curta duracao (1-2 dias maximo)
git checkout -b feature/small-change
# ... mudancas minimas ...
git push -u origin feature/small-change
# Fazer merge para main rapidamente via PR

# Feature flags controlam funcionalidades nao lancadas
if (featureFlags.newDashboard) {
    renderNewDashboard();
}

Ideal para: Equipes de alta velocidade com pipelines CI/CD solidos e infraestrutura de feature flags.

Tabela de Referencia de Comandos Avancados do Git

ComandoDescricaoExemplo
git rebase -i HEAD~NRebase interativo para os ultimos N commitsgit rebase -i HEAD~5
git bisect startIniciar busca binaria para bugsgit bisect start
git bisect run <script>Bisect automatizado com um script de testegit bisect run npm test
git cherry-pick <SHA>Aplicar um commit especifico na branch atualgit cherry-pick a1b2c3d
git cherry-pick --no-commitCherry-pick sem auto-commitgit cherry-pick --no-commit a1b2c3d
git reflogMostrar historico de movimentos do HEADgit reflog
git worktree add <caminho> <branch>Fazer checkout de uma branch em um diretorio separadogit worktree add ../fix main
git stash push -m "msg"Guardar mudancas com uma mensagem descritivagit stash push -m "WIP auth"
git stash push -pStash interativo de hunks selecionadosgit stash push -p
git blame -L 10,20 <arquivo>Blame de um intervalo de linhas especificogit blame -L 10,20 auth.js
git log -S "string"Encontrar commits que adicionam/removem uma stringgit log -S "loginUser"
git log -G "regex"Encontrar commits que correspondam a uma regexgit log -G "TODO|FIXME"
git commit --fixup=<SHA>Criar um commit fixup para autosquashgit commit --fixup=a1b2c3d
git config core.hooksPathDefinir um diretorio de hooks personalizadogit config core.hooksPath .githooks

Solucao de Problemas

Conflitos de Rebase Nao Se Resolvem

# Se um rebase tem conflitos demais, abortar e tentar outra abordagem
git rebase --abort

# Alternativa: usar merge em vez de rebase para historicos complexos
git merge develop

Bisect Da Resultados Incorretos

# Se voce marcou um commit incorretamente, ver o log e reproduzir
git bisect log > bisect-log.txt
# Editar o arquivo de log para remover a entrada incorreta
git bisect reset
git bisect replay bisect-log.txt

Scripts de Hook Nao Executam

# Garantir que o arquivo de hook seja executavel
chmod +x .git/hooks/pre-commit

# Verificar que a linha shebang esteja correta
head -1 .git/hooks/pre-commit
# Deveria ser: #!/bin/sh ou #!/bin/bash

# Verificar se core.hooksPath sobrescreve a localizacao padrao
git config --get core.hooksPath

Nao Consegue Excluir um Worktree

# Forcar a remocao de um worktree com mudancas nao commitadas
git worktree remove --force ../old-worktree

# Limpar entradas de worktree obsoletas
git worktree prune

Entrada de Reflog Nao Encontrada

# Aumentar o tempo de expiracao do reflog antes que seja tarde demais
git config gc.reflogExpire 180.days
git config gc.reflogExpireUnreachable 90.days

# Se o reflog estiver vazio, tentar fsck para encontrar commits pendentes
git fsck --unreachable --no-reflogs

Cherry-Pick Resulta em um Commit Vazio

# As mudancas ja existem na branch destino
# Usar --allow-empty para manter o commit, ou pula-lo
git cherry-pick --skip

# Ou verificar se a mudanca ja foi aplicada
git log --oneline --all -- path/to/changed/file

Resumo

Os fluxos de trabalho avancados do Git transformam a forma como voce gerencia codigo. O rebase interativo mantem seu historico de commits limpo e significativo. Git bisect transforma uma busca manual por bugs em uma busca binaria automatizada. Os Git hooks aplicam padroes de qualidade de codigo antes que codigo defeituoso entre no repositorio. O reflog atua como sua rede de seguranca, tornando virtualmente cada erro do Git recuperavel. Cherry-pick e worktrees proporcionam a flexibilidade para trabalhar entre branches sem interrupcoes.

A chave e a pratica. Crie um repositorio de teste, faca dezenas de commits e experimente cada comando deste guia. Uma vez que essas ferramentas se tornem naturais, voce lidara com situacoes complexas do Git com confianca.

Para automatizar seus pipelines de testes e deploy apos dominar esses fluxos de trabalho do Git, leia nosso guia sobre Primeiros Passos com GitHub Actions para CI/CD.