Git sem mistério: snapshots, história e colaboração segura

O problema que “salvar como final-3” não resolve

Você alterou a prioridade da ordem de serviço OS 742, uma colega atualizou o contrato enviado ao sistema de gestão empresarial e um agente de programação ajustou testes. Qual versão contém cada decisão? Quem verificou a mudança? É possível desfazer somente o defeito sem apagar o trabalho correto?

Git é um sistema distribuído de controle de versão. Ele registra estados do projeto e relações entre esses estados. Distribuído significa que um clone normalmente possui histórico e banco de objetos locais; muitos comandos não precisam consultar servidor. Um repositório é o projeto acompanhado por Git, incluindo seus arquivos visíveis e uma área interna de metadados chamada .git.

Git não substitui backup, revisão ou teste. Ele preserva conteúdo registrado, mas não entende se uma regra de manutenção está correta. Também não protege automaticamente arquivos nunca adicionados nem revoga um segredo vazado.

Três lugares antes do primeiro commit

Considere o arquivo prioridade.txt. Você troca alta por imediata. Agora existem três superfícies:

  1. Diretório de trabalho, ou working tree: os arquivos que você enxerga e edita.
  2. Área de preparação, ou staging area: seleção exata que entrará no próximo registro. O nome técnico dessa área é índice.
  3. Repositório local: objetos e histórico já confirmados.

O fluxo básico é:

Fluxo: Working tree: edição atual, Índice: próximo snapshot, Commit: snapshot registrado, Branch aponta para o commit, Remote recebe objetos e referênciaWorking tree: ediçãoatualÍndice: próximo snapshotCommit: snapshotregistradoBranch aponta para ocommitRemote recebe objetos ereferência
Ler o fluxo em texto
  1. 1. Working tree: edição atual
  2. 2. Índice: próximo snapshot
  3. 3. Commit: snapshot registrado
  4. 4. Branch aponta para o commit
  5. 5. Remote recebe objetos e referência

git add não publica nada e não cria commit. Ele copia a versão selecionada da mudança para o índice. git commit registra o snapshot preparado: uma fotografia lógica dos arquivos rastreados naquele momento. A documentação oficial descreve os estados modificado, preparado e confirmado e o modelo de snapshots do Git.

Use inspeção antes de ação:

git status
git diff
git diff --staged

status resume o estado. git diff mostra mudanças no diretório de trabalho ainda não preparadas. git diff --staged compara o índice com o commit atual: é uma prévia do que será confirmado. Se você editou duas regras mas quer commits separados, prepare uma por vez. Um commit útil deve expressar uma intenção coerente e passar seus testes; “backup de tudo que estava aberto” é uma fronteira ruim.

Commit, hash e história como grafo

Um commit referencia um snapshot, metadados como autor e mensagem e um ou mais commits pais. O primeiro não tem pai; um commit comum tem um; um merge pode ter dois. Essas relações formam um grafo, uma rede de nós e ligações direcionadas.

Cada objeto recebe um hash, identificador calculado a partir de conteúdo e metadados. Alterar o conteúdo produz outro identificador. O hash ajuda a detectar mudança e nomear precisamente um estado; não é senha, criptografia do projeto nem certificado de qualidade. Mesmo que a interface mostre sete caracteres, o identificador armazenado é maior.

A---B---C  ← main
     \
      D---E  ← os-742

Aqui, A a E representam commits. Branch é um nome móvel que aponta para um commit; não é uma pasta nem uma cópia completa. main aponta para C; os-742 aponta para E. HEAD indica a posição atualmente selecionada, normalmente uma branch. Ao confirmar novo trabalho, o ponteiro dessa branch avança.

Inspecione sem modificar:

git log --oneline --decorate --graph --all -12
git show HEAD
git show <hash>

A mensagem deve explicar intenção: fix: impedir baixa duplicada da OS informa mais que alterações. O diff mostra o “o quê”; mensagem, especificação e pull request explicam “por quê”.

Branches permitem linhas de trabalho

