O que é Git e como ele guarda todo o histórico do seu código

Muita gente que começa com Git acha que ele guarda “as diferenças” entre versões e que, por isso, um comando errado apaga o trabalho para sempre. O resultado é medo: a pessoa evita criar branches, copia a pasta inteira como “projeto_final_v3” por segurança e, quando algo dá errado, apaga o repositório e clona de novo, perdendo o que não tinha enviado.
$ ls ./neste-artigo
Entender como o Git realmente guarda o histórico resolve esse medo. Ele é muito mais difícil de quebrar do que parece.
Git em uma frase, antes do mecanismo
Git é um sistema de controle de versão distribuído: ele registra fotografias do seu projeto ao longo do tempo, cada uma com autor, data e mensagem, e cada cópia do repositório tem o histórico completo. Foi criado por Linus Torvalds em 2005 para o desenvolvimento do kernel Linux e hoje é o padrão da indústria.
“Distribuído” quer dizer que não existe um servidor central obrigatório. O repositório no seu notebook é tão completo quanto o que está no GitHub. Você faz commits, cria branches e consulta o histórico sem internet.
Num computador recém-configurado, o Git precisa saber quem você é, porque nome e e-mail vão gravados em cada fotografia do histórico:
git config --global user.name "Seu Nome"
git config --global user.email "[email protected]"
git initO git init cria uma pasta oculta .git dentro do projeto. É ali que mora todo o histórico: commits, branches e configurações locais. Apagar essa pasta é a única forma realmente simples de perder o histórico inteiro, e por isso ela nunca deve ser mexida à mão. Se você já tem um projeto no GitHub, o caminho é o inverso: git clone URL baixa a pasta de trabalho e o .git completo de uma vez.
Git guarda fotografias, não listas de alterações
Esse é o ponto que o capítulo O que é Git, do livro Pro Git (gratuito e em português) faz questão de destacar. Sistemas mais antigos, como o Subversion, armazenam cada arquivo e uma sequência de mudanças sobre ele. O Git armazena, a cada commit, um retrato de como todos os arquivos estavam naquele instante.
Para não desperdiçar espaço, o Git reaproveita arquivos intactos: o novo retrato aponta para o mesmo conteúdo já guardado. E cada conteúdo é identificado por um hash (uma sequência como a1b2c3d...) calculado a partir dele mesmo. Se um bit mudar, o hash muda. É por isso que o histórico do Git é praticamente impossível de corromper sem que ele perceba.

O caminho de uma alteração até virar commit
Todo arquivo do projeto passa por três áreas. Seguir uma mudança do começo ao fim deixa claro o papel de cada comando que você usa todo dia.
- Diretório de trabalho. Você edita
index.htmlno editor. O Git percebe que o arquivo mudou, mas ainda não fez nada com isso.git statusmostra o arquivo como “modificado”. - Área de preparação (staging). Com
git add index.html, você diz: “esta versão do arquivo entra na próxima fotografia”. Dá para preparar só parte das mudanças e deixar o resto para outro commit. - Repositório.
git commit -m "Corrige menu no celular"tira a fotografia de tudo que está na área de preparação e grava no histórico, com um hash próprio e um ponteiro para o commit anterior. - Remoto.
git pushenvia os commits novos para um servidor (GitHub, GitLab, Bitbucket).git pullfaz o contrário: traz o que outras pessoas enviaram e junta com o seu trabalho.
Como cada commit aponta para o anterior, o histórico vira uma corrente. git log --oneline --graph desenha essa corrente no terminal.
git status
git add index.html
git commit -m "Corrige menu no celular"
git log --onelineResposta rápida: o Git guarda o histórico como uma corrente de fotografias completas do projeto, cada uma ligada à anterior e identificada por um hash. Branch é só um nome apontando para uma dessas fotografias.
Branch no Git é só uma etiqueta móvel
Muita gente imagina que criar uma branch copia o projeto inteiro. Não copia. Uma branch é um arquivo minúsculo contendo o hash de um commit. A cada commit feito nela, a etiqueta anda para frente.
Por isso criar branch no Git é instantâneo, e por isso o fluxo comum é abrir uma branch para cada tarefa:
git switch -c ajuste-menu
# edita, adiciona, faz commits
git switch main
git merge ajuste-menuO merge junta os históricos. Se as duas branches mexeram em linhas diferentes, o Git resolve sozinho. Se mexeram na mesma linha, ele para e pede que você escolha: é o famoso conflito, que assusta mais do que deveria. O arquivo fica marcado com <<<<<<< e >>>>>>>, você edita deixando a versão certa, faz git add e conclui o commit.
Por que é tão difícil perder trabalho de verdade no Git
Voltando ao medo do início. Uma vez que algo virou commit, o Git guarda aquele conteúdo por um bom tempo, mesmo que nenhuma branch aponte mais para ele. O comando git reflog lista por onde o seu HEAD (o “você está aqui”) passou nos últimos dias, inclusive commits que pareciam perdidos depois de um reset mal feito.
git reflog
git switch -c resgate a1b2c3dO que realmente se perde é o que nunca entrou em commit. Mudanças só no diretório de trabalho somem com um git checkout -- arquivo ou um git reset --hard. A documentação do git reset deixa claro que o modo --hard descarta alterações não commitadas, sem volta.
Daí sai a regra de ouro: faça commits pequenos e frequentes. Commit local não custa nada e é a sua rede de segurança.
Os tropeços de quem começa com Git
- Commitar senha ou chave de API. Mesmo apagando depois, ela continua no histórico. Use um arquivo
.gitignorepara o.envdesde o primeiro dia e, se vazou, troque a chave imediatamente. - Mensagem “ajustes”. Daqui a três meses ela não diz nada. Escreva o que mudou e por quê, em uma linha.
- Commit gigante no fim do dia. Mistura correção de bug com refatoração e torna impossível desfazer só uma parte.
- Trabalhar direto na main em projeto de equipe. Uma branch por tarefa evita pisar no código dos colegas.
- Usar
push --forceem branch compartilhada. Reescreve o histórico que outras pessoas já baixaram. Se precisar, prefira--force-with-lease, que recusa o envio se alguém tiver atualizado a branch. - Versionar
node_modulesou arquivos gerados. Infla o repositório sem motivo; o.gitignoreresolve.
Fotografias e etiquetas na sua rotina
Sabendo que commit é fotografia barata e branch é etiqueta, você passa a experimentar sem medo: cria uma branch para testar uma ideia maluca, faz commits à vontade e, se não der certo, simplesmente volta para a main. Esse é o uso que separa quem “sabe uns comandos” de quem trabalha com Git com tranquilidade.
O próximo passo é ligar o repositório local a um remoto e colaborar. Plataformas como o GitHub entram aí, e mudanças recentes nelas, como as do Secret Scanning do GitHub, mostram por que não commitar segredos importa tanto. Para os termos que apareceram aqui (hash, HEAD, merge), use o nosso glossário de programação como consulta rápida.




