.gitattributes
Impara a usare .gitattributes per controllare fine riga, diff, strategie di merge ed esportazione per percorso file. Con esempi pratici.
Cosa fa .gitattributes
Un file .gitattributes indica a Git come trattare file specifici in base al loro percorso. Mentre .gitignore decide se Git traccia un file, .gitattributes decide come Git gestisce i file che traccia — come normalizzare i fine riga, come eseguire il diff, come fare il merge e cosa fare al momento dell'esportazione. Risiede nel repository ed è committato, quindi ogni collaboratore ottiene lo stesso comportamento, indipendentemente dalla propria configurazione Git personale.
Questa pagina tratta il formato del file, gli attributi più comuni (normalizzazione dei fine riga, marcatura dei binari, driver personalizzati per diff/merge e export-ignore), dove Git cerca il file e come vengono risolte le regole in conflitto.
Formato del file
Ogni riga associa un pattern di file a uno o più attributi:
# pattern attributes
*.txt text
*.png binary
*.sh text eol=lfI pattern seguono le stesse regole glob di .gitignore: * corrisponde a qualsiasi cosa tranne /, ** corrisponde attraverso le directory, un / iniziale ancora al directory del file .gitattributes, e le righe che iniziano con # sono commenti. Ogni attributo dopo il pattern assume una di queste quattro forme:
- Set —
textattiva l'attributo. - Unset —
-textlo disattiva (il trattino iniziale). - Valore —
eol=lfimposta un valore specifico. - Non specificato —
!textcancella qualsiasi impostazione precedente, lasciando il comportamento predefinito di Git.
Dove Git lo cerca
La maggior parte dei progetti mantiene un singolo .gitattributes nella radice del repository. Ma Git controlla diverse posizioni, e una regola in una directory più profonda sovrascrive quella in una più alta:
- Un
.gitattributesin qualsiasi directory si applica ai file in quella directory e nelle sottodirectory. $GIT_DIR/info/attributescontiene regole che non vengono committate (locali al proprio clone).core.attributesFile(spesso~/.config/git/attributes) imposta i valori predefiniti per utente.
Quando due regole potrebbero corrispondere allo stesso file, vince il percorso più specifico e, all'interno di un singolo file, vince l'ultima riga corrispondente. È possibile ispezionare il risultato per qualsiasi percorso con git check-attr:
git check-attr -a README.md
# README.md: text: autoNormalizzazione dei fine riga
L'uso più comune di .gitattributes è porre fine al caos del "tutte le righe modificate" che si verifica quando sviluppatori Windows e Unix condividono un repository. Marcare i file come text permette a Git di normalizzare i fine riga a LF nel repository e di convertirli al checkout:
* text=auto
*.sh text eol=lf
*.bat text eol=crlftext=auto lascia a Git il compito di decidere quali file sono testo e li memorizza con LF nel repository; le impostazioni esplicite eol forzano poi un fine riga specifico al checkout per i file che ne hanno bisogno (gli script shell devono rimanere LF, i file batch Windows devono rimanere CRLF). Poiché le regole sono committate, questo approccio è più affidabile che affidarsi all'impostazione core.autocrlf di ogni sviluppatore, che varia da macchina a macchina.
Se si aggiunge * text=auto a un repository esistente, i file già committati con CRLF non verranno rinormalizzati automaticamente. Eseguire una pulizia una tantum affinché il commit successivo li corregga:
git add --renormalize .
git commit -m "Normalize line endings"Marcare i file come binari
Indicare a Git che un file è binario gli impedisce di tentare di mostrare un diff testuale o di fare il merge riga per riga:
*.pdf binary
*.png binaryL'attributo binary è una macro integrata che si espande in -text -diff, disabilitando la conversione dei fine riga e il diff testuale. Questo impedisce a Git di corrompere un file con riscritture dei fine riga e blocca git diff dal riversare nel terminale un'incomprensibile sequenza di byte.
Per i binari di grandi dimensioni come video, dataset o file di design, marcarli come binari non è sufficiente — gonfiano comunque la cronologia del repository. In questi casi, archiviarli con Git LFS, che .gitattributes viene anche usato per configurare.
Comportamento personalizzato per diff e merge
.gitattributes può instradare determinati file attraverso driver personalizzati per diff o merge, ma un driver personalizzato deve essere definito prima nella configurazione Git — l'attributo lo referenzia solo per nome.
Un caso comune è un file lock generato automaticamente: durante un conflitto di merge si vuole mantenere la versione del proprio branch nella sua interezza anziché fare il merge riga per riga. Registrare un driver ours una volta, poi puntare il percorso su di esso:
git config merge.ours.driver true# .gitattributes
package-lock.json merge=oursImpostare driver su true significa "il merge ha sempre successo e il risultato è la versione del branch corrente." (Questo attributo per file merge=ours è indipendente dalla strategia di merge -s ours, che si applica all'intero merge.)
Un driver diff personalizzato funziona allo stesso modo ed è utile per formati non testuali. Git include anche driver diff integrati che producono intestazioni di hunk significative per i linguaggi comuni, così il diff mostra quale funzione è cambiata:
*.c diff=cpp
*.py diff=pythonVedi git diff per come questi driver influenzano l'output.
Export-ignore
Quando qualcuno scarica un archivio di rilascio tramite git archive, spesso si desidera escludere i file di sviluppo. L'attributo export-ignore fa esattamente questo:
/tests export-ignore
/.github export-ignore
.gitattributes export-ignoreQuesto mantiene fuori dal tarball prodotto da git archive le suite di test, la configurazione CI e i file dell'editor, in modo che i destinatari scarichino solo ciò di cui hanno bisogno. Un attributo correlato, export-subst, espande segnaposto come $Format:%H$ nei file esportati, così un archivio può registrare il commit da cui è stato costruito.
Attributi comuni
| Attributo | Effetto |
|---|---|
text | Normalizza i fine riga a LF nel repository. |
eol=lf / eol=crlf | Forza un fine riga specifico al checkout. |
binary | Tratta il file come binario — nessun diff, nessuna conversione dei fine riga. |
merge=<driver> | Usa una strategia di merge personalizzata per il file. |
diff=<driver> | Usa un driver diff personalizzato. |
export-ignore | Esclude il percorso dalle esportazioni di git archive. |
export-subst | Espande i segnaposto $Format:…$ nei file archiviati. |
Quando usarlo
Ricorrere a .gitattributes ogni volta che il comportamento di Git per singolo file deve essere uguale per tutti i membri del team, anziché lasciarlo alle impostazioni locali. I vantaggi quotidiani sono la normalizzazione dei fine riga in un team misto Windows/Unix, l'eliminazione di diff inutili sui binari e la riduzione degli archivi di rilascio. I vantaggi avanzati — driver personalizzati per merge/diff e Git LFS — risolvono problemi specifici quando un progetto li incontra. Iniziare con * text=auto e aggiungere regole man mano che emergono problemi concreti.