Os arquivos mágicos do Git
(nesbitt.io)- O Git controla seu comportamento por meio de arquivos específicos dentro do repositório, que não ficam nas configurações internas de
.git/, mas são versionados e viajam junto com o código .gitignore,.gitattributes,.lfsconfig,.gitmodules,.mailmapetc. cuidam, respectivamente, de excluir arquivos do rastreamento, definir atributos, configurar LFS, gerenciar submódulos e unificar autores.git-blame-ignore-revse.gitmessageajudam a melhorar a colaboração ao permitir ignorar commits de formatação de código e fornecer templates de mensagem de commit- GitHub, GitLab, Gitea etc. ampliam funcionalidades como CI/CD e definição de revisores por meio de pastas de configuração específicas da plataforma, como
.github/,.gitlab/e.gitea/ - Essa estrutura vai além do Git e também aparece em EditorConfig, Docker e ferramentas de gerenciamento de versões de linguagem, formando um ecossistema de configuração automática baseado em dotfiles
Principais arquivos mágicos do Git
- O Git reconhece vários arquivos especiais como
.gitignore,.gitattributes,.lfsconfig,.gitmodulese.mailmappara controlar o comportamento do repositório- Esses arquivos não fazem parte das configurações internas de
.git/, mas sim de componentes compartilhados e versionados, garantindo comportamento consistente na colaboração
- Esses arquivos não fazem parte das configurações internas de
.gitignore
- Define padrões de arquivos que o Git não deve rastrear
- Suporta curingas (
*.log), diretórios (dist/) e negação (!important.log) - É aplicado na ordem
.gitignore,.git/info/exclude, configuração global (~/.config/git/ignore)
- Suporta curingas (
- Arquivos já rastreados continuam sendo rastreados mesmo após adicionar ao
.gitignore; é possível removê-los comgit rm --cached - GitHub, GitLab e Gitea permitem fazer commit de arquivos que batem com padrões ignorados sem aviso
- O GitHub fornece templates de
.gitignorepor linguagem em seu repositório oficial
.gitattributes
- Controla filtros, diff, merge, finais de linha e detecção de linguagem por arquivo
- Ex.:
*.psd filter=lfs,*.png binary,*.sh text eol=lf
- Ex.:
textnormaliza finais de linha,binarydesativa diff/merge, emerge=oursmantém a versão local em caso de conflito- O GitHub Linguist lê
.gitattributespara excluir das estatísticas de linguagem, recolher código gerado e excluir documentação - Também reconhece
.gitattributespor diretório e.git/info/attributes
.lfsconfig
- Armazena configurações do Git LFS junto com o repositório
- Permite definir a URL do servidor LFS, número de tentativas de transferência etc.
- Exemplo:
[lfs] url = https://lfs.example.com/repo [lfs "transfer"] maxretries = 3
.gitattributesdefine quais arquivos serão tratados por LFS, e.lfsconfigcuida dos detalhes como a localização do servidor- Para mover arquivos já commitados para LFS, é necessário o comando
git lfs migrate
.gitmodules
- Armazena informações de configuração de submódulos
- Inclui caminho, URL e branch de cada módulo
- Exemplo:
[submodule "vendor/lib"] path = vendor/lib url = https://github.com/example/lib.git branch = main
- É criado com
git submodule adde consultado emgit submodule update - Em
git clone, os submódulos não são baixados automaticamente; é necessário usar a opção--recurse-submodules - Há desvantagens como não permitir rastrear faixas de versão e gerar diretórios
.gitaninhados
.mailmap
- Faz a unificação de nomes e e-mails de autores
- Exemplo:
Jane Developer <[email protected]> <[email protected]>
- Exemplo:
- Em
git log,git shortlog,git blameetc., os nomes passam a aparecer de forma unificada - O gráfico de contribuidores do GitHub não respeita mailmap
- A localização pode ser definida com
.mailmapou a configuraçãomailmap.file
.git-blame-ignore-revs
- Define a lista de commits a ignorar no
git blame- Exclui mudanças sem significado, como execução de formatadores ou aplicação de lint
- Exemplo:
# Ran prettier on entire codebase a1b2c3d4e5f6g7h8i9j0...
- Pode ser ativado com
git config blame.ignoreRevsFile .git-blame-ignore-revs - GitHub, GitLab (15.4+) e Gitea o reconhecem automaticamente
- Se o arquivo não existir, podem ocorrer erros; por isso, recomenda-se manter um arquivo vazio
.gitmessage
- Define um template de mensagem de commit
- Exemplo:
# <type>: <subject> # # Types: feat, fix, docs, style, refactor, test, chore
- Exemplo:
- Requer configuração com
git config commit.template .gitmessage - Após clonar, a configuração manual ainda é necessária; algumas equipes automatizam isso com husky e afins
- Como alternativa, é possível usar os hooks
commit-msgouprepare-commit-msg
Pastas de extensão por plataforma
- GitHub, GitLab, Gitea, Forgejo e Bitbucket usam suas próprias pastas de configuração
.github/,.gitlab/,.gitea/,.forgejo/,.bitbucket/
- Elas incluem workflows de CI/CD, templates de issue/PR, arquivos CODEOWNERS etc.
- O Forgejo faz fallback na ordem
.forgejo/ → .gitea/ → .github/, e o Gitea em.gitea/ → .github/ - O SourceHut usa
.build.ymlou.builds/*.yml
Outros arquivos convencionais
- .gitkeep: como o Git não rastreia diretórios vazios, é usado como arquivo fictício para manter o diretório
- .gitconfig: fornece exemplos de configuração de Git por projeto, mas não é carregado automaticamente
- .gitsigners: gerencia a lista de chaves de assinatura GPG/SSH e pode ser definido com
gpg.ssh.allowedSignersFile - .gitreview: arquivo de configuração do servidor de revisão de código Gerrit
- Exemplo:
[gerrit] host=review.opendev.org port=29418 project=openstack/nova.git defaultbranch=master
- Exemplo:
- .gitlint: define regras de lint para mensagens de commit
- Exemplo:
[general] ignore=body-is-missing [title-max-length] line-length=72
- Exemplo:
- .jj/: diretório de estado do Jujutsu, um VCS compatível com Git, que pode coexistir com
.git/
O ecossistema de dotfiles além do Git
- .editorconfig: mantém um estilo de código consistente entre editores
- Define indentação, finais de linha, codificação, remoção de espaços em branco etc.
- É suportado por editores principais como VS Code, Vim e Emacs
- .ruby-version, .node-version, .python-version: lidos por ferramentas de gerenciamento de versão de linguagem (como rbenv, nodenv, pyenv) para fazer troca automática
- .tool-versions: arquivo de gerenciamento de versões multilinguagem do asdf
- .dockerignore: define a lista de arquivos a excluir no build do Docker
- Usa a mesma sintaxe de padrões do
.gitignore, melhora a velocidade de build e evita incluir informações sensíveis
- Usa a mesma sintaxe de padrões do
Pontos a considerar ao desenvolver ferramentas integradas ao Git
- Ferramentas que lidam com repositórios Git precisam reconhecer estes arquivos obrigatoriamente
.gitignore: aplicar padrões ignorados ao explorar arquivos.gitattributes: distinguir binários e arquivos gerados.mailmap: exibir informações de autor de forma unificada.gitmodules: tratar submódulos
- O formato dos arquivos de configuração do Git segue a estrutura
[section "subsection"] key = value, e pode ser lido e gravado com o comandogit config - A maioria das bibliotecas Git para diferentes linguagens oferece suporte para fazer parse desse formato
2 comentários
Eu não conhecia o
gitmessage, mas acho que vou experimentar.Comentários do Hacker News
.gitignoree por isso não mostram arquivos ignorados na UI web, mas isso parece uma explicação erradaNa prática, eles não aparecem porque não fazem parte do repositório. Se um arquivo já foi commitado, eu diria que o correto é ele aparecer
.gitignore, ele continua aparecendo na UI. Isso acontece porque ele ainda faz parte do repoPor outro lado, também é possível forçar o commit de um arquivo ignorado desde o início, embora exija um pequeno truque
.gitignoresó decide se arquivos untracked devem ser ocultados. Se quiser, você pode commitar arquivos ignoradosshowinwebui=(true|false)😄.git/info/exclude. É um gitignore só local, feito para configurações minhasPor exemplo, é útil quando você cria arquivos temporários durante a investigação de um bug e quer mantê-los mesmo ao trocar de branch
Eu uso um alias de shell assim Assim dá para adicionar algo facilmente com
git-ignore-local myfile.extNo MacOS, basta ajustar a parte do
readlinkSe você registrar essa função no PATH comogit-ignore-local, pode usá-la comogit ignore-local.git/info/excludetambém é mencionado logo no começo da explicação do.gitignore/test export-ignoreao.gitattributes, dá para excluir arquivos de teste ao fazer deploy para servidores de produçãoQuando ferramentas de deploy como o Capistrano usam
git export, isso é aplicado automaticamente e os arquivos de teste não vão para o servidorIsso economiza espaço em disco sem afetar o desenvolvimento
git archiveQuase não vejo isso sendo usado nem em ferramentas básicas de CI. Foi com o Capistrano que vi esse uso pela primeira vez
Aliás, com a opção
export-substtambém dá para inserir informações parecidas comgit describediretamente dentro de um arquivojj, eu queria excluir completamente a pasta.jjdo repo e de todas as operações do gitInclusive para que ela não fosse apagada pelo
git clean -xdf. Por enquanto estou resolvendo com um alias temporáriogit clean -e .jj.git/info/exclude.mailmapA discussão relacionada está em GitHub Community Discussion
package-lock.json merge=oursPorque o significado de ours/theirs fica ambíguo em merge ou rebase
Esse tipo de configuração só faz sentido em ferramentas de merge automatizado, como a branch do git-annex
Referência: explicação do significado de ours/theirs, estrutura interna do git-annex
.git-blame-ignore-revsé um bom recurso, mas deveria ficar na seção de “outras convenções”Se ele não estiver configurado no cliente git, então em repositórios sem esse arquivo o git blame falha
(:optional)para evitar erro mesmo quando o arquivo não existeHá uma explicação em esta resposta no Stack Overflow
Só é uma pena que nem todas as ferramentas suportem
.mailmap. Por exemplo, o IntelliJ ainda trata isso como bug/pedido de recursoAlém disso,
.git-blame-ignore-revsé apenas uma convenção simples; ele só funciona se você configurar manualmente.ignoreEu achava que só o
.gitignorevalia, mas quando mudei as configurações do ripgrep em.ignore, os resultados da busca mudaram. No fim, fazia sentidoLink: post no nesbitt.io