O Que Acontece Quando Você Faz um Commit: Um Mergulho Profundo no Git
1. O que é o Git? O Git é um sistema de controle de versão distribuído que permite aos desenvolvedores gerenciar e acompanhar alterações em arquivos de projetos. Ele armazena imagens do sistema de arquivos em miniatura, salvando apenas referências para arquivos não alterados, o que torna suas operações rápidas e eficientes. 2. Os Três Estados Os arquivos no Git podem estar em três estados principais: Modified: O arquivo foi modificado. Staged: O arquivo está preparado para o próximo commit. Committed: O arquivo foi salvo no banco de dados local. 3. Como o Git Garante a Integridade dos Arquivos? Tudo no Git passa por uma soma de verificações (checksum) antes de ser armazenado e é referenciado por esse checksum. Isso torna impossível alterar o conteúdo de qualquer arquivo ou pasta sem que o Git saiba. O mecanismo de verificação é chamado de hash SHA-1, uma sequência de 40 caracteres hexadecimais (ex.: fa7064f204b8bb4ade5eed778ee1e278e54559d2), calculada com base no conteúdo de uma estrutura de arquivo ou diretório no Git. Para gerar um hash SHA-1 no linux: echo -e 'Hello, World!' | sha1sum 60fde9c2310b0d4cad4dab8d126b04387efba289 E caso seja removido algum caractere da string? echo -e 'Hello, World' | sha1sum 4ab299c8ad6ed14f31923dd94f8b5f5cb89dfb54 Percebe-se que o valor mudou. Dessa forma, o Git garante a integridade dos arquivos. 4. Estrutura Básica de Pastas Ao iniciar um projeto no Git, é criado o diretório de trabalho .git, que contém a seguinte estrutura: git init ls -F1 .git Estrutura Descrição HEAD Aponta para a branch atual. config Contém opções de configuração específicas do projeto. description Usado pelo GitWeb, pode ser ignorado. hooks Scripts que podem ser executados em operações como commit e merge. info Mantém o arquivo exclude global para padrões ignorados. objects Guarda todo o conteúdo do banco de dados de objetos. refs Guarda referências para objetos de commit. index Guarda informações da staging area. Os principais diretórios são: objects, refs e HEAD. 5. Plumbing vs. Porcelain Existem duas categorias de comandos no Git: Plumbing: Comandos de baixo nível, que oferecem acesso ao funcionamento interno do Git. Porcelain: Comandos amigáveis usados no dia a dia. Para os comandos porcelain, este guia expõe os comandos do dia a dia: Git Cheatsheet 6. Objetos O Git utiliza uma estrutura de dados baseada em objetos para armazenar informações sobre o repositório. Existem três tipos principais de objetos: Blobs Trees Commits 6.1 Blobs Um blob é um objeto que contém o conteúdo de um arquivo. Ele não armazena informações sobre o nome do arquivo ou o diretório em que está localizado. Para criar um blob, utiliza-se o comando plumbing: hash-object: echo 'Hello, World!' | git hash-object -w --stdin 8ab686eafeb1f44702738c8b0f24f2567c36da6d -w: Informa ao hash-object para armazenar o objeto. --stdin: Informa ao comando para ler o conteúdo do stdin. Se você não especificar, o parâmetro é o caminho para um arquivo. O comando hash-object não apenas faz o hash do conteúdo, ele adiciona algumas informações importantes para o funcionamento interno, como: o tipo do objeto, o tamanho do conteúdo e o delimitador. Para o exemplo Hello, World! fica dessa forma: blob 14\0Hello, World!. Então, dessa obtêm-se o mesmo valor nesses dois casos: echo 'Hello, World!' | git hash-object -w --stdin 8ab686eafeb1f44702738c8b0f24f2567c36da6d echo -e 'blob 14\0Hello, World!' | sha1sum 8ab686eafeb1f44702738c8b0f24f2567c36da6d Para visualizar como o Git armazenou os dados: find .git/objects -type f .git/objects/8a/b686eafeb1f44702738c8b0f24f2567c36da6d Para recuperar o conteúdo do arquivo: git cat-file -p Hello, World! 6.2 Trees Os objetos tree resolvem o problema de armazenar o nome do arquivo e também permitem armazenar de forma conjunta um grupo de arquivos. Para agrupar os objetos blobs na área de staging em uma estrutura de árvore (tree): Criar um arquivo: echo 'Hello, World!' > hello-world.txt Gerar um hash SHA-1 para esse arquivo: git hash-object -w hello-world.txt Usar o comando plumbing update-index para adicionar o blob à área de staging e dar um nome a ele: git update-index \ --add \ --cacheinfo 100644 \ \ hello-world.txt --add: Adiciona o blob à área de staging --cacheinfo ,,: Registra um arquivo que ainda não está no diretório de trabalho (.git). Alguns dos Modos UNIX Válidos no Git: 100644: Arquivo normal (permissões de leitura e escrita para o proprietário, leitura para o grupo e outros). 100755: Arquivo executável (permissões de leitura, escrita e execução para o proprietário, leitura e execução para o grupo e outros). 120000: Link simbólico (um ponteiro para outro arquivo ou diretório). E pode ser adicionado outros blobs à área de staging, após isso, já pode ser cr

