O que é o Git?

Git e o sistema de controle de versão distribuído mais usado no mundo. Criado por Linus Torvalds em 2005, ele permite rastrear mudanças no código, colaborar em equipe e reverter erros com precisão. Neste guia você encontra todos os comandos essenciais com exemplos reais, para que servem e os riscos de cada um.

Convenção: <branch> = substitua pelo nome real. Comandos marcados com aviso são destrutivos ou irreversíveis.

1. git init

Inicializa um repositório Git novo na pasta atual. Cria o diretório .git/ que armazena todo o histórico.

# Inicializar na pasta atual
$ git init

# Inicializar com nome de pasta
$ git init meu-projeto

# Inicializar como repositório bare (para servidores)
$ git init --bare repo.git

Quando usar: ao começar um projeto novo do zero.
Cuidado: não inicializar dentro de outro repositório Git (causa repositórios aninhados).

2. git clone

Baixa um repositório remoto completo (histórico, branches, tags) para sua máquina.

# Clonar repositório
$ git clone https://GitHub.com/usuário/repo.git

# Clonar em pasta específica
$ git clone https://GitHub.com/usuário/repo.git minha-pasta

# Clonar apenas a branch principal (mais rápido em repos grandes)
$ git clone --single-branch --depth 1 https://GitHub.com/usuário/repo.git

Quando usar: ao começar a trabalhar em um projeto existente.
Cuidado: com --depth 1 você perde o histórico completo. Use apenas para builds/deploy, não para desenvolvimento.

3. git status

Mostra o estado atual do repositório: arquivos modificados, staged, não rastreados e branch atual.

$ git status

# Versão resumida
$ git status -s

Quando usar: antes de qualquer commit. E inofensivo, apenas le.
Dica: crie o hábito de rodar git status antes de qualquer outro comando.

4. git add

Adiciona arquivos a área de staging (índice), preparando-os para o próximo commit.

# Adicionar arquivo específico
$ git add arquivo.js

# Adicionar pasta inteira
$ git add src/

# Adicionar tudo no diretório atual
$ git add .

# Adicionar interativamente (escolhe trecho por trecho)
$ git add -p

Quando usar: após editar arquivos que você quer incluir no próximo commit.
Cuidado: git add . pode incluir acidentalmente arquivos sensíveis (.env, chaves privadas). Configure o .gitignore antes.

5. git commit

Salva o estado atual dos arquivos staged no histórico permanente do repositório.

# Commit com mensagem
$ git commit -m "feat: adiciona endpoint de login"

# Commit abrindo editor para mensagem longa
$ git commit

# Adicionar e commitar arquivos rastreados de uma vez
$ git commit -am "fix: corrige validação de email"

# Corrigir a mensagem do último commit (ANTES do push)
$ git commit --amend -m "nova mensagem"

Quando usar: ao terminar uma unidade lógica de trabalho: uma feature, um fix, uma refatoração.
Risco com --amend: reescreve o histórico. Use apenas antes de fazer push. Após o push, --amend causa conflito para outros colaboradores.

6. git push

Envia os commits locais para o repositório remoto.

# Push na branch atual
$ git push

# Push com upstream definido (primeira vez)
$ git push -u origin main

# Push em branch específica
$ git push origin feature/login

# Push de tags
$ git push origin --tags

Quando usar: após commits locais, para compartilhar com a equipe.
AVISO: nunca use --force em branches compartilhadas (main, develop). O force push reescreve o histórico remoto e pode apagar commits de colegas. Prefira --force-with-lease.

7. git pull

Baixa as mudanças do repositório remoto e integra com a branch local. E o equivalente a git fetch + git merge.

# Pull padrão (merge)
$ git pull

# Pull com rebase (histórico mais limpo)
$ git pull --rebase

# Pull de branch específica
$ git pull origin develop

Quando usar: antes de começar a trabalhar, para garantir que você tem as últimas mudanças.
Cuidado com conflitos: se você tem mudanças locais e o remoto também mudou, pode gerar conflitos de merge. Prefira commitar ou fazer stash antes do pull.

8. git fetch

Baixa as mudanças do remoto sem integrar com a branch local. Você ve o que mudou, mas não altera seu código.

# Fetch de todas as branches remotas
$ git fetch

# Fetch de uma origem específica
$ git fetch origin

# Ver o que mudou no remoto após o fetch
$ git log HEAD..origin/main --oneline

