Atributos de archivo
.gitattributes es el archivo de más valor que hay en git y que casi nadie
escribe. Es la forma que tiene un repositorio de enseñarle a git cosas sobre
su propio contenido: qué archivos son binarios, cuáles deberían concatenarse
en vez de entrar en conflicto, cuáles no salen nunca en un archivo comprimido,
qué finales de línea le tocan a cada cual.
Lo importante: se commitea. Una regla que añadas arregla el problema para todo el que clone, en cualquier sistema operativo, para siempre — al contrario que un ajuste en tu propia configuración, que te lo arregla a ti y deja que tus compañeros lo descubran por las malas.
⌘K → Atributos de archivo.

Qué hacen las reglas
| Atributo | Arregla |
|---|---|
text=auto eol=lf |
Finales de línea que cambian según quién hiciera el checkout del archivo |
binary |
Que git intente diffear o fusionar a tres bandas un PSD, un DOCX, un recurso compilado |
merge=union |
Un changelog al que todo el mundo añade líneas, y con el que todo el mundo entra en conflicto |
-merge |
Archivos donde una fusión a tres bandas produce sinsentidos — lockfiles, código generado |
export-ignore |
Configuración de CI y fixtures que se cuelan dentro del tarball de un release |
diff=<driver> |
Diffs ilegibles de formatos que sí son legibles, si hay un conversor |
filter=lfs |
Archivos grandes guardados vía LFS |
linguist-vendored |
Código vendorizado que cuenta como tuyo en las estadísticas de lenguajes |
binary es la forma corta de -diff -merge -text, que son tres respuestas a
"deja de hacer conjeturas sobre este archivo" en una sola palabra.
Edición
Los preajustes rellenan un patrón y sus atributos; edita el patrón antes de
añadirlo — CHANGELOG.md es una sugerencia, no una regla sobre tu proyecto.
Las ediciones son quirúrgicas. Añadir una regla para un patrón que ya tiene una reescribe esa línea donde está, en lugar de añadir al final una segunda regla que gana por venir después. Los comentarios del archivo sobreviven intactos, porque el "por qué" que hay junto a una regla suele valer más que la regla.
Cada guardado es una acción normal de Gitcito: sale su toast, y Deshacer restaura el archivo exactamente como estaba.
Un repositorio puede tener varios archivos de atributos. Uno en la raíz, uno
en cualquier subdirectorio, y un .git/info/attributes privado que no se
commitea nunca y solo aplica en tu máquina — el sitio adecuado para una regla
que va sobre ti, no sobre el proyecto. Gitcito los lista todos y dice cuál es
cuál.
¿Qué se aplica a una ruta?
Las reglas vienen de varios archivos, gana la más específica, y leerlos para
deducir la respuesta es adivinar. ¿Qué se aplica a una ruta? ejecuta
git check-attr y muestra lo que concluye el propio git — la única respuesta
que cuenta.
Drivers de diff: hacer legible un documento de Word
Un .docx es un zip. Un .pdf es un grafo de objetos comprimido. Git los
diffea por lo que son — ruido — así que el historial de un documento resulta
ilegible aunque el documento no lo sea.
Un driver de diff arregla esto con textconv: un comando que convierte el
archivo en texto solo a efectos del diff. El archivo de tu árbol de trabajo no
se toca; git se limita a comparar el texto convertido.
Dos mitades, y hacen falta las dos:
diff.<name>.textconven la configuración de git — el comando conversor.*.docx diff=<name>en.gitattributes— a qué archivos aplica.
Los botones de aquí hacen las dos cosas de golpe. Para Word, Excel, JSON y .strings,
Gitcito incluye el conversor él mismo — el mismo análisis de documentos que
usan sus vistas previas, expuesto como un pequeño comando gitcito-textconv
dentro de la app — así que esos cuatro funcionan sin instalar nada. El resto
sigue necesitando una herramienta real en tu PATH: Gitcito lo comprueba y deja
en gris lo que falta, en vez de escribir un driver que falla al primer diff.
| Driver | Necesita | Te da |
|---|---|---|
word |
nada — viene con Gitcito | Diffs de prosa de los .docx |
excel |
nada — viene con Gitcito | Diffs por filas (CSV por hoja) de los .xlsx/.xls |
json |
nada — viene con Gitcito | Diffs de JSON estables y con las claves ordenadas |
strings |
nada — viene con Gitcito | Diffs por líneas de un .strings en UTF-16, que git llama binario |
pdf |
pdftotext (poppler) |
Diffs de texto de los .pdf |
exif |
exiftool |
Qué cambió en una imagen, cuando los píxeles son opacos |
El que muerde en proyectos iOS
Localizable.strings va en UTF-16 durante casi toda la historia de Xcode, y
UTF-16 está lleno de bytes NUL, así que git lo llama binario y no muestra
nada:
diff --git a/Localizable.strings b/Localizable.strings
Binary files a/Localizable.strings and b/Localizable.strings differ
Y es justo el archivo donde más importa ver qué cadena movió alguien. El driver
strings lo descodifica solo para el diff — leyendo la marca de orden de bytes
en vez de suponerla, así que un .strings moderno en UTF-8 pasa intacto en vez
de convertirse en galimatías.
Los String Catalogs (.xcstrings, Xcode 15 en adelante) son JSON, y el driver
json los cubre: ordena las claves, así que una traducción añadida arriba deja
de reescribir el archivo entero en el diff.
Los límites del conversor incluido, dichos sin rodeos: .doc (el viejo formato
binario de Word) no se entiende, solo .docx; el PDF no está cubierto —
Gitcito previsualiza los PDF con el visor del navegador y no tiene extractor de
texto que reutilizar —; y cada diff de un documento paga un breve coste de
arranque del conversor. Con git config diff.<name>.cachetextconv true, git
cachea la salida por blob.
La mitad del conversor vive en tu configuración, no en el repositorio — git
no va a ejecutar comandos que te entregue un clon, y esa es una propiedad de
seguridad que merece la pena conservar. Los drivers incluidos, además, apuntan
a tu ruta de instalación de Gitcito, así que un compañero que clone recibirá
la regla diff=word y, hasta que conecte su propio conversor (Gitcito u otro),
el viejo diff ilegible. Dilo en tu README.
Filtros clean/smudge — con una prueba en seco primero
Un filtro reescribe el contenido al entrar y salir del repositorio: clean
se ejecuta al hacer stage (árbol de trabajo → repo), smudge en el checkout
(repo → árbol de trabajo). Así funciona git-lfs, y así eliminan los equipos las
credenciales o el ruido generado de lo que se commitea.
También es la cosa más peligrosa a la que puede apuntar .gitattributes: un
filtro se ejecuta en cada checkout de cada archivo que encaje, y uno mal
hecho corrompe tu árbol de trabajo en silencio. Por eso Gitcito se niega a ser
aquí un simple cuadro de texto. Configurar un
filtro pasa por una prueba en seco contra archivos reales de tu repositorio
que encajen con el patrón:
- El comando
cleanse ejecuta sobre una copia de cada archivo que encaje (hasta cinco) — nada del repositorio ni de su configuración se toca. - Si se da un comando
smudge, se ejecuta sobre la salida limpia y el resultado se compara byte a byte con el original — la comprobación de ida y vuelta. Un filtro que no completa la ida y vuelta significa que un checkout no restaurará lo que tenías. - Solo tras una prueba en seco con exactamente los valores que vas a guardar se activa el botón de guardar. Una prueba en seco fallida — error del comando, ningún archivo que encaje, o una ida y vuelta que difiere — aún se puede guardar, pero solo a través de una advertencia explícita que dice qué se puede perder.
Guardar escribe filter.<name>.clean/smudge en tu configuración local de
git y la regla filter=<name> en el archivo de atributos, y deja una entrada
de deshacer que restaura lo que la configuración tuviera antes. El interruptor
required establece filter.<name>.required, con el que git hace fallar la
operación en vez de dejar pasar los archivos en silencio cuando el filtro se
rompe.
Los límites, dichos sin rodeos: la prueba en seco muestrea hasta cinco archivos
que encajen, de como mucho 5 MB cada uno, con un límite de 10 segundos por
comando — un filtro que se porta bien con la muestra puede portarse mal con un
archivo que la muestra no vio. Los comandos viven en tu configuración, así
que un compañero que clone recibe la regla filter=<name> pero no los
comandos; sin ellos (y sin required) sus archivos pasan sin cambios.
Límites que conviene conocer
text=autocambia lo que se commitea, normalizando los finales de línea al entrar. En un repositorio ya existente, añádelo y luego ejecutagit add --renormalize .a conciencia, en un commit propio.- Los atributos no se aplican retroactivamente. Marcar hoy un archivo como
binaryno cambia cómo se guardaron sus diffs pasados; cambia cómo lo trata git a partir de ahora. - Las reglas solo hacen efecto donde el archivo es visible. Una regla en
design/.gitattributesno dice nada sobresrc/. - Gitcito escribe archivos enteros, así que un archivo formateado a mano vuelve
con su formato — pero una regla que Gitcito reescriba queda reformateada al
espaciado canónico de git,
pattern attr attr.
Ver también: LFS y checkout disperso · Bundles y archivos comprimidos · Opciones de merge · Hooks