1. O que é o Git?
O Git é um sistema de controle de versão distribuído que permite aos desenvolvedores gerenciar e acompanhar alterações em arquivos de projetos. Ele armazena imagens do sistema de arquivos em miniatura, salvando apenas referências para arquivos não alterados, o que torna suas operações rápidas e eficientes.
2. Os Três Estados
Os arquivos no Git podem estar em três estados principais:
- Modified: O arquivo foi modificado.
- Staged: O arquivo está preparado para o próximo commit.
- Committed: O arquivo foi salvo no banco de dados local.
3. Como o Git Garante a Integridade dos Arquivos?
Tudo no Git passa por uma soma de verificações (checksum) antes de ser armazenado e é referenciado por esse checksum. Isso torna impossível alterar o conteúdo de qualquer arquivo ou pasta sem que o Git saiba. O mecanismo de verificação é chamado de hash SHA-1, uma sequência de 40 caracteres hexadecimais (ex.: fa7064f204b8bb4ade5eed778ee1e278e54559d2
), calculada com base no conteúdo de uma estrutura de arquivo ou diretório no Git.
Para gerar um hash SHA-1 no linux:
echo -e 'Hello, World!' | sha1sum
60fde9c2310b0d4cad4dab8d126b04387efba289
E caso seja removido algum caractere da string?
echo -e 'Hello, World' | sha1sum
4ab299c8ad6ed14f31923dd94f8b5f5cb89dfb54
Percebe-se que o valor mudou. Dessa forma, o Git garante a integridade dos arquivos.
4. Estrutura Básica de Pastas
Ao iniciar um projeto no Git, é criado o diretório de trabalho .git
, que contém a seguinte estrutura:
git init
ls -F1 .git
Estrutura | Descrição |
---|---|
HEAD | Aponta para a branch atual. |
config | Contém opções de configuração específicas do projeto. |
description | Usado pelo GitWeb, pode ser ignorado. |
hooks | Scripts que podem ser executados em operações como commit e merge. |
info | Mantém o arquivo exclude global para padrões ignorados. |
objects | Guarda todo o conteúdo do banco de dados de objetos. |
refs | Guarda referências para objetos de commit. |
index | Guarda informações da staging area. |
Os principais diretórios são: objects, refs e HEAD.
5. Plumbing vs. Porcelain
Existem duas categorias de comandos no Git:
- Plumbing: Comandos de baixo nível, que oferecem acesso ao funcionamento interno do Git.
- Porcelain: Comandos amigáveis usados no dia a dia.
Para os comandos porcelain, este guia expõe os comandos do dia a dia: Git Cheatsheet
6. Objetos
O Git utiliza uma estrutura de dados baseada em objetos para armazenar informações sobre o repositório. Existem três tipos principais de objetos:
- Blobs
- Trees
- Commits
6.1 Blobs
Um blob é um objeto que contém o conteúdo de um arquivo. Ele não armazena informações sobre o nome do arquivo ou o diretório em que está localizado.
- Para criar um blob, utiliza-se o comando plumbing:
hash-object
:
echo 'Hello, World!' | git hash-object -w --stdin
8ab686eafeb1f44702738c8b0f24f2567c36da6d
-
-w
: Informa aohash-object
para armazenar o objeto. -
--stdin
: Informa ao comando para ler o conteúdo do stdin. Se você não especificar, o parâmetro é o caminho para um arquivo.
O comando hash-object
não apenas faz o hash do conteúdo, ele adiciona algumas informações importantes para o funcionamento interno, como: o tipo do objeto, o tamanho do conteúdo e o delimitador.
Para o exemplo Hello, World!
fica dessa forma: blob 14\0Hello, World!
.
Então, dessa obtêm-se o mesmo valor nesses dois casos:
echo 'Hello, World!' | git hash-object -w --stdin
8ab686eafeb1f44702738c8b0f24f2567c36da6d
echo -e 'blob 14\0Hello, World!' | sha1sum
8ab686eafeb1f44702738c8b0f24f2567c36da6d
Para visualizar como o Git armazenou os dados:
find .git/objects -type f
.git/objects/8a/b686eafeb1f44702738c8b0f24f2567c36da6d
Para recuperar o conteúdo do arquivo:
git cat-file -p
Hello, World!
6.2 Trees
Os objetos tree resolvem o problema de armazenar o nome do arquivo e também permitem armazenar de forma conjunta um grupo de arquivos.
Para agrupar os objetos blobs na área de staging em uma estrutura de árvore (tree):
- Criar um arquivo:
echo 'Hello, World!' > hello-world.txt
- Gerar um hash SHA-1 para esse arquivo:
git hash-object -w hello-world.txt
- Usar o comando plumbing
update-index
para adicionar o blob à área de staging e dar um nome a ele:
git update-index \
--add \
--cacheinfo 100644 \
\
hello-world.txt
-
--add
: Adiciona o blob à área de staging -
--cacheinfo
: Registra um arquivo que ainda não está no diretório de trabalho (.git).,
Alguns dos Modos UNIX Válidos no Git:
-
100644
: Arquivo normal (permissões de leitura e escrita para o proprietário, leitura para o grupo e outros). -
100755
: Arquivo executável (permissões de leitura, escrita e execução para o proprietário, leitura e execução para o grupo e outros). -
120000
: Link simbólico (um ponteiro para outro arquivo ou diretório).
E pode ser adicionado outros blobs à área de staging, após isso, já pode ser criado um objeto tree com o comando plumbing write-tree
:
git write-tree
43b603fc7207c1f84ba7e65934181336a0e68b92
Para visualizar, basta utilizar o comando cat-file
:
git cat-file -p
100644 blob 8ab686eafeb1f44702738c8b0f24f2567c36da6d hello-world.txt
Mas ainda falta algo: Onde está as informações do autor, a data da modificação e a mensagem?
6.3 Commits
Os objetos commit armazenam informações essenciais sobre as alterações feitas no repositório. Cada objeto commit contém:
- Um ponteiro para um objeto tree, que representa o estado do diretório no momento do commit.
- Informações sobre o autor do commit (nome e e-mail).
- A data e hora em que o commit foi feito (timestamp).
- Uma mensagem de commit que descreve as alterações realizadas.
- Um ponteiro para o commit anterior (ou commits, no caso de merges), permitindo a construção de um histórico de alterações.
O comando plumbing commit-tree
é o encarregado para criar um objeto commit:
git commit-tree 43b60 -m 'mensagem do commit'
21cc9199e22c5eb10731608f88d99a3bb147b2eb
Para visualizar o objeto commit, basta utilzar o comando plumbing cat-file
:
git cat-file -p
tree 43b603fc7207c1f84ba7e65934181336a0e68b92
author Gustavo Vasconcelos 1744048435 -0300
committer Gustavo Vasconcelos 1744048435 -0300
mensagem do commit
É possível também aninhar commits passando o hash do commit anterior para que eles tenham uma linha do tempo:
- Gerar hash:
'Para um segundo commit' | git hash-object -w --stdin
fa538a1ae921322d20bc39c86135ec528c261e1f
- Adicionar a área de staging:
git update-index \
--add \
--cacheinfo 100644 \
fa538a1ae921322d20bc39c86135ec528c261e1f \
hello-world.txt
- Criar o objeto tree:
git write-tree
a687f3f49545dba2ff9a424891d445b59c107893
- Criar o objeto commit referenciando o commit anterior:
git commit-tree a687f -m 'segundo commit' -p 21cc9
a3e6aedbac6c7e8c33db0cd6490658c8b3519dd3
-
-p
: Usa para referenciar o commit anterior.
Pode-se utilizar o comando porcelain log
para visualizar o histórico:
git log --stat 6aa7e
commit 6aa7e37d8ad583deaee0783462fb62a241c5b9c1
Author: Gustavo Vasconcelos
Date: Mon Apr 7 15:17:01 2025 -0300
segundo commit
hello-world.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
commit 21cc9199e22c5eb10731608f88d99a3bb147b2eb
Author: Gustavo Vasconcelos
Date: Mon Apr 7 14:53:55 2025 -0300
mensagem do commit
hello-world.txt | 1 +
1 file changed, 1 insertion(+)
Basicamente este é o ciclo de vida de uma modificação até um commit no Git, tudo baseado em chave-valor e armazenado no banco de dados local, e agora dá pra entender como o git busca tão rapidamente alterações feitas em um projeto, independente do tamanho ou do tempo que o projeto existe.