Quando usar: quando quiser ver o que mudou no repositório remoto sem afetar seu trabalho local. E o mais seguro dos três (fetch/pull/merge).

9. git branch

Gerência branches: lista, cria, renomeia e deleta.

# Listar branches locais
$ git branch

# Listar todas (locais + remotas)
$ git branch -a

# Criar branch nova
$ git branch feature/autenticação

# Renomear branch atual
$ git branch -m novo-nome

# Deletar branch (já mergeada)
$ git branch -d feature/login

# Forçar deleção (não mergeada)
$ git branch -D feature/teste

Quando usar: para isolar desenvolvimento de features, correções ou experimentos.
AVISO: -D deleta sem verificar merge. Perda permanente dos commits daquela branch se não tiver push.

10. git checkout

Troca de branch ou restaura arquivos. Comando histórico com múltiplas funções (substituído em parte por git switch e git restore).

# Trocar para branch existente
$ git checkout main

# Criar e trocar para nova branch
$ git checkout -b feature/novo-endpoint

# Restaurar arquivo para o último commit (descarta mudanças)
$ git checkout -- arquivo.js

# Trocar para commit específico (modo detached HEAD)
$ git checkout abc1234

Risco com -- arquivo: descarta permanentemente as mudanças não commitadas do arquivo. Sem aviso, sem desfazer.
Detached HEAD: commits feitos nesse estado são perdidos ao trocar de branch. Crie uma branch antes de commitar.

11. git switch e git restore (modernos)

Desde o Git 2.23, as funções de checkout foram separadas para maior clareza:

# Trocar de branch
$ git switch main
$ git switch -c feature/nova

# Restaurar arquivo (descarta mudanças não staged)
$ git restore arquivo.js

# Restaurar arquivo staged de volta para unstaged
$ git restore --staged arquivo.js

Prefira esses em projetos novos. São mais explícitos e menos propensos a erros de digitação perigosos.

12. git merge

Integra os commits de uma branch dentro de outra, criando um commit de merge.

# Mergear branch feature na branch atual
$ git merge feature/login

# Merge sem fast-forward (sempre cria commit de merge)
$ git merge --no-ff feature/login

# Abortar merge em caso de conflito
$ git merge --abort

Quando usar: para integrar features concluídas na branch principal.
Conflitos precisam ser resolvidos manualmente. Use git status para ver os arquivos em conflito, edite-os, rode git add e depois git commit.

13. git rebase

Reaplica commits de uma branch em cima de outra, reescrevendo o histórico para uma linha do tempo linear.

# Rebase da branch atual em cima de main
$ git rebase main

# Rebase interativo: reorganizar, juntar, editar commits
$ git rebase -i HEAD~3

# Abortar rebase em caso de problemas
$ git rebase --abort

# Continuar após resolver conflito
$ git rebase --continue

ATENÇÃO: NUNCA rebase em branches públicas/compartilhadas. Rebase reescreve IDs de commits. Quem tem a branch localmente terá conflitos impossíveis de resolver limpo. Use apenas em branches pessoais antes do merge.

14. git reset

Move o ponteiro HEAD para um commit anterior. Três modos com consequências bem diferentes:

# --soft: volta commits, mantem mudanças staged
$ git reset --soft HEAD~1

# --mixed (padrão): volta commits, mantem mudanças como unstaged
$ git reset HEAD~1

# --hard: volta commits E DESCARTA as mudanças
$ git reset --hard HEAD~1

# Desfazer staging de um arquivo
$ git reset HEAD arquivo.js

AVISO: --hard e destrutivo e irreversível. Todas as mudanças não commitadas somem. Se você fez push, reset em commits públicos causa problemas sérios para a equipe. Para desfazer commits já publicados, prefira git revert.

15. git revert

Cria um novo commit que desfaz as mudanças de um commit anterior, sem reescrever o histórico.

# Reverter o último commit
$ git revert HEAD

# Reverter commit específico
$ git revert abc1234

# Reverter sem abrir editor de mensagem
$ git revert --no-edit HEAD

Prefira revert ao reset em branches compartilhadas. Ele preserva o histórico e e seguro para equipes. O commit revertido ainda fica visível no log.

16. git stash

Salva temporariamente mudanças não commitadas em uma pilha, limpando o working directory.

# Salvar mudanças atuais no stash
$ git stash

# Salvar com descrição
$ git stash push -m "WIP: formulário de login"

# Listar todos os stashes
$ git stash list

