Domando la Complejidad del Proyecto - La Saga¶
Control de versiones del entorno de desarrollo sin contaminar tu repositorio principal
A medida que los proyectos evolucionan, especialmente las bases de conocimiento o los sitios de documentación que involucran múltiples herramientas como MkDocs, Obsidian, scripts personalizados e IDEs especializados como Cursor, la complejidad aumenta naturalmente. La integración de estas herramientas crea flujos de trabajo potentes, pero también introduce un nuevo desafío: gestionar el número creciente de archivos de configuración, borradores, scripts y documentos de planificación que respaldan el proyecto principal.
El Punto Crítico: Cuando .gitignore No Es Suficiente¶
Recientemente alcancé un hito doloroso que muchos desarrolladores encuentran: perder varias horas de trabajo. ¿El culpable? Archivos cruciales para mi flujo de trabajo de desarrollo no estaban bajo control de versiones.
Como muchos, quería mantener limpio mi repositorio público de GitHub. Para este proyecto, esto significaba confirmar solo el contenido principal de Markdown y los archivos esenciales de MkDocs necesarios para construir el sitio web. Todo lo demás –la configuración de mi bóveda de Obsidian, la configuración de Cursor, los scripts de traducción de borradores, las notas de planificación de tareas– estaba diligentemente listado en .gitignore. Esto mantenía ordenado el repositorio principal, pero dejaba mi andamiaje vital de desarrollo desprotegido.
Esta llamada de atención ocurrió relativamente pronto, afortunadamente. Mientras trabajaba en la integración de herramientas de traducción y planificaba el flujo de trabajo utilizando notas dentro de la estructura de mi proyecto, un percance sobrescribió un trabajo de planificación significativo. Frustrante, sí, pero una lección valiosa aprendida antes de que las apuestas fueran más altas.
Buscando una Solución: Los Intentos Fallidos¶
Mis ideas iniciales giraban en torno a usar Git de manera más inteligente, pero me encontré con obstáculos.
Intento 1: Repositorios Anidados - La Pesadilla del Cambio de Ramas¶
Mi primer pensamiento fue explorar formas de tener múltiples historiales de Git dentro del mismo directorio de proyecto, quizás usando repositorios anidados. La idea era tener un repositorio "dev" de nivel superior que rastreara todo (configuraciones del IDE, borradores, archivos del repositorio interno) mientras que el repositorio "público" interno contenía solo los archivos limpios y desplegables del proyecto. El repositorio externo ignoraría el directorio .git del repositorio interno.
En teoría, esto sonaba como un enfoque en capas ordenado. Sin embargo, cuando intenté configurarlo, muy pronto me di cuenta de que no funcionaba. En primer lugar, Git no admite realmente repositorios anidados, al menos no de la manera que yo imaginaba. Y tiene sentido. Hay una advertencia en la que no había pensado: digamos que estoy trabajando en el repositorio interno (docs-nica) y cambio a una rama diferente. Ahora todos los archivos en esa carpeta cambian (para reflejar la rama), pero el repositorio externo (docs-nica-dev) todavía está en su rama principal. El repositorio externo ahora ve todos estos cambios de archivos y piensa que son cambios en su rama principal... Es claramente visible por qué esto es un problema. Bien, así que este enfoque no funcionaba.
Intento 2: Repositorios Separados + Hooks de Git - La Catástrofe de la Copia¶
De vuelta a la mesa de dibujo. Mi siguiente idea fue tener dos repositorios completamente separados. Uno de dev que contiene todo lo que necesito (scripts, notas, configuraciones, y los archivos principales del proyecto). Y uno public que solo contiene el contenido Markdown y la configuración de MkDocs – solo lo esencial, tal como está previsto para el despliegue.
Pero aquí viene el problema: si cambiamos algo en el repositorio public (quizás una corrección rápida directamente allí, o al traer cambios de colaboradores), ¿cómo debería saberlo el repositorio dev? Y más comúnmente, ¿cómo se reflejan los cambios en dev en public? Necesitamos alguna forma de vincularlos.
La primera idea fue usar hooks de GitHub (o hooks de Git locales). Estos te permiten definir comandos para ejecutar después de ciertas acciones de Git, como un commit. Configuré un hook que, después de un commit en el repositorio dev, básicamente copiaría los archivos relevantes (la carpeta docs/, mkdocs.yml, etc.) al directorio del repositorio public.
Parecía funcionar a primera vista, pero este enfoque tenía dos problemas principales:
- Historial Ruidoso: El hook copiaba todos los archivos relevantes en cada commit. Esto significaba que el repositorio
publicsiempre pensaba que todo su contenido había cambiado. Aunque técnicamente no rompía nada, el historial de commits se volvió menos útil, mostrando cientos (o miles) de archivos cambiados en cada commit, haciendo imposible identificar instantáneamente qué contenidos de archivo realmente cambiaron. - Ceguera ante Eliminaciones: El script solo copiaba archivos. Si eliminaba un archivo o carpeta en el repositorio
dev, este cambio no se reflejaría en el repositoriopublic. El archivo antiguo simplemente permanecería allí.
Maldición, ya había pasado horas en esto – y todavía no hay una solución funcional.
El Avance: Repositorios Separados + Sincronización de Archivos¶
Entonces recordé un software de código abierto que había probado hace mucho tiempo para sincronizar carpetas locales: FreeFileSync. Si bien es desafortunado agregar otro conjunto de herramientas/software a la pila necesaria, en realidad logró exactamente lo que quería.
La configuración ahora implica:
- Dos repositorios Git separados:
docs-nica-dev(que contiene todo) ydocs-nica(la versión pública y limpia). - FreeFileSync: Se utiliza para definir las reglas de cómo sincronizar las carpetas específicas (como
docs/, archivos de tema,mkdocs.yml) entre las dos ubicaciones de los repositorios. Puede manejar sincronizaciones bidireccionales, duplicación y, lo más importante, propagar eliminaciones correctamente. - RealTimeSync (parte de FreeFileSync): Se utiliza para monitorear las carpetas definidas en busca de cambios y activar la sincronización automáticamente según las reglas de FreeFileSync.
Esta combinación finalmente cierra la brecha entre los dos repositorios de manera efectiva. Los cambios realizados en las carpetas de contenido principal del repositorio dev se reflejan en el repositorio public, y viceversa si es necesario (aunque mi flujo principal es dev -> public). Las eliminaciones se manejan correctamente y, dado que solo sincroniza los archivos cambiados, el historial de commits en el repositorio public refleja con precisión las modificaciones reales.
La Captura Restante: Sincronización vs. Momento del Commit¶
Sin embargo, todavía hay una desventaja. Cuando cambio un archivo en el repositorio dev, y RealTimeSync está en ejecución, esos cambios se sincronizan en el directorio del repositorio public inmediatamente, incluso si aún no se han confirmado en el repositorio dev. La solución de sincronización está desacoplada de Git.
No es un gran problema, pero requiere un poco más de cuidado al confirmar y enviar cambios. Básicamente, cuando trabajo en el repositorio dev, necesito asegurarme de confirmar todo allí antes de cambiar el enfoque al repositorio public para confirmar y enviar. Además, refuerza el hábito de revisar realmente los cambios preparados para confirmar en el repositorio public antes de confirmar y enviar, solo para asegurar que el estado sea exactamente lo que pretendo.
¿Para Quién Es Esto? (Aclaración Importante)¶
Espera, sin embargo, antes de que pienses que toda esta configuración es obligatoria solo para usar la wiki, déjame aclarar. ¿Toda esta complejidad? No es necesaria si solo quieres trabajar con el contenido principal. El punto de entrada principal sigue siendo súper simple: clona el repositorio público docs-nica (que solo tiene los archivos Markdown y la configuración de MkDocs) y usa las herramientas que tú prefieras. Eso es todo.
Entonces, ¿por qué pasé por todos estos problemas? Esta configuración de desarrollo bastante compleja sirve a dos propósitos principales para mí:
- Mi Red de Seguridad Personal: Es un control de versiones crucial para todas mis piezas y fragmentos de desarrollo – las configuraciones, los scripts a medio terminar, las notas de planificación – cosas que no puedo permitirme perder de nuevo.
- Compartir Mi Flujo de Trabajo Exacto (Opcionalmente): Si alguien quiere replicar mi entorno específico, puede clonar el repositorio
docs-nica-dev. Obtendrán mi configuración completa de Obsidian (plugins, configuraciones, marcadores, búsquedas, todo lo demás), potencialmente configuraciones de Cursor y cualquier otra herramienta integrada que haya configurado. Es una forma de compartir una configuración base lista para usar.
Pero la idea fundamental no ha cambiado: puedes tomar absolutamente solo el repositorio público y construir tu propio flujo de trabajo a su alrededor con tus herramientas favoritas. Esta elaborada danza se trata de gestionar mi caos de desarrollo y ofrecer un plano para aquellos que lo deseen.
Conclusión: Una Solución Ganada con Esfuerzo¶
En general, estoy feliz de haber encontrado una solución al problema ahora – aunque me costó como dos días de prueba, error y frustración. Pero acertar con este flujo de trabajo fue crucial para evitar problemas futuros, asegurando tanto un repositorio público limpio como un entorno de desarrollo completamente controlado por versiones.
¿Es esta configuración perfecta? Requiere gestionar dos repositorios y una herramienta de sincronización externa, además de un flujo de trabajo consciente para confirmar. Sin embargo, resuelve directamente el problema crítico de versionar todo lo necesario para un proceso de desarrollo complejo sin comprometer la limpieza del repositorio del proyecto principal ni luchar contra las limitaciones de Git con estructuras anidadas. Para proyectos que superan las simples estrategias de .gitignore, este enfoque ofrece un camino pragmático, brindando seguridad y estructura para la inevitable y desordenada realidad del trabajo de desarrollo.