Depois de algum tempo usando o Git, você sabe certamente quais as melhores maneiras de usá-lo todos os dias, incluindo os comandos mais úteis.
Quando você atinge esse nível de compreensão de como usar uma ferramenta, é hora de se aprofundar em seus conceitos, arquitetura e estrutura.
Neste post, vamos entender como o Git organiza suas informações e como ele persiste essas informações em sua estrutura de arquivos.
O HEAD em .git/HEAD
HEAD é um arquivo que contém o nome da ramificação atual (current branch).
ref: refs/heads/dev
Neste exemplo, seu HEAD está apontando agora para branch dev
.
HEAD também pode ser um ID de commit, que é chamado de estado HEAD desanexado (detached HEAD state).
12836deb078b57c1e800058d2cf8eb075ea24cb1
Branches em .git/refs/heads/
Cada ramificação é armazenada como um arquivo que contém 1 (apenas um) commit ID.
Esses arquivos são armazenados em uma pasta chamada refs/heads
.
Na imagem, cada arquivo é o nome de uma ramificação, e as pastas representam nomes de branches com um separador /
, como fix/BUG-123
. Neste exemplo BUG-123 será um arquivo com esse nome e talvez a seguinte ID de commit:
82e5b05312cc6c7af6b8fea1e09ca2f438ddd703
Tags, stash, remotes tudo em .git/refs
Assim como as branches vivem em .git/refs
, também tags, `stash, remotes.
- .git
-- refs
--- heads <- *branches*
--- remotes
--- stash
--- tags
Commits em .git/objects
Um commit é salvo em um arquivo contendo seu(s) pai(s) (parents), mensagem, árvore e autor.
Essas informações são compactadas e a melhor maneira de ver objetos git é usando o comando:
git cat-file -p HASH
No comando acima, HASH
é a ID de commit.
git cat-file -p 95173d8501
# output
tree e0645455629c2bd9d64b81fb17503dcb4df5bd9f
parent 81b21476b2c5d19a8fdbf9d414b42088c94484c8
parent 7473e3c226411ed5252539ca9d337de0a6f9ccbb
author Ademir Mazer Jr [ Nuno ] <[email protected]> 1697586900 -0300
committer GitHub <[email protected]> 1697586900 -0300
gpgsig -----BEGIN PGP SIGNATURE-----
XXXXXABCAAQBQJlLx7UCRBK7hj4Ov3rIwAAwREIAJynSGsjhJnjaLpYbEF/fp7O
VZQ8o+ZS+Pg/F4tG8ytE4Yd4B9hp63pwrpaDIJx27SARzOokIKovie99pQrVMfUz
DQviwVd41Eh6aNqkDcj0qNihw15rM/EZqUTUW6ApMgg/8kdtcsdsdsd
5FWRzG43Q98ZgvZQJfzPeAmePKap/iGZNfsg0LMLB6vBQ1xVXyQ6lY8scDPv2lg3
HDeldfJqsjEDzDODbcv2GcyhkOmb32Esn7R5H5bjgXaCqAWZI+40HgxTwfRratlNsdsdsdssdCI9TPHwFGHfW4Lk3t/9HIx7ldWRtoEykOVL01Ak=
=QWAS
-----END PGP SIGNATURE-----
Merge pull request #705 from Mazer/1510-planilha-prod-preco
fix: staus de completo da classe quando não tem um item na NF do pedido
Árvores (trees) em .git/objects
Árvores são arquivos com listagens de diretórios. Os arquivos nele são chamados de blobs
.
git cat-file -p master^{tree}
# output
100644 blob 6537ca4677ee97ddcb112f22d086b92721fd578c .editorconfig
100644 blob 354be23c7b01803db48f6008a82ce042e41f9a04 .env.example
100644 blob 967315dd3d16d50942fa7abd383dfb95ec685491 .gitattributes
100644 blob f6fb8a7f6d07dd3f7a624bb373f87be0365cc569 .gitignore
100644 blob 57f7d3b20c41447e1c9f6cc80fd161b9cad54d42 .rnd
040000 tree 42f824c3c2b6743a468d08893b3fdaa453316fc5 .scribe
100644 blob 9231873a112ba0ded2550a45741bad544e7a1998 .styleci.yml
040000 tree e7170f21fba71d487011969e6eebae029cbc2afd .vscode
100644 blob 80258098b18a85ff17ccf7d29259886882ee97be README.md
040000 tree e489d9339d4dfd9c025a40053c18815596d1df08 app
100644 blob 5c23e2e24fc5d9e8224d7357dbb583c83884582b artisan
040000 tree fa579600b150dfe96277f923c509bc473517b32a bootstrap
100644 blob 08183152f2089d6c229474c8eb020fd54fe0070c composer.json
100644 blob 67772e4ece555d51d3833d5f1b8c634902ceb709 composer.lock
040000 tree bf28bd62dc2e4604e853c6aac64b4ee6bb79c762 config
040000 tree 48955a5c0935bcb7c88b1cbb0599eba405b66b36 database
100644 blob 769dd5516e2308eff567d1774de12a842db7f16b package-lock.json
100644 blob ca5629bc4cd598cae98b89c723a707b3f7bc6b38 package.json
100644 blob 90952f05a7c49f0ebc6af0fe4f7b332cd61ea586 phpstan.neon
100644 blob 4ae4d979d1ecc9bb45aabf0ff7071ce0e63bd4e2 phpunit.xml
040000 tree 2297374bcd5c5d552865315e4d310cc14de468d7 public
040000 tree a6ef03f417eff40e2e6a1e19ff020a789c2dc201 resources
040000 tree 33d6539ee1ae71d17961971a618825157083e38a routes
100644 blob 5fb6379e71f275a1784e6638adc96420aaa5c5b2 server.php
040000 tree d0be5083619e6e92c3408f2455afd9b338970e16 storage
040000 tree d50aa6e9b745b0dba78abd8fa5b1c9a57946a46a tests
100644 blob b9889e995f67106aebdb994d29c30e4dd5a85325 webhook-deploy.sh
100644 blob 6189710be60e7cb518dc9f5e7eea7d4b88879388 webpack.mix.j
Blobs em .git/objects
Blobs
são os arquivos que contêm seu conteúdo real (código-fonte, textos, etc).
git cat-file -p 6537
# output
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.{yml,yaml}]
indent_size = 2
Observe a primeira linha da seção anterior (Árvores), 6537 é o código hash do arquivo blob para .editorconfig
.
Reflog em .git/logs/refs/heads/main
reflog
armazena o histórico de cada branch, tag e HEAD na pasta .git/logs/refs
. Nesse diretório, o arquivo HEAD
armazena o log HEAD completo. Em subdiretórios dentro de refs
há história de logs para heads e remotes.
Cada linha de reflog
tem:
- antes/depois de commit IDs
- usuário
- carimbo de data/hora
- mensagem de log
0000 6e6b Ademir Mazer Junior <[email protected]> 1695844143 -0300 branch: Created from HEAD
6e6b 075d Ademir Mazer Junior <[email protected]> 1695847428 -0300 commit: feat: #1510 planilha modelo com produtos
075d af8b Ademir Mazer Junior <[email protected]> 1697505509 -0300 commit: fix: corrige atualização de preço promocional pela planilha
af8b ff78 Ademir Mazer Junior <[email protected]> 1697544622 -0300 commit: fix: nome da classe
ff78 7473 Ademir Mazer Junior <[email protected]> 1697586865 -0300 commit: fix: staus de completo da classe quando não tem um item na NF do pedido
7473 44a1 Ademir Mazer Junior <[email protected]> 1698783202 -0300 commit: fix: cálculo de valor final e exception no cálculo de valor promocional
Rastreamento branches remotas em .git/refs/remotes/origin/main
Os rastreamentos-remotos
de branches armazenam a ID de commit existente mais recentemente para uma branch remota.
Quando o git status
mostra you're up to date with origin/main
(que você está atualizado com origin/main), ele está se referindo ao ID de commit no arquivo main
dentro de refs/remotes/origin
.
59be37277161007fccab827ad3e4196563216eb6
Configuração em .git/config
A configuração do repositório é armazenada no arquivo .git/config
. Nesse arquivo, você define remotes, autor e outras configurações de repositório.
O Git tem configurações locais, globais e do sistema. As configurações globais geralmente estão localizadas em ~/.gitconfig
.
Para saber mais sobre configurações, leia Git Config: Configuração de Email e Username.
.
Hooks em .git/hooks/pre-commit
Os scripts chamados hooks
no Git são opcionais, você pode escrever scripts para fazerem qualquer coisa, configurar e executar quando algum evento ocorrer no fluxo de trabalho do Git, por exemplo antes de um commit.
#!/bin/bash
phpstan app/
Área de staging em .git/index
A área de staging
armazena arquivos que estão prontos para serem confirmados (commited). O arquivo onde eles são armazenados é um arquivo binário chamado index
.
Para saber mais sobre o git index leia: Git Index.
Considerações Finais
Para engenheiros de software e desenvolvedores, uma compreensão profunda dos arquivos e da estrutura de pastas do Git não apenas aumenta a proficiência no uso do Git, mas também capacita a solucionar problemas, otimizar e aproveitar o Git em todo o seu potencial.
Comentários