# Aplicar o stash mais recente
$ git stash pop

# Aplicar stash específico sem remove-lo
$ git stash apply stash@{2}

# Deletar stash específico
$ git stash drop stash@{0}

Quando usar: precisa trocar de branch urgente mas tem trabalho em andamento.
Cuidado: stashes ficam apenas no repositório local. Trocar de máquina = perder o stash.

17. git diff

Mostra as diferenças entre versões, arquivos, branches ou commits.

# Ver mudanças não staged
$ git diff

# Ver mudanças staged (prontas para commit)
$ git diff --staged

# Comparar dois commits
$ git diff abc1234 def5678

# Comparar duas branches
$ git diff main..feature/login

# Diff de arquivo específico
$ git diff HEAD arquivo.js

Quando usar: antes de commitar, para revisar exatamente o que vai entrar no commit. Inofensivo, apenas le.

18. git log

Exibe o histórico de commits do repositório.

# Log padrão
$ git log

# Log compacto (uma linha por commit)
$ git log --oneline

# Log com grafo de branches
$ git log --oneline --graph --all

# Log dos últimos 5 commits
$ git log -5

# Log de arquivo específico
$ git log --oneline -- arquivo.js

# Buscar commits por autor
$ git log --author="Wallyson"

Quando usar: para entender o histórico, encontrar quando um bug foi introduzido ou verificar o trabalho da equipe. Inofensivo.

19. git remote

Gerência as conexões com repositórios remotos (GitHub, GitLab, etc.).

# Listar remotos
$ git remote -v

# Adicionar remoto
$ git remote add origin https://GitHub.com/usuário/repo.git

# Trocar URL do remoto
$ git remote set-url origin https://GitHub.com/usuário/novo-repo.git

# Remover remoto
$ git remote remove origin

Quando usar: ao configurar um novo repositório ou trocar de GitHub para GitLab.
Cuidado ao trocar URLs: um push acidental para o remoto errado pode expor código privado.

20. git config

Configura opcoes do Git: nome, email, editor, aliases e comportamentos.

# Configurar nome e email globais
$ git config --global user.name "Seu Nome"
$ git config --global user.email "[email protected]"

# Ver todas as configurações
$ git config --list

# Configurar editor padrão
$ git config --global core.editor "code --wait"

# Criar alias
$ git config --global alias.st status
$ git config --global alias.lg "log --oneline --graph"

# Configuração local (só para o projeto atual)
$ git config user.email "[email protected]"

Quando usar: ao configurar Git em uma máquina nova ou personalizar seu fluxo de trabalho.
Atenção ao email: o email nos commits fica público no GitHub.

21. git tag

Marca pontos específicos no histórico, geralmente versões de lançamento.

# Criar tag leve
$ git tag v1.0.0

# Criar tag anotada (com mensagem e autor)
$ git tag -a v1.0.0 -m "Versão 1.0.0: lançamento inicial"

# Listar todas as tags
$ git tag

# Enviar tag para o remoto
$ git push origin v1.0.0

# Deletar tag local
$ git tag -d v1.0.0

# Deletar tag remota
$ git push origin --delete v1.0.0

Quando usar: para marcar releases (v1.0, v2.3.1). Tags são imutáveis por convenção.

22. git cherry-pick

Aplica o patch de um commit específico na branch atual, sem trazer o restante da branch de origem.

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

# Aplicar múltiplos commits
$ git cherry-pick abc1234 def5678

# Aplicar sem criar commit (apenas staging)
$ git cherry-pick --no-commit abc1234

Quando usar: para pegar um hotfix feito em outra branch sem fazer merge completo.
Aviso: gera commits duplicados no histórico. Use com moderação.

23. git blame

Mostra quem alterou cada linha de um arquivo e em qual commit.

# Ver autor de cada linha
$ git blame arquivo.js

# Mostrar apenas linhas 10 a 20
$ git blame -L 10,20 arquivo.js

# Ignorar commits de formatação
$ git blame -w arquivo.js

Quando usar: para entender o contexto de uma linha de código. Inofensivo.
Dica cultural: use git blame para entender o código, não para culpar pessoas.

24. git bisect

Usa busca binária para encontrar qual commit introduziu um bug. Divide o histórico ao meio repetidamente até isolar o commit problemático.

# Iniciar bisect
$ git bisect start

# Marcar o commit atual como ruim
$ git bisect bad

