📦 Como o Git funciona por dentro
O Git não guarda diffs. Ele é um banco de objetos endereçados por conteúdo: cada arquivo, cada commit e cada diretório vira um objeto imutável identificado pelo SHA-1 do seu conteúdo. Clique nos nós abaixo para explorar como um pequeno repositório é representado internamente.
① Intuição
Pense no Git como um banco de dados de snapshots, não de diferenças. Quando você faz
git commit, o Git não calcula "o que mudou" — ele tira uma foto completa do
estado atual e salva cada arquivo como um blob, cada diretório como uma
tree e o commit em si como outro objeto que aponta para a tree raiz.
A mágica: dois commits que compartilham um arquivo sem mudanças apontam para o mesmo blob. Não há cópia. O endereçamento por hash garante isso.
② Visualização — grafo de objetos
Este repositório tem 2 commits. O segundo alterou o README mas não tocou em
main.py — veja como as duas trees compartilham o mesmo blob.
③ Explicação técnica
Ao rodar git init, uma pasta .git/ é criada — ela é o banco
de dados inteiro:
$ git init meu-projeto $ cd meu-projeto # .git/ é criado — tudo vive aqui .git/ objects/ ← banco de objetos (commits, trees, blobs) refs/ ← ponteiros nomeados (branches, tags) HEAD ← "você está aqui"
Quando você faz git add, o Git computa o hash do conteúdo do arquivo
e salva um blob no object store:
# Você escreve um arquivo $ echo "print('hello')" > main.py # git add calcula o SHA-1 do conteúdo e salva $ git add main.py # → cria .git/objects/d4/e5f6... (blob) # O staging area (index) mapeia nome → hash $ git ls-files --stage 100644 d4e5f6... 0 main.py
O endereçamento por conteúdo (content-addressed storage) é a ideia central:
# Objetos são identificados pelo SHA-1 do conteúdo import hashlib conteudo = b"blob 14\0print('hello')\n" sha1 = hashlib.sha1(conteudo).hexdigest() # → "d4e5f6abc..." # Consequência: mesmo conteúdo = mesmo hash # git NUNCA duplica blobs idênticos
Os 4 tipos de objeto
| Tipo | Conteúdo | Gerado por |
|---|---|---|
| blob | Bytes de um arquivo | git add |
| tree | Lista de (modo, nome, hash) | git commit |
| commit | tree + parent + autor + mensagem | git commit |
| tag | Ponteiro nomeado para um commit | git tag -a |
④ Projeto
Inspecione um repositório real:
- Entre em qualquer repo Git:
cd meu-projeto - Veja os últimos 3 commits:
git log --oneline -3 - Inspecione um commit pelo hash:
git cat-file -p <hash> - Inspecione a tree que ele aponta:
git cat-file -p <tree-hash> - Leia um blob:
git cat-file -p <blob-hash> - Verifique um arquivo que não mudou em 2 commits — o hash do blob é idêntico!
⑤ Perguntas rápidas
- Se você renomear um arquivo sem mudar o conteúdo, o blob muda?
- O que
git clonerealmente transfere pela rede? - Por que
git checkouté tão rápido se cada commit é um snapshot completo? - O que acontece ao objeto quando você faz
git revert?
⑥ Aplicações no mundo real
- GitHub/GitLab — armazenam bilhões de objetos Git no mesmo modelo
- Merkle trees — Bitcoin, IPFS e sistemas de arquivos distribuídos usam a mesma ideia: hash de conteúdo garante integridade
- Imagens Docker — camadas são blobs endereçados por hash, reutilizados entre imagens (exatamente como blobs do Git)
- Nix/Guix — gerenciadores de pacotes que usam content-addressing para builds reproduzíveis