Git de verdade: commit, branch, merge, rebase, reflog
- ⬜🔑 SSH e chaves: como acessar máquinas remotas com segurança(Fundamentos Técnicos)
Recomendamos completar os pré-requisitos antes de seguir, mas nada te impede de continuar.
Git é o sistema de controle de versão mais usado do mundo — e também o mais mal-entendido. A maioria aprende os comandos sem entender o modelo mental subjacente. Quando você entende o que Git realmente armazena, tudo faz sentido: merge, rebase, reset, cherry-pick viram operações previsíveis.
O que Git realmente armazena: objetos e o DAG
Git não armazena diffs — armazena snapshots. Cada commit é uma foto completa do projeto naquele momento. Git é eficiente porque objetos idênticos (mesmo conteúdo → mesmo hash SHA-1) são armazenados apenas uma vez.
Existem 4 tipos de objetos no Git:
# Blob — conteúdo de um arquivo (sem nome, sem permissão) git cat-file -p a1b2c3 # mostra conteúdo de um blob # Tree — diretório (lista de blobs e outras trees com nomes e permissões) # 100644 blob a1b2c3 README.md # 100755 blob d4e5f6 script.sh # 040000 tree 789abc src/ # Commit — aponta para uma tree + metadados + referências ao(s) pai(s) # tree 789abc... # parent def012... ← SHA do commit anterior # author Fernando ... # committer Fernando ... # (linha em branco) # Mensagem do commit # Tag — aponta para um commit com anotação # O histórico é um DAG (Directed Acyclic Graph) de commits: # A ← B ← C ← D (main) # ↖ # E ← F (feature) # D e F são a mesma base C. Após merge: A ← B ← C ← D ← G # ↗ # E ← F
# Explorar os objetos internamente git log --oneline --graph --all # visualiza o DAG git cat-file -t SHA # tipo do objeto (blob/tree/commit/tag) git cat-file -p SHA # conteúdo do objeto ls .git/objects/ # os arquivos físicos no disco
As três áreas do Git
# Working Directory → Staging Area (Index) → Repository (.git/) # Estado das mudanças git status # resumo das três áreas git diff # working directory vs staging area git diff --staged # staging area vs último commit git diff HEAD # working directory vs último commit # Movendo mudanças para staging git add arquivo.txt # adiciona arquivo inteiro git add src/ # adiciona diretório git add -p # interativo: seleciona hunks (partes) a adicionar git add -A # todos os arquivos (novos, modificados, deletados) # Commit: salva staging no repositório git commit -m "feat: adiciona autenticação JWT" git commit --amend # modifica o ÚLTIMO commit (não use se já fez push) git commit -v # abre editor com o diff completo visível # Desfazendo staging (sem perder mudanças) git restore --staged arquivo.txt # retira do staging, mantém no working dir git reset HEAD arquivo.txt # equivalente (forma antiga) # Desfazendo mudanças no working directory (DESTRUTIVO) git restore arquivo.txt # descarta mudanças locais (irrecuperável) git checkout -- arquivo.txt # equivalente (forma antiga)
Branches: são só ponteiros para commits
Uma branch no Git é literalmente um arquivo de texto com 40 caracteres: o SHA do commit que ela aponta. Criar uma branch é instantâneo — não copia nada. HEAD é um ponteiro para a branch atual (ou diretamente para um commit, "detached HEAD state").
# Criar e navegar branches git branch feature/auth # cria branch no commit atual git checkout feature/auth # muda para ela git checkout -b feature/auth # cria E muda (atalho) git switch -c feature/auth # forma moderna (Git 2.23+) # Ver branches git branch # branches locais git branch -r # branches remotas git branch -a # todas git branch -v # com último commit de cada # Deletar branch git branch -d feature/auth # deleta se já mergeada git branch -D feature/auth # força delete (mesmo sem merge) # Renomear git branch -m nome-novo # renomeia branch atual git branch -m nome-velho nome-novo # Mudar de branch (com mudanças em andamento) git stash # salva mudanças temporariamente git switch outra-branch git stash pop # recupera as mudanças
Merge vs Rebase: qual escolher
| Aspecto | git merge | git rebase |
|---|---|---|
| Histórico | Preserva — cria commit de merge | Reescreve — commits novos com mesmos changes |
| Resultado | Commit com 2 pais (não-linear) | Histórico linear |
| Conflitos | Resolve uma vez no merge commit | Resolve em cada commit rebased |
| Seguro para push | Sempre | Somente para branches não compartilhadas |
| Quando usar | Integrar branches públicas (main) | Limpar histórico local antes do push |
# MERGE — preserva histórico real git checkout main git merge feature/auth # Cria: main → ... → merge-commit (tem dois pais: ultimo-main e ultimo-feature) # REBASE — reescreve o histórico da feature sobre main git checkout feature/auth git rebase main # Move commits da feature para após o último commit do main # Os commits da feature são NOVOS (SHAs diferentes), mas com os mesmos changes # MERGE SQUASH — todos os commits da feature viram 1 commit só em main git checkout main git merge --squash feature/auth git commit -m "feat: autenticação JWT (squash de 5 commits)" # Útil para manter main com histórico limpo # INTERACTIVE REBASE — editar, reordenar, squash, fixup commits git rebase -i HEAD~5 # edita últimos 5 commits # pick SHA1 commit 1 → manter # squash SHA2 commit 2 → juntar com anterior # fixup SHA3 commit 3 → juntar sem preservar mensagem # reword SHA4 commit 4 → mudar mensagem # drop SHA5 commit 5 → deletar
Reflog: a rede de segurança do Git
O reflog registra para onde HEAD aponta a cada operação. É local (não vai para o remote) e mantém objetos por ~90 dias. É o que salva quando você faz reset --hard acidentalmente.
# Ver o reflog
git reflog # últimas ~100 entradas do HEAD
git reflog show main # reflog de uma branch específica
# Saída típica:
# abc1234 HEAD@{0}: reset: moving to HEAD~3
# def5678 HEAD@{1}: commit: feat: adiciona login
# ghi9012 HEAD@{2}: commit: fix: corrige validação
# jkl3456 HEAD@{3}: checkout: moving from main to feature/auth
# RECUPERAR após reset --hard acidental
git reflog # encontra SHA antes do reset
git reset --hard def5678 # volta para lá
# ou: criar nova branch naquele ponto
git checkout -b recuperado def5678
# RECUPERAR commit que nunca foi commitado em nenhuma branch
git fsck --lost-found # lista dangling objects
ls .git/lost-found/ # blobs e commits "perdidos"git stash também aparece no reflog como stash@0. Se fizer git stash drop por acidente, git stash show stash@0 e git stash apply stash@0 podem recuperar se o objeto ainda não foi coletado.Operações avançadas do dia-a-dia
# cherry-pick: aplicar um commit específico em outra branch
git checkout main
git cherry-pick abc1234 # aplica as mudanças desse commit em main
# Desfazer um commit de forma segura (não-destrutivo)
git revert abc1234 # cria um novo commit que desfaz as mudanças
# Bisect: encontra qual commit introduziu um bug (busca binária)
git bisect start
git bisect bad # commit atual tem o bug
git bisect good v2.1.0 # esta versão estava OK
# Git faz checkout automático de commits intermediários
# Você testa e informa: git bisect good / git bisect bad
git bisect reset # termina
# Tags: marcar releases
git tag v1.0.0 # tag leve (só aponta para commit)
git tag -a v1.0.0 -m "Release 1.0.0" # tag anotada (com metadados)
git push origin v1.0.0 # tags não sobem com push padrão
git push origin --tags # sobe todas as tags
# Stash avançado
git stash push -m "WIP: auth endpoint" # com nome
git stash list # lista todos os stashes
git stash apply stash@{2} # aplica sem remover da lista
git stash pop # aplica e removeQuiz rápido
3 perguntas · Acerte tudo e ganhe o badge 🎯 Gabarito