# Marcar commit antigo como bom
$ git bisect good v1.2.0

# Git navega automaticamente: você testa e marca:
$ git bisect good
# ou
$ git bisect bad

# Após encontrar o commit culpado
$ git bisect reset

Quando usar: quando você sabe que algo funcionava antes mas parou e não sabe qual commit quebrou. Encontra o commit culpado em um histórico de 1000 commits em apenas 10 iterações.

25. git reflog

Mostra o histórico de todos os movimentos do HEAD, incluindo operações que apagam commits como reset e rebase.

$ git reflog

# Ver reflog de uma branch específica
$ git reflog show feature/login

# Recuperar commit perdido após reset --hard
$ git reset --hard abc1234  # hash visto no reflog

Quando usar: para recuperar trabalho após um reset --hard acidental. Os registros ficam disponíveis por 90 dias por padrão.

26. git show

Exibe detalhes de um commit: mensagem, autor, diff completo das mudanças.

# Ver último commit
$ git show

# Ver commit específico
$ git show abc1234

# Ver apenas o diff de um arquivo no commit
$ git show abc1234:src/arquivo.js

Quando usar: para revisar o que um commit específico alterou. Inofensivo.

27. git clean

Remove arquivos não rastreados (untracked) do diretório de trabalho.

# Simular o que seria removido (dry run - faca SEMPRE antes)
$ git clean -n

# Remover arquivos não rastreados
$ git clean -f

# Remover também pastas não rastreadas
$ git clean -fd

# Remover também arquivos ignorados (.gitignore)
$ git clean -fdx

AVISO: extremamente destrutivo e irreversível. Sempre rode git clean -n (dry run) antes do -f. Arquivos removidos NÃO vao para a lixeira.

28. git worktree

Permite ter múltiplas branches do repositório abertas ao mesmo tempo em pastas diferentes, sem clonar novamente.

# Criar worktree em outra pasta para outra branch
$ git worktree add ../repo-hotfix hotfix/bug-crítico

# Listar worktrees
$ git worktree list

# Remover worktree após terminar
$ git worktree remove ../repo-hotfix

Quando usar: quando precisa corrigir um bug urgente em produção enquanto ainda esta no meio de uma feature. Evita fazer stash e trocar de branch no mesmo diretório.

29. git submodule

Incorpora um repositório Git dentro de outro, útil para dependências que precisam ser versionadas separadamente.

# Adicionar submodulo
$ git submodule add https://GitHub.com/usuário/lib.git libs/lib

# Clonar repositório com submodulos
$ git clone --recurse-submodules https://GitHub.com/usuário/repo.git

# Atualizar submodulos
$ git submodule update --init --recursive

Aviso: submodulos são complexos de manter. Cada colaborador precisa lembrar de rodá-los ao clonar/atualizar. Considere alternativas como npm/pip para dependências simples.

30. git gc (Garbage Collection)

Otimiza o repositório: comprime objetos, remove dados orfaos e compacta o histórico.

# Executar coleta de lixo
$ git gc

# Limpeza mais agressiva
$ git gc --aggressive

Quando usar: raramente necessário. O Git roda gc automaticamente. Use se o repositório estiver muito grande ou lento.
Aviso: --aggressive pode demorar muito em repositórios grandes.

Tabela de Risco dos Comandos

ComandoO que fazReversível?Risco
git statusEstado atual-Nenhum
git addStage arquivosSim (restore)Baixo
git commitSalvar snapshotSim (revert)Baixo
git pushEnviar para remotoCom revertMédio
git pullBaixar e integrarSimMédio
git reset --softVoltar commits (mantem mudanças)Sim (reflog)Médio
git reset --hardVoltar commits e descartar tudoVia reflogALTO
git rebaseReescrever históricoVia reflogALTO
git clean -fDeletar arquivos não rastreadosNÃOCRÍTICO
git push --forceSobrescrever remotoVia reflog remotoCRÍTICO

Boas Práticas Essenciais

  • Commits atómicos: cada commit deve fazer uma coisa só
  • Mensagens descritivas: use o padrão Conventional Commits: feat:, fix:, docs:, refactor:
  • Nunca commitar segredos: senhas, tokens, chaves de API pertencem ao .gitignore
  • Branch por feature: crie branches separadas para cada funcionalidade ou correção
  • Pull antes de push: sempre atualize sua branch antes de enviar
  • Revise antes de commitar: git diff --staged antes de cada git commit