25. Markdown y Git {#25-markdown-y-git}
Markdown y Git encajan porque ambos trabajan con texto plano. Un cambio en un párrafo produce una diferencia legible, no un binario opaco. Esa legibilidad es la base de la revisión: permite ver qué cambió, quién lo cambió y por qué.
Pero Git no está diseñado específicamente para prosa. Los saltos de línea, los conflictos de fusión y los archivos grandes requieren decisiones explícitas. Este capítulo recoge las que más afectan a un corpus Markdown.
25.1 Por qué encajan {#251-por-qué-encajan}
| Uso | Descripción |
|---|---|
| README | Puerta de entrada del repositorio |
| Commits | El mensaje es texto plano; la plataforma puede renderizar Markdown en la descripción de un PR, no en el mensaje del cliente git |
| Pull Requests | Descripción, comentarios y sugerencias en GFM |
| Issues | Cuerpos en GFM; plantillas en .github/ISSUE_TEMPLATE/ |
| Wiki | Repositorio Git aparte (repo.wiki.git) con páginas Markdown |
| Documentación versionada | Docs as code: misma rama, misma revisión y mismo CI que el código |
| Historial | git log -p -- docs/uso.md muestra la evolución |
| Ramas | La documentación de una función viaja en la rama de esa función |
| Revisión | Los cambios se revisan en un PR como cualquier código |
El beneficio no es solo técnico: obliga a que la documentación tenga un proceso. Un cambio de comportamiento y su documentación pueden revisarse juntos, y el historial conserva por qué se tomó una decisión.
25.2 Qué versionar y qué no {#252-qué-versionar-y-qué-no}
Versiona:
- Archivos
.md, imágenes fuente y diagramas editables. - Plantillas, configuraciones y scripts de generación.
- El archivo
README.md, la licencia y la guía de contribución.
No versiones:
- Salidas generadas (
_site/,dist/, PDF construidos en CI). - Cachés, credenciales, archivos de entorno y datos personales.
- Binarios enormes que no necesitan historial.
La regla práctica: si se puede regenerar, no se versiona. Si un PDF tarda segundos en generarse, no hace falta guardarlo; si es el entregable que se publica, puede tener sentido adjuntarlo a una release.
25.3 Una frase por línea {#253-una-frase-por-línea}
Escribir una frase por línea (semantic line breaks) hace que las diferencias de Git sean más precisas. En lugar de un párrafo completo en una línea, cada frase ocupa la suya:
Markdown es un lenguaje de marcado ligero.
Permite escribir texto con estructura y convertirlo a HTML.
El texto fuente sigue siendo legible sin renderizar.
Si cambias la segunda frase, el diff muestra una línea modificada, no un párrafo entero. En prosa revisada por varias personas, esto reduce el ruido y facilita la revisión.
No es una obligación de Markdown: el render une las líneas en un párrafo. Es una convención de escritura que mejora el trabajo con Git. Algunos editores y formateadores pueden reflowar el texto; si el equipo adopta la convención, conviene desactivar el reflow automático o aplicarlo solo al guardar de forma consciente.
25.4 Finales de línea y .gitattributes {#254-finales-de-línea-y-gitattributes}
Windows y Unix usan finales de línea distintos. Git puede normalizarlos, pero la configuración global de cada persona no basta: el repositorio debe declarar la regla.
# Normalizar Markdown a LF en el repositorio
*.md text eol=lf
# Usar el driver de diff de Markdown
*.md diff=markdown
# Tratar binarios como binarios
*.png binary
*.jpg binary
*.pdf binary
textindica que el archivo es texto.eol=lffuerza LF en el árbol de trabajo al hacer checkout.binaryevita conversiones y diffs de texto.diff=markdownusa el driver integrado de Git para resaltar mejor los cambios.
En Windows, core.autocrlf puede entrar en conflicto con .gitattributes. Cuando ambos existen, las reglas del repositorio tienen prioridad, pero conviene documentar la configuración y comprobar el resultado con git diff --check.
25.5 Conflictos de fusión {#255-conflictos-de-fusión}
Un conflicto ocurre cuando dos ramas cambian la misma región. En Markdown son frecuentes porque dos personas editan el mismo párrafo o la misma lista.
<<<<<<< HEAD
El comando se ejecuta con privilegios de administrador.
=======
El comando requiere privilegios de administrador.
>>>>>>> rama
Pasos para resolverlo:
- Entiende el contexto:
git log --merge -p -- archivo.md. - Elige o combina: no te limites a borrar marcas; reescribe la frase final.
- Comprueba el render: un conflicto mal resuelto puede dejar una tabla rota.
- Marca como resuelto:
git add archivo.md. - Ejecuta las pruebas y el linting antes de continuar.
Ayudas útiles:
git checkout --conflict=diff3 -- archivo.mdmuestra también la versión base.git rererereutiliza resoluciones anteriores de conflictos similares.git merge --abortcancela la fusión y vuelve al estado anterior.
El atributo merge=union combina automáticamente las líneas de ambas ramas, pero suele duplicar frases y no es adecuado para prosa. Úsalo solo en archivos donde la unión sea segura, como listas de entradas independientes.
25.6 Revisar diferencias {#256-revisar-diferencias}
| Comando | Para qué |
|---|---|
git diff |
Cambios no preparados |
git diff --staged |
Cambios preparados |
git diff --word-diff |
Diferencias por palabra |
git diff --color-words |
Igual, con color en el terminal |
git diff --stat |
Resumen por archivo |
git log -p --follow -- docs/uso.md |
Historial con cambios, siguiendo renombrados |
git blame -w -C -C -C -- docs/uso.md |
Autoría por línea, ignorando espacios y detectando movimientos |
git blame no es una herramienta para culpar: sirve para encontrar el contexto de una línea. Combínalo con git log para leer el commit completo, no solo el fragmento.
Antes de abrir un PR, revisa el diff tú mismo. Un cambio de una palabra puede alterar el significado de una instrucción; el diff es el último punto donde se detecta sin publicar.
25.7 Renombrados y enlaces {#257-renombrados-y-enlaces}
Git detecta renombrados por similitud, pero no actualiza los enlaces de Markdown. Si mueves un archivo:
- Usa
git mv viejo.md nuevo.mdpara conservar el historial. - Busca referencias al nombre antiguo en todo el repositorio.
- Actualiza los enlaces relativos y las anclas.
- Añade una redirección si la URL pública cambia.
- Comprueba el sitio generado, no solo el editor.
git mv docs/instalacion.md docs/inicio/instalacion.md
rg "instalacion\.md" -n
git log --follow -- docs/inicio/instalacion.md sigue el historial a través del renombrado, aunque no es infalible si el archivo cambió mucho. El capítulo 63 trata las redirecciones desde el punto de vista del sitio publicado.
25.8 Archivos grandes con Git LFS {#258-archivos-grandes-con-git-lfs}
Las imágenes, los vídeos y los PDF pueden inflar el repositorio. Git LFS (Large File Storage) guarda un puntero en Git y el archivo en un almacenamiento aparte:
git lfs install
git lfs track "*.mp4"
git lfs track "*.psd"
git add .gitattributes
git lfs trackescribe las reglas en.gitattributes; versiona ese archivo.- Los clones necesitan
git lfs instally acceso al servidor LFS. - GitHub, GitLab y otros hosts tienen cuotas y límites; compruébalos antes de subir.
- LFS no sustituye una política de assets: si un vídeo no necesita historial, publícalo fuera del repositorio.
Para imágenes pequeñas de documentación, un PNG optimizado suele ser suficiente; LFS añade complejidad y dependencia del host.
25.9 Commits, firma y revisión {#259-commits-firma-y-revisión}
Un mensaje de commit útil explica qué y por qué, no solo «cambios»:
docs(instalacion): aclarar requisitos de Linux
Separa los requisitos de sistema de los pasos de instalación.
Añade verificación con `ejemplo --version`.
- Conventional Commits es una convención opcional; si se adopta, documenta los tipos y el alcance.
- Firma de commits:
git commit -Sfirma con GPG o SSH;git config commit.gpgsign truelo hace por defecto. La plataforma muestra el estado de verificación. - Sign-off:
git commit -sañade la líneaSigned-off-by, usada por proyectos con DCO. - Revisión: una persona distinta del autor aprueba los cambios sustantivos; los arreglos triviales pueden tener un flujo más ligero.
El capítulo 26 describe las plantillas y la revisión en GitHub; el 62, la propiedad y la revisión programada.
25.10 Lista de comprobación {#2510-lista-de-comprobación}
- El repositorio tiene
.gitattributescon finales de línea y binarios. - Los archivos generados no se versionan.
- El equipo conoce la convención de una frase por línea (si se adopta).
- Los conflictos se resuelven reescribiendo, no borrando marcas a ciegas.
- Los renombrados actualizan enlaces y redirecciones.
- Las imágenes y vídeos grandes tienen una política (LFS o externa).
- Los mensajes de commit explican el cambio.
- Los commits importantes están firmados o tienen sign-off, si el proyecto lo exige.
- El diff se revisa antes de abrir el PR.
- El linting y la validación de enlaces se ejecutan en CI.