Criar uma branch é criar outro nome para um commit existente. Você pode avançá-la sem mover main:

git switch -c feature/os-742

switch -c cria e seleciona a branch. Depois de editar, inspecionar, preparar e confirmar, a nova história diverge. Branch curta reduz conflito e facilita revisão. Branch longa acumula decisões incompatíveis e torna integração mais arriscada.

Para juntar histórias, merge encontra ancestrais e combina mudanças. Se uma branch apenas avançou a partir da outra, o Git pode mover o ponteiro por fast-forward. Se ambas avançaram, pode criar um commit de merge. Merge preserva a topologia: continua visível que houve trabalho paralelo.

Rebase pega commits de uma linha, reaplica suas mudanças sobre outra base e cria novos commits com novos hashes. Ele pode produzir uma sequência linear e é útil para organizar trabalho local antes de compartilhar. O custo é reescrever identidade e parentesco. A orientação oficial alerta para não fazer rebase de commits que já foram enviados e usados por outras pessoas sem coordenação (Pro Git: Rebasing). Para iniciante: use merge como padrão; use rebase somente quando entender a política da equipe e souber que a história ainda é privada.

Situação Escolha inicial Motivo
branch local, ainda não compartilhada rebase pode ser aceitável ninguém depende dos hashes antigos
branch compartilhada merge preserva commits já consumidos
correção já publicada revert acrescenta desfazer auditável
dúvida sobre intenção pare e converse Git não conhece a regra do negócio

Remote não é “a nuvem mágica”

Um remote é uma configuração local que associa um nome a outro repositório. origin é apenas o nome convencional criado no clone. Pode apontar para GitHub, GitLab, servidor empresarial ou até uma pasta local.

  • git fetch origin baixa objetos e atualiza referências remotas locais, como origin/main, sem integrar automaticamente sua branch.
  • git merge origin/main integra explicitamente o estado buscado.
  • git pull combina busca com uma forma de integração definida por configuração ou opção. Por esconder dois passos, leia a política antes de automatizar.
  • git push origin minha-branch envia objetos e solicita atualização da referência remota; o servidor pode negar por proteção.

Uma pull request, ou solicitação de integração, é recurso da plataforma de hospedagem, não um objeto fundamental do Git. Ela reúne diff, contexto, conversa, revisões e verificações antes de integrar uma branch. A documentação do GitHub descreve pull requests como mecanismo para propor, revisar e integrar mudanças (GitHub Docs).

Uma boa solicitação responde: qual problema; qual decisão; o que ficou fora; como testar; quais riscos; como reverter. Revisão deve verificar separadamente conformidade com a especificação e qualidade da implementação.

Conflito: Git encontrou duas intenções

Um conflito textual ocorre quando Git não consegue combinar automaticamente alterações sobrepostas. O arquivo recebe marcadores:

<<<<<<< HEAD
response_field=state
=======
response_field=status
>>>>>>> outra-branch

Não escolha “o meu” ou “o deles” pela posição. Descubra o requisito, edite a versão final, execute testes, prepare o arquivo e conclua a integração. git status lista os arquivos pendentes.

Um conflito semântico é mais perigoso: Git combina os textos sem marcador, porém os comportamentos são incompatíveis. Ana muda a resposta da interface de status para state; Bruno altera um consumidor que ainda lê status. Arquivos diferentes podem gerar merge limpo e aplicação quebrada. Testes de contrato e revisão detectam o que o algoritmo textual não pode decidir.

Escada de recuperação segura

Quando algo parece perdido, pare de produzir novas mudanças. Comece por comandos de leitura:

git status
git diff
git diff --staged
git log --oneline --decorate --graph --all -20
git reflog --date=local -20

Depois classifique o caso:

  • mudança ainda não preparada: copie ou preserve o arquivo antes de qualquer descarte;
  • mudança preparada por engano: git restore --staged arquivo retira do próximo commit sem apagar a edição do working tree;
  • commit local correto numa branch errada: crie uma nova branch apontando para ele;
  • commit defeituoso já compartilhado: git revert <hash> cria novo commit com mudança inversa, preservando auditoria;
  • branch local movida: o reflog registra movimentos recentes de referências locais; encontre o hash e crie git branch resgate <hash>.

O manual de git revert descreve a criação de commits inversos. O manual de git reflog deixa claro que reflogs registram atualizações locais de referências. Portanto, reflog não é backup compartilhado nem permanente.

Evite git reset --hard, git clean -fd, force push ou troca destrutiva enquanto houver trabalho não identificado. Esses comandos têm usos especializados, mas não são primeiros socorros. Nunca edite arquivos dentro de .git para “consertar” a história.

Pessoas, coding agents e worktrees

Um worktree adicional permite associar outra pasta do mesmo repositório a outra branch. Assim, a OS 742 fica numa pasta e a correção urgente em outra, sem alternar os arquivos da pasta atual. O comando e suas restrições estão no manual oficial de git worktree.

Para agentes de programação, aplique o mesmo isolamento:

  1. um ticket pequeno por branch e worktree;
  2. nunca dois agentes escrevendo na mesma pasta;
  3. escopo e arquivos protegidos declarados antes da execução;
  4. testes e critérios de aceite dentro do ticket;
  5. diff revisado por humano ou avaliador independente;
  6. integração somente após build e verificações determinísticas;
  7. agente não recebe permissão para force push ou apagar trabalho alheio.

Worktree isola arquivos, não pensamento nem infraestrutura. Agentes ainda podem alterar dependência comum, usar segredo do ambiente ou produzir commits incompatíveis. CI — integração contínua, isto é, verificações automáticas —, proteção de branch e revisão continuam necessárias.

Segurança e limites

Nunca confirme senha, token, chave privada, arquivo .env, exportação do ERP ou dado pessoal. .gitignore evita selecionar certos caminhos ainda não rastreados; não remove conteúdo já registrado. Se um segredo entrou no histórico, trate-o como comprometido: revogue ou rotacione primeiro, interrompa o uso, investigue exposição e siga a política de saneamento. Apagar a linha num commit posterior não invalida cópias anteriores.

Git registra autoria declarada, não prova que o autor compreendeu ou escreveu o código. Assinaturas melhoram proveniência, mas não substituem revisão. Um clone no mesmo hash também pode falhar se dependências, versões, arquivos gerados ou configuração inofensiva estiverem implícitos.

Critérios de aceite e prática

Você dominou esta etapa quando consegue desenhar working tree → índice → commit; prever os dois diffs; explicar por que branch é ponteiro; diferenciar fetch de pull; justificar merge versus rebase; resolver conflito pelo requisito; recuperar um hash via reflog criando branch; e explicar como worktrees reduzem colisões entre agentes.

Exercício: descreva três commits para mudar a prioridade da OS 742, atualizar seu teste e documentar migração do ERP. Quais mudanças devem ficar juntas? Simule um revisor: marque um risco de contrato, um risco de segredo e uma evidência ausente.

Recuperação ativa: git add envia ao servidor? Hash prova qualidade? O que HEAD aponta? Um merge sem marcadores garante compatibilidade? Por que rebase altera IDs? Quando revert é preferível? Reflog existe no remote? Worktree autoriza dois agentes a editar a mesma branch?

Execute agora o caderno operacional. Ele transforma o modelo em conflito, falha, reversão e recuperação reais.

Teste de fixação

Comprove o que você aprendeu

Responda todas as questões. O gabarito comentado só aparece depois do envio.

1. Depois de editar um arquivo e executar `git add`, onde a mudança foi preparada?
2. Uma branch já compartilhada possui commits usados por outras pessoas. Qual cuidado se aplica ao rebase?
3. Uma branch local foi movida por engano e o commit parece perdido. Qual procedimento reduz dano?

Consulta universal

O que você quer encontrar?

Títulos, capítulos, conceitos, termos, laboratórios e ferramentas em uma única busca.

Digite pelo menos dois caracteres.