Garden

Principais comandos do Git

Um guia mais direto sobre os comandos do Git que eu mais uso no dia a dia.

GitWorkflowBase

O que é Git

Git é um sistema de versionamento.

Na prática, ele serve para registrar mudanças no código ao longo do tempo.

É como se ele fosse um histórico do projeto com superpoderes:

  • mostra o que mudou
  • permite voltar atrás
  • deixa várias pessoas trabalharem no mesmo projeto
  • ajuda a organizar experimentos sem bagunçar a base principal

Se eu fosse resumir em uma frase:

Git é a ferramenta que ajuda você a não se perder no próprio projeto.

Como o Git funciona por baixo dos panos

O jeito mais simples de entender Git é pensar em fotos do projeto.

Cada commit é como uma foto do estado dos arquivos naquele momento.

Não é exatamente uma “foto” literal, mas essa metáfora ajuda bastante.

Commit

Quando você faz um commit, o Git salva um novo ponto no histórico.

Exemplo:

commit A -> commit B -> commit C

Cada commit aponta para o commit anterior.

Um detalhe importante aqui:

o Git não sai recriando todos os arquivos do projeto do zero toda vez que você faz um commit.

O jeito mais correto de pensar é que cada commit aponta para o estado do projeto naquele momento.

Se um arquivo não mudou, o Git pode reaproveitar a referência para o conteúdo que já existia antes, em vez de duplicar tudo de novo.

Se o arquivo mudou, aí sim o Git registra esse novo estado.

Por isso, para aprender Git, faz mais sentido pensar em snapshots com reaproveitamento de referências.

Branch

Uma branch é como uma etiqueta apontando para um commit.

Exemplo:

main -> commit C

Se você cria uma nova branch a partir daí:

main -> commit C
feature/login -> commit C

As duas começam no mesmo ponto, mas depois podem seguir caminhos diferentes.

HEAD

HEAD é um ponteiro especial que normalmente indica em qual branch você está agora.

Exemplo:

HEAD -> feature/login
feature/login -> commit C
main -> commit C

Se você fizer um novo commit nessa branch:

HEAD -> feature/login
feature/login -> commit D
main -> commit C

Ou seja:

  • o HEAD aponta para a branch atual
  • a branch atual aponta para o commit mais recente daquela linha

Working tree, stage e commit

No dia a dia, eu gosto de pensar em 3 camadas:

  1. working tree
  2. staging area
  3. commit

Working tree

É o que você está editando no projeto agora.

Staging area

É a “área de preparação”.

Quando você roda git add, está dizendo:

“essas mudanças aqui eu quero colocar no próximo commit”

Commit

É o registro final no histórico.

Então o fluxo mais comum é:

git add .
git commit -m "feat: adiciona login"

Um fluxo mental simples

No meu dia a dia, eu penso mais ou menos assim:

  1. alterei arquivos
  2. vejo o que mudou com git status ou git diff
  3. escolho o que vai entrar com git add
  4. salvo no histórico com git commit
  5. envio para o remoto com git push

Principais comandos

git init

Cria um repositório Git naquele projeto.

git init

Use quando o projeto ainda não está versionado.

git status

Mostra o estado atual do repositório.

git status

É um dos comandos que mais vale decorar, porque ele responde:

  • quais arquivos mudaram
  • o que está staged
  • o que ainda não está staged
  • em qual branch você está

git add

Adiciona mudanças para a staging area.

git add .

Ou, para adicionar tudo no projeto:

git add -A

Importante:

git add não manda para stash e não cria commit.

Ele só prepara as mudanças para o próximo commit.

git commit -m

Cria um commit com uma mensagem.

git commit -m "feat: adiciona tela de login"

É aqui que você salva um novo ponto no histórico.

git branch

Mostra as branches locais.

git branch

Também pode ser usado para criar branch, mas no dia a dia eu costumo preferir checkout -b.

git checkout -b nova-branch

Cria e já entra numa nova branch.

git checkout -b feature/login

Outra forma de fazer a mesma coisa é:

git switch -c feature/login

Os dois resolvem bem esse cenário.

git fetch

Atualiza suas referências locais com base no remoto.

git fetch

Pensa assim:

“traz as novidades do remoto, mas sem mexer ainda na minha branch atual”

Ele não mergeia automaticamente suas mudanças locais.

git pull

Atualiza sua branch local trazendo mudanças do remoto.

git pull

De forma simplificada, costuma ser algo próximo de:

git fetch + git merge

Dependendo da configuração do projeto, ele também pode usar rebase.

git push

Envia seus commits para o remoto.

git push

Ou explicitando origem e branch:

git push origin minha-branch

Se quiser criar uma relação de rastreamento entre a branch local e a branch remota, pode usar -u ou --set-upstream.

git push -u origin minha-branch

Depois disso, você pode usar apenas:

git push
git pull

E o Git já saberá qual branch remota essa branch local acompanha.

git diff

Mostra diferenças entre versões de arquivos.

git diff

Sem flags, ele normalmente mostra o que mudou antes do stage.

Também existem usos como:

git diff --staged
git diff main

Então esse é um comando bem mais flexível do que parece no começo.

git log

Mostra o histórico de commits.

git log

Quando quero ler de forma mais enxuta, costumo usar variantes como:

git log --oneline

git stash push

Guarda mudanças sem precisar criar commit.

git stash push -u -m "ajustes no formulário"

Isso é útil quando:

  • você precisa trocar de branch rápido
  • ainda não quer commitar
  • quer limpar a área de trabalho temporariamente

git stash list

Lista os stashes salvos.

git stash list

git stash pop

Traz de volta o stash e remove ele da pilha.

git stash pop

Ou um stash específico passando referência(posição):

git stash pop stash@{0}

Exemplo:

# Cria um stash
git stash push -m "ajuste login"

# Cria outro stash
git stash push -m "corrige modal"

# Lista os stash
git stash list

# o que será exibido:
stash@{0}: On feature/login: corrige modal
stash@{1}: On feature/login: ajuste login

git cherry-pick

Traz um commit específico para sua branch atual.

git cherry-pick hash-do-commit

Isso é ótimo quando você quer aproveitar uma mudança específica sem trazer o resto da branch.

git commit --amend

Altera o commit mais recente.

git commit --amend

Eu costumo usar principalmente quando esqueci de incluir um arquivo.

Se esse commit já foi enviado para o remoto, tome cuidado.

Nesse caso, normalmente você vai precisar de um novo push reescrevendo histórico.

git reset --soft HEAD~1

Volta um commit, mas mantém as mudanças prontas para você reorganizar.

git reset --soft HEAD~1

É útil quando o commit foi feito cedo demais, mas você não quer perder o trabalho.

Resumo rápido:

  • --soft: volta o commit e preserva mudanças staged
  • --mixed: volta o commit e tira do stage
  • --hard: volta tudo e descarta mudanças

Esse último merece bastante cuidado, pois você vai perder todo o trabalho feito.

git merge

Junta o histórico de outra branch na sua branch atual.

git merge nome-da-branch

Pensa assim:

“traz essa linha de trabalho para dentro da minha”

Dependendo do caso:

  • pode criar um merge commit
  • ou pode fazer fast-forward, sem criar commit extra

git rebase -i HEAD~2

Reescreve commits de forma interativa.

git rebase -i HEAD~2

Esse é um comando muito útil, mas merece cuidado.

Eu costumo usar para:

  • ajustar mensagem de commit
  • incluir/alterar algum código que faltou
  • remover algo sensível que entrou por engano

Pensa no rebase como:

“vou reorganizar essa parte do histórico como se eu tivesse feito do jeito certo desde o começo”

O que o rebase realmente faz

Uma coisa que me ajudou bastante a entender rebase foi perceber que o Git não pensa em “branches” da forma que a gente costuma imaginar visualmente.

Na prática, ele pensa mais em:

“quais commits existem na minha branch atual, mas ainda não existem na nova base?”

Esses commits são os chamados commits exclusivos.

Exemplo:

A---B---C---X---Y main
     \
      D---E feature

Se eu estiver na feature e fizer:

git rebase main

o Git:

  1. encontra o ancestral comum (C)
  2. identifica os commits exclusivos da feature (D e E)
  3. usa Y como nova base para reaplicar D e E
  4. reaplica os commits em cima da nova base

Resultado:

A---B---C---X---Y main
                 \
                  D'---E'

Esses commits reaplicados possuem novos hashes.

Ou seja:

o Git não “move” os commits ele recria os commits em outra base

Foi isso que me fez entender por que o rebase muitas vezes parece uma sequência automática de cherry-pick.

Dependendo do histórico do projeto, isso também pode gerar situações em que commits parecidos em conteúdo aparecem reaplicados com novos hashes, especialmente após outros rebases, squashs ou cherry-picks.

git branch -d

Remove uma branch local.

git branch -d nome-da-branch

Se precisar forçar:

git branch -D nome-da-branch

Comandos que eu mais uso sem pensar muito

Se eu fosse reduzir tudo para um kit básico do dia a dia, seria mais ou menos isso:

git status
git add .
git commit -m "mensagem"
git pull
git push
git diff
git log --oneline

Cuidados importantes

Evite usar força sem entender

-f ou --force pode resolver um problema rápido, mas também pode bagunçar histórico compartilhado.

Se realmente precisar reescrever histórico já publicado, prefira:

git push --force-with-lease

Ele é menos agressivo do que --force.

Rebase não é vilão, mas também não é brinquedo

Rebase é ótimo para deixar o histórico mais limpo.

Mas, se usado sem entender o que está fazendo, pode:

  • reescrever commits já compartilhados
  • dificultar rastreabilidade
  • gerar confusão no time

Em projeto de empresa, vale sempre respeitar a convenção do time.

Merge e rebase não são “iguais”

Os dois podem resolver o problema de atualizar uma branch, mas fazem isso de formas diferentes.

  • merge preserva o histórico como ele aconteceu
  • rebase reaplica commits em outra base, deixando a linha mais linear

Então o resultado visual e histórico muda bastante.

Conclusão

No começo, Git parece um monte de comando solto e meio ameaçador.

Depois de um tempo, você percebe que a maior parte do dia a dia gira em torno de poucos comandos bem repetidos.

Claro que existem muitas outras formas e comandos no Git.

Mas, no dia a dia, eu prefiro dominar muito bem o básico e entender exatamente o que cada comando altera no histórico.

O importante não é decorar tudo de uma vez e nem usar exatamente esses comandos.

É usar o que resolve o seu problema no dia a dia.

É entender o básico muito bem:

  • o que é branch
  • o que é commit
  • o que é stage
  • o que cada comando realmente altera

Quando isso fica claro, Git deixa de parecer “mágica perigosa” e começa a parecer só uma ferramenta muito útil.

Voltar para o garden