.gitattributes
Aprenda a usar o .gitattributes para controlar finais de linha, diffs, estratégias de merge e exportação por caminho de arquivo. Com exemplos.
O que o .gitattributes faz
Um arquivo .gitattributes diz ao Git como tratar arquivos específicos com base no caminho deles. Enquanto o .gitignore decide se o Git rastreia um arquivo, o .gitattributes decide como o Git lida com os arquivos que ele rastreia — como normalizar finais de linha, como exibir diffs, como fazer merge e o que fazer no momento da exportação. Ele fica no seu repositório e é confirmado com commit, de modo que todos os colaboradores obtêm o mesmo comportamento, independentemente das suas configurações pessoais do Git config.
Esta página aborda o formato do arquivo, os atributos mais comuns (normalização de finais de linha, marcação de binários, drivers personalizados de diff/merge e export-ignore), onde o Git procura o arquivo e como regras conflitantes são resolvidas.
Formato do arquivo
Cada linha combina um padrão de arquivo com um ou mais atributos:
# pattern attributes
*.txt text
*.png binary
*.sh text eol=lfOs padrões seguem as mesmas regras de glob do .gitignore: * corresponde a qualquer coisa exceto /, ** corresponde entre diretórios, um / no início ancora ao diretório do arquivo .gitattributes, e linhas que começam com # são comentários. Cada atributo após o padrão assume uma das quatro formas:
- Definido —
textativa o atributo. - Desativado —
-texto desativa (o traço inicial). - Valor —
eol=lfdefine um valor específico. - Não especificado —
!textlimpa qualquer configuração anterior, deixando o padrão do Git.
Onde o Git procura o arquivo
A maioria dos projetos mantém um único .gitattributes na raiz do repositório. Mas o Git verifica vários locais, e uma regra em um diretório mais profundo substitui uma em nível mais alto:
- Um
.gitattributesem qualquer diretório se aplica aos arquivos naquele diretório e abaixo. $GIT_DIR/info/attributescontém regras que não são confirmadas com commit (locais ao seu clone).core.attributesFile(geralmente~/.config/git/attributes) define padrões por usuário.
Quando duas regras podem corresponder ao mesmo arquivo, o caminho mais específico tem prioridade e, dentro de um arquivo, a última linha correspondente vence. Você pode inspecionar o resultado para qualquer caminho com git check-attr:
git check-attr -a README.md
# README.md: text: autoNormalizando finais de linha
O uso mais comum do .gitattributes é acabar com a bagunça de "cada linha alterada" que acontece quando desenvolvedores Windows e Unix compartilham um repositório. Marcar arquivos como text permite que o Git normalize os finais de linha para LF no repositório e os converta no checkout:
* text=auto
*.sh text eol=lf
*.bat text eol=crlftext=auto deixa o Git decidir quais arquivos são texto e armazená-los com LF no repositório; as configurações explícitas de eol forçam uma terminação específica no checkout para arquivos que precisam disso (scripts shell devem permanecer com LF, arquivos batch do Windows devem permanecer com CRLF). Como as regras são confirmadas com commit, isso é mais confiável do que depender da configuração core.autocrlf de cada desenvolvedor, que varia de máquina para máquina.
Se você adicionar * text=auto a um repositório existente, os arquivos já confirmados com CRLF não serão renormalizados automaticamente. Execute uma limpeza única para que o próximo commit os corrija:
git add --renormalize .
git commit -m "Normalize line endings"Marcando arquivos como binários
Dizer ao Git que um arquivo é binário impede que ele tente exibir um diff textual ou fazer merge linha por linha:
*.pdf binary
*.png binaryO atributo binary é uma macro integrada que se expande para -text -diff, desabilitando a conversão de finais de linha e o diff textual. Isso evita que o Git corrompa um arquivo com reescrita de finais de linha e impede que git diff despeje bytes ilegíveis no terminal.
Para binários grandes como vídeos, conjuntos de dados ou arquivos de design, marcá-los como binários não é suficiente — eles ainda incham o histórico do repositório. Armazene-os com o Git LFS, que o .gitattributes também é usado para configurar.
Comportamento personalizado de diff e merge
O .gitattributes pode encaminhar determinados arquivos para drivers personalizados de diff ou merge, mas um driver personalizado precisa ser definido na sua configuração do Git primeiro — o atributo apenas o referencia pelo nome.
Um caso comum é um arquivo de lock gerado: durante um conflito de merge, você quer manter a versão do seu branch integralmente, em vez de fazer merge linha por linha. Registre um driver ours uma vez e aponte o caminho para ele:
git config merge.ours.driver true# .gitattributes
package-lock.json merge=oursDefinir driver como true significa "o merge sempre é bem-sucedido e o resultado é a versão do branch atual." (Este atributo merge=ours por arquivo é independente da estratégia de merge -s ours, que se aplica a um merge inteiro.)
Um driver personalizado de diff funciona da mesma forma e é útil para formatos não textuais. O Git também inclui drivers de diff integrados que produzem cabeçalhos de trecho significativos para linguagens comuns, de modo que um diff mostra qual função foi alterada:
*.c diff=cpp
*.py diff=pythonConsulte git diff para ver como esses drivers moldam a saída.
Export-ignore
Quando alguém baixa um arquivo de release via git archive, geralmente você quer excluir os arquivos de desenvolvimento. O atributo export-ignore faz exatamente isso:
/tests export-ignore
/.github export-ignore
.gitattributes export-ignoreIsso mantém suítes de teste, configurações de CI e arquivos de editor fora do tarball que git archive produz, para que os consumidores baixem apenas o que precisam. Um atributo relacionado, export-subst, expande marcadores como $Format:%H$ dentro dos arquivos exportados para que um arquivo compactado possa registrar o commit a partir do qual foi criado.
Atributos comuns
| Atributo | Efeito |
|---|---|
text | Normaliza os finais de linha para LF no repositório. |
eol=lf / eol=crlf | Força um final de linha específico no checkout. |
binary | Trata o arquivo como binário — sem diff, sem conversão de final de linha. |
merge=<driver> | Usa uma estratégia de merge personalizada para o arquivo. |
diff=<driver> | Usa um driver de diff personalizado. |
export-ignore | Exclui o caminho das exportações do git archive. |
export-subst | Expande marcadores $Format:…$ em arquivos exportados. |
Quando usar
Recorra ao .gitattributes sempre que o comportamento do Git por arquivo precisar ser igual para todos no time, em vez de ficar sujeito às configurações locais. Os ganhos do dia a dia são: normalizar finais de linha em equipes mistas Windows/Unix, silenciar diffs inúteis em binários e reduzir os arquivos de release. Os ganhos avançados — drivers personalizados de merge/diff e Git LFS — resolvem pontos específicos de dor quando um projeto os encontra. Comece com * text=auto e adicione regras conforme problemas concretos aparecerem.