Git do básico ao avançado
Um mapa prático para trabalhar com Git no mundo real: histórico, branches, remotes, worktrees, cherry-pick e manobras menos óbvias.
Git parece simples quando o caso é linear: editar, adicionar, commitar, dar push. O problema é que a vida real raramente é linear. Você muda de branch no meio do trabalho, precisa reaproveitar um commit isolado, quer publicar artefatos sem misturar código, ou precisa manter várias linhas de trabalho vivas ao mesmo tempo. É aí que o Git deixa de ser uma lista de comandos e passa a ser um sistema de modelagem de histórico.
O modelo mental que evita 80% da confusão
Antes de falar de comandos, vale fixar as camadas certas:
- Working tree: os arquivos como estão no disco agora.
- Index ou staging area: o que vai entrar no próximo commit.
- Commit: um snapshot versionado com pai(s), mensagem e metadados.
- Ref: um nome que aponta para um commit, como
main,HEADouorigin/main.
Cenários básicos que precisam ficar automáticos
O básico não é “iniciante”. O básico é o conjunto de movimentos que você executa sem pensar.
| Situação | Comando | Intenção real |
|---|---|---|
| Ver o estado atual | git status | descobrir em que camada a mudança está |
| Ver o diff do disco | git diff | o que mudou no working tree |
| Ver o diff staged | git diff --cached | o que vai para o próximo commit |
| Adicionar arquivo | git add arquivo | mover mudança para o index |
| Commitar | git commit -m "..." | criar snapshot local |
| Atualizar refs remotas | git fetch | baixar histórico sem misturar ainda |
| Enviar sua branch | git push -u origin minha-branch | publicar e criar upstream |
O comando mais importante aqui é, curiosamente, o git status. Quase todo erro operacional nasce de agir sem saber se a mudança está só no disco, staged, commitada ou já publicada.
Branches: o que são e como usá-las bem
Uma branch não é uma cópia do repositório. É só um ponteiro móvel para um commit. Isso parece detalhe, mas muda tudo: criar branch é barato, apagar branch é barato, experimentar é barato.
git switch main
git pull --ff-only
git switch -c feature/painel-filtros
# ... trabalho ...
git add .
git commit -m "feat: adiciona filtros no painel"
git push -u origin feature/painel-filtros
feature/, fix/, chore/, spike/ já resolvem muito. Branch com nome claro vira documentação operacional.
Merge, rebase e merge request: qual problema cada um resolve
Essas coisas costumam ser misturadas, mas resolvem problemas diferentes:
- Merge: combina duas linhas de histórico preservando o fato de que eram paralelas.
- Rebase: reescreve sua linha de commits como se ela tivesse nascido em outro ponto.
- Merge request / pull request: mecanismo social e de revisão, não operação de DAG em si.
Regra prática: use rebase para manter sua branch atualizada e limpa antes de revisão; use merge quando quiser preservar a estrutura real de integração ou quando o time prefere esse estilo; use MR/PR como ritual de revisão, CI e aprovação.
git fetch origin
git switch feature/painel-filtros
git rebase origin/main
git switch main
git merge --no-ff feature/painel-filtros
Cherry-pick: quando você quer só aquele commit
Cherry-pick é o instrumento certo quando você quer reaproveitar um commit específico sem trazer a branch inteira junto.
Casos clássicos:
- corrigir produção com um patch pequeno que nasceu em outra branch;
- copiar um commit de documentação sem misturar o resto da feature;
- backport de correção para release antiga.
git switch release/1.4
git cherry-pick a1b2c3d
A beleza do cherry-pick é a precisão. O risco é o contexto: às vezes aquele commit dependia de mudanças anteriores e, isolado, para de fazer sentido.
Worktrees: a forma elegante de viver em várias branches ao mesmo tempo
Muita gente ainda troca de branch dentro do mesmo diretório e vai fazendo stash para sobreviver. Funciona, mas é frágil. Worktree resolve isso melhor: múltiplas árvores de trabalho ligadas ao mesmo repositório Git.
git worktree add ../repo-feature-login -b feature/login origin/main
Isso cria um novo diretório, uma nova branch e uma nova working tree, sem duplicar o repositório inteiro. O objeto Git continua compartilhado; o que muda é a área de trabalho.
Quando worktree brilha:
- manter
mainaberta para hotfix e outra árvore para uma feature longa; - rodar testes de duas branches lado a lado;
- revisar PR sem desmontar seu trabalho atual;
- usar agentes ou automação paralela sem colisão de checkout.
git worktree list
git worktree remove ../repo-feature-login
Branches órfãs: quando você quer uma história nova sem herdar a velha
Branch órfã é uma branch que nasce sem pai no histórico visível daquela linha. Ela é útil quando você quer publicar conteúdo ou artefatos sem carregar o histórico principal junto.
Casos típicos:
gh-pagesou branch só de site estático;- branch de export, snapshot ou build;
- repositórios onde você quer manter código numa linha e documentação publicada em outra totalmente separada.
git switch --orphan gh-pages
git rm -rf .
# adiciona só os arquivos que devem viver nessa branch
A branch órfã é boa justamente porque impede que a história de build, artefato ou site fique acoplada à história do código-fonte. É uma separação conceitual, não só estética.
Remotes: mais do que origin
Remote é só um nome para um endpoint Git. origin é convenção, não regra. Entender isso libera fluxos mais sofisticados.
Exemplos de uso real:
- origin: seu fork;
- upstream: repositório principal do projeto;
- mirror: outro host, como GitLab além do GitHub;
- deploy: repo especial só para publicação.
git remote -v
git remote add upstream git@github.com:org/projeto.git
git remote set-url origin git@github.com:marinho/projeto.git
git remote rename origin github
Esse tipo de ajuste é valioso quando você muda de provedor, cria fork, passa de HTTPS para SSH ou quer espelhar o mesmo projeto em mais de um lugar.
git fetch upstream
git switch main
git rebase upstream/main
git push --force-with-lease origin main
O detalhe importante aqui é o --force-with-lease. Ele é o jeito civilizado de forçar push após rebase: protege contra sobrescrever trabalho remoto que você não viu.
Cenários complexos do mundo real
1. Hotfix no meio de uma feature longa
Você está no meio de uma feature cheia de mudanças locais, mas precisa corrigir produção agora. Em vez de stash frenético, use worktree ou branch limpa a partir de main.
git worktree add ../repo-hotfix -b hotfix/caddy-timeout origin/main
cd ../repo-hotfix
# corrige, testa, commit, push
2. Backport de correção sem trazer a feature inteira
A correção nasceu em main, mas a release antiga ainda precisa dela. Cherry-pick costuma ser a ferramenta certa.
git switch release/1.2
git cherry-pick a1b2c3d
3. Publicar artefato sem sujar a linha principal
Você quer separar claramente “fonte” e “publicado”. Branch órfã ajuda muito aqui.
git switch --orphan published-docs
git rm -rf .
cp -R build/* .
git add .
git commit -m "docs: publica versão atual"
4. Migrando de host ou mantendo espelho
Em vez de trocar tudo de uma vez, você pode operar com remotes paralelos e validar aos poucos.
git remote add gitlab git@gitlab.com:empresa/projeto.git
git push gitlab main
git push gitlab --tags
Comandos de inspeção que valem ouro
Uso avançado de Git depende menos de “decorar mutações” e mais de saber inspecionar bem.
git log --oneline --graph --decorate --allpara enxergar a topologia.git show <commit>para entender um commit isolado.git reflogpara achar referências recentes, inclusive depois de erro.git branch -vvpara ver tracking e último commit.git remote show originpara auditar o remote com mais contexto.
git reflog salva muita gente. Se você “perdeu” uma branch, resetou errado ou reescreveu histórico, muitas vezes o commit ainda está acessível pelo reflog.
Antipadrões que custam caro
- Usar stash como estratégia de vida. Stash serve para pausas pontuais, não como arquitetura de fluxo.
- Rebase cego em branch compartilhada. Reescrever histórico sem combinar com o time é receita para ruído.
- Forçar push com
--forcepor reflexo. Prefira--force-with-lease. - Não nomear branches semânticas. Branch ruim é custo cognitivo futuro.
- Ignorar worktrees. Muita dor de contexto paralelo some quando você passa a usá-las.
- Confundir PR/MR com integração técnica. PR é processo social; merge/rebase/cherry-pick são operações de histórico.
Uma receita prática para operar melhor
- Fixe o modelo mental: disco, index, commit, ref.
- Antes de agir, rode
git statuse saiba exatamente em que estado você está. - Use branch curta e nomeada para cada linha de trabalho.
- Use worktree quando houver paralelismo real.
- Use cherry-pick para reaproveitamento preciso, não para integrar tudo.
- Use branch órfã quando o histórico publicado precisa ser outro.
- Modele seus remotes conscientemente: fork, upstream, espelho, deploy.
Esta página é um estudo gerado em conversa com o Hermes e pode evoluir com novos exemplos, cenários de recuperação e fluxos específicos de GitHub, GitLab ou Forgejo.