Parte: 15 — Herramientas, editores y automatización (tooling) · Fuente: Documentación de Git LFS, GitHub (Working with large files) y Godot 4 (Version control systems) ⏱️ Duración estimada: 75 min · Nivel: Avanzado
Un juego no es solo código: son texturas, audio, mallas y escenas que pesan y cambian a menudo. Git, pensado para texto, se atraganta con binarios grandes y con las escenas de Godot cuando dos personas las tocan a la vez. En esta clase montamos un flujo de versionado de equipo apto para juegos: Git LFS para los binarios, un .gitattributes bien afinado, ramas por feature y las buenas prácticas que hacen que un .tscn casi nunca genere un conflicto imposible.
Aprenderás a rastrear assets pesados con LFS sin inflar el historial, a organizar el trabajo en ramas de característica que se integran con revisión, y —lo más valioso— a prevenir conflictos de escena manteniéndolas pequeñas y modulares, además de resolver uno cuando aparezca. El resultado es un repositorio donde varios desarrolladores avanzan sin pisarse.
Al finalizar, el alumno podrá:
.gitattributes.| # | Tema | Por qué importa |
|---|---|---|
| 1 | Git y los binarios | Git guarda cada versión completa; los binarios inflan el repo. |
| 2 | Git LFS | Sustituye el binario por un puntero y guarda el archivo aparte. |
| 3 | .gitattributes |
Declara qué rastrea LFS y cómo trata cada tipo de archivo. |
| 4 | Ramas por feature | Aíslan el trabajo en curso del código estable. |
| 5 | Pull requests y revisión | Integran cambios con una comprobación humana y de CI. |
| 6 | Conflictos en escenas | Los .tscn son texto, pero difíciles de fusionar a mano. |
| 7 | Escenas pequeñas y modulares | Reducen la superficie de colisión entre compañeros. |
| 8 | Estrategia ante conflicto | A veces rehacer es más seguro que fusionar. |
.gitattributes: archivo que asigna atributos por patrón de ruta (qué va a LFS, fin de línea, merge). Clave: se versiona y aplica a todo el equipo.main. Clave: aísla el trabajo hasta que está listo.PackedScene): escena pequeña reutilizable e instanciable. Clave: menos gente edita el mismo archivo a la vez..tscn: formato de texto de las escenas de Godot. Clave: es diffable, pero los IDs internos complican la fusión manual.Necesitas Git y el binario de Git LFS instalado (git lfs version debe responder). En Windows viene con Git for Windows; en Linux/macOS se instala aparte. Trabaja sobre un repositorio de Godot con una carpeta assets/ que contenga imágenes y audio de prueba.
Godot guarda escenas (.tscn) y recursos (.tres) como texto por defecto, lo que ayuda al diff; conviene mantenerlo así en Project Settings en vez de usar formato binario. La guía oficial de Git LFS está en https://git-lfs.com/ y las recomendaciones de Godot sobre control de versiones en https://docs.godotengine.org/en/stable/tutorials/best_practices/version_control_systems.html.
Vamos a configurar LFS, montar un flujo de ramas y provocar/resolver un conflicto de escena controlado.
.gitattributes:git lfs install # una sola vez por maquina
git lfs track "*.png" "*.jpg" "*.webp"
git lfs track "*.wav" "*.ogg" "*.mp3"
git lfs track "*.glb" "*.blend" "*.exr"
cat .gitattributes
# *.png filter=lfs diff=lfs merge=lfs -text
# *.ogg filter=lfs diff=lfs merge=lfs -text
# ...
git add .gitattributes
git commit -m "Configurar Git LFS para assets binarios"
cp ~/texturas/heroe.png assets/heroe.png
git add assets/heroe.png
git commit -m "Anadir textura del heroe"
git lfs ls-files # lista los archivos rastreados por LFS
# 3a4b1c2d * assets/heroe.png
.gitattributes para las escenas: márcalas como texto y evita normalizaciones raras de fin de línea que ensucian los diffs:cat >> .gitattributes <<'EOF'
# Escenas y recursos de Godot: texto, diff legible, sin conversion CRLF
*.tscn text eol=lf
*.tres text eol=lf
*.gd text eol=lf
EOF
git add .gitattributes
git commit -m "Tratar escenas y scripts como texto LF"
git switch -c feature/menu-pausa # rama de una tarea concreta
# ...editas escenas y scripts del menu de pausa...
git add . && git commit -m "Menu de pausa funcional"
git push -u origin feature/menu-pausa
# Luego abres un Pull Request hacia main para revision + CI
.tscn, al fusionar aparece el conflicto. Para escenas modulares y diminutas, lo pragmático suele ser quedarse con una versión y reaplicar el cambio menor:git switch main
git merge feature/menu-pausa
# CONFLICT (content): Merge conflict in ui/menu.tscn
git checkout --theirs ui/menu.tscn # toma la version de la rama entrante
# ...reabres la escena en Godot, reaplicas a mano el ajuste que faltaba...
git add ui/menu.tscn
git commit -m "Resolver conflicto de menu.tscn tomando la rama feature"
La lección observable: los binarios viajan por LFS sin inflar el historial, cada tarea vive en su rama, y como las escenas son pequeñas y modulares, el único conflicto se resuelve tomando una versión y reaplicando un retoque menor en el editor. Cuanto más grande fuera esa escena, más doloroso sería.
.gitattributes el rastreo LFS de *.ttf y *.mp4, confírmalo y verifica con git lfs ls-files.git lfs migrate import --include="*.png" en una rama de prueba.PackedScene instanciadas y explica cómo reduce la probabilidad de conflicto.main y comprueba que no hay conflicto.main en GitHub que exija PR y checks verdes antes de fusionar.Configura un repositorio de juego con Git LFS rastreando al menos tres tipos de asset binario vía .gitattributes, un flujo de ramas por feature documentado, y demuestra la resolución de un conflicto de escena provocado a propósito. Entrega el .gitattributes y el historial que evidencie la resolución.
Criterio de aceptación: git lfs ls-files muestra los assets binarios gestionados por LFS (no como blobs en el historial), existe al menos una rama feature/* integrada por fusión, y el log documenta un conflicto de .tscn resuelto con un commit de merge explicado; las escenas del proyecto son pequeñas y modulares en lugar de una única escena monolítica.
| Síntoma | Causa y arreglo |
|---|---|
| El repo pesa gigas pese a usar LFS | Añadiste .gitattributes después de commitear binarios. Migra con git lfs migrate import para reescribir el historial. |
| Al clonar, los assets son archivos de texto de 130 bytes | Falta git lfs pull o LFS no está instalado en esa máquina. Instálalo y ejecuta git lfs pull. |
Conflictos constantes en un .tscn enorme |
La escena es monolítica. Divídela en subescenas instanciadas para que cada uno toque partes distintas. |
| Diffs de escena llenos de cambios de fin de línea | Falta eol=lf en .gitattributes. Decláralo y renormaliza con git add --renormalize .. |
git lfs track no surte efecto |
Rastreaste tras commitear el archivo. Los patrones solo afectan a lo que se añade después; re-añade el archivo. |
❓ ¿Puedo fusionar automáticamente dos escenas en conflicto? No de forma fiable: los IDs internos de nodos y sub-recursos hacen que la fusión textual sea arriesgada. Por eso se prioriza prevenir con escenas pequeñas.
❓ ¿LFS tiene coste? El almacenamiento y ancho de banda de LFS en GitHub tienen cuota gratuita y luego se paga. Alternativas self-hosted evitan ese coste.
❓ ¿Debo usar formato binario para escenas (.scn) para acelerar? No para el desarrollo compartido: el texto (.tscn) permite diffs y revisión. El binario solo tiene sentido en exportación, no en el repo.
❓ ¿Qué va a LFS y qué no? A LFS: imágenes, audio, vídeo, mallas, fuentes, .blend. En Git normal: scripts, escenas, recursos de texto y configuración, que son pequeños y diffables.
Clase 262 - Integración continua (CI) para juegos