Skip to content

🚫 GITIGNORE PHILOSOPHY

La Filosofía de la Exclusión Inteligente

".gitignore es la filosofía del repositorio codificada. Define no solo qué archivos excluir, sino qué merece ser preservado en la historia del proyecto. Es el guardián que protege de la contaminación."


📖 TABLA DE CONTENIDOS

  1. El Principio de Relevancia
  2. Arquitectura de Patterns
  3. Estructura Organizacional
  4. Estrategias Avanzadas
  5. Anti-Patterns y Peligros
  6. AudioLab Strategy
  7. Casos de Estudio
  8. Mantenimiento y Evolución

🧠 CAPÍTULO 1: EL PRINCIPIO DE RELEVANCIA

¿Qué Merece Vivir en el Repositorio?

Esta es la pregunta fundamental que .gitignore responde. No es una lista arbitraria de archivos - es una declaración filosófica sobre qué constituye la esencia de tu proyecto.

┌──────────────────────────────────────────────────────────┐
│              LA PREGUNTA EXISTENCIAL                      │
├──────────────────────────────────────────────────────────┤
│                                                           │
│  Ante cualquier archivo, pregunta:                        │
│                                                           │
│  "Si borrara todo excepto este archivo y clonara          │
│   el repositorio en una máquina nueva, ¿podría            │
│   recrear el proyecto completo?"                          │
│                                                           │
│  Si la respuesta es SÍ → El archivo ES ESENCIAL           │
│  Si la respuesta es NO → El archivo es DERIVADO           │
│                                                           │
└──────────────────────────────────────────────────────────┘

El Árbol de Decisión de Inclusión

🎯 CRITERIO DE INCLUSIÓN/EXCLUSIÓN

         ┌─────────────────────┐
         │  Archivo encontrado │
         └──────────┬──────────┘
         ┌──────────▼───────────┐
         │   ¿Es FUENTE?        │
         │ (código escrito por  │
         │     humanos)         │
         └──────┬───────┬───────┘
                │       │
            SÍ  │       │ NO
                │       │
                ▼       ▼
           ✅ INCLUDE   │
             ┌──────────▼───────────┐
             │ ¿Es NECESARIO para   │
             │  BUILD/REPRODUCIR?   │
             │ (CMakeLists, package │
             │     manifests)       │
             └──────┬───────┬───────┘
                    │       │
                SÍ  │       │ NO
                    │       │
                    ▼       ▼
               ✅ INCLUDE   │
                 ┌──────────▼───────────┐
                 │ ¿Es DOCUMENTACIÓN    │
                 │   ESENCIAL?          │
                 │ (arquitectura, API)  │
                 └──────┬───────┬───────┘
                        │       │
                    SÍ  │       │ NO
                        │       │
                        ▼       ▼
                   ✅ INCLUDE   │
                     ┌──────────▼───────────┐
                     │ ¿Es DERIVABLE de     │
                     │  archivos source?    │
                     │ (compilado, generado)│
                     └──────┬───────┬───────┘
                            │       │
                        SÍ  │       │ NO
                            │       │
                            ▼       ▼
                      ❌ IGNORE     │
                         ┌──────────▼───────────┐
                         │ ¿Es ESPECÍFICO de    │
                         │   developer/entorno? │
                         │ (IDE, OS, personal)  │
                         └──────┬───────┬───────┘
                                │       │
                            SÍ  │       │ NO
                                │       │
                                ▼       ▼
                          ❌ IGNORE  ⚠️ EVALUAR
                                       CASO

Taxonomía Ontológica de Archivos

╔═══════════════════════════════════════════════════════════╗
║            CLASIFICACIÓN FUNDAMENTAL                      ║
╚═══════════════════════════════════════════════════════════╝

┌───────────────────────────────────────────────────────────┐
│  🌱 SOURCE (Incluir - La Esencia del Proyecto)            │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINICIÓN: Archivos creados por humanos, no derivables  │
│                                                           │
│  EJEMPLOS:                                                │
│  ✅ Código fuente                                         │
│     ├─ .cpp, .h, .c, .hpp (C/C++)                         │
│     ├─ .py (Python)                                       │
│     ├─ .js, .ts (JavaScript/TypeScript)                   │
│     └─ .rs (Rust)                                         │
│                                                           │
│  ✅ Build scripts                                         │
│     ├─ CMakeLists.txt                                     │
│     ├─ Makefile                                           │
│     ├─ package.json                                       │
│     └─ build.sh                                           │
│                                                           │
│  ✅ Configuration crítica                                 │
│     ├─ .gitignore                                         │
│     ├─ .clang-format                                      │
│     ├─ .github/workflows/*.yml                            │
│     └─ vcpkg.json                                         │
│                                                           │
│  ✅ Assets source (si no LFS)                             │
│     ├─ SVG designs                                        │
│     ├─ UI mockups (Figma exports)                         │
│     └─ Small test samples (< 1MB)                         │
│                                                           │
│  FILOSOFÍA:                                               │
│  "Si se pierde, el proyecto no puede reconstruirse"       │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  🏗️ DERIVED (Ignorar - Productos del Build)               │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINICIÓN: Generados por compiladores/herramientas      │
│                                                           │
│  EJEMPLOS:                                                │
│  ❌ Binarios compilados                                   │
│     ├─ .exe, .app (ejecutables)                           │
│     ├─ .dll, .so, .dylib (librerías dinámicas)            │
│     ├─ .a, .lib (librerías estáticas)                     │
│     └─ .o, .obj (object files)                            │
│                                                           │
│  ❌ Build artifacts                                       │
│     ├─ build/, out/, dist/                                │
│     ├─ cmake-build-debug/                                 │
│     ├─ .cmake/                                            │
│     └─ CMakeCache.txt                                     │
│                                                           │
│  ❌ Generated code                                        │
│     ├─ *.pb.cc, *.pb.h (protobuf)                         │
│     ├─ moc_*.cpp (Qt meta-object)                         │
│     ├─ ui_*.h (Qt UI forms)                               │
│     └─ *_autogen/ (CMake auto-generated)                  │
│                                                           │
│  ❌ Processed assets                                      │
│     ├─ Optimized images                                   │
│     ├─ Minified JS/CSS                                    │
│     └─ Compiled shaders                                   │
│                                                           │
│  FILOSOFÍA:                                               │
│  "Si puede regenerarse con 'make clean && make',          │
│   no pertenece al repositorio"                            │
│                                                           │
│  EXCEPCIÓN:                                               │
│  Si el build tool es raro/complejo, considera incluir     │
│  binaries en releases/ folder (pero NO en main history)   │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  🔧 ENVIRONMENT (Ignorar - Específico del Developer)      │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINICIÓN: Preferencias personales y entorno local      │
│                                                           │
│  EJEMPLOS:                                                │
│  ❌ IDE settings personales                               │
│     ├─ .vscode/settings.json (preferencias)               │
│     ├─ .idea/ (JetBrains IDEs)                            │
│     ├─ *.user (Visual Studio user settings)               │
│     └─ .vs/ (Visual Studio local)                         │
│                                                           │
│  ❌ OS-specific files                                     │
│     ├─ .DS_Store (macOS Finder)                           │
│     ├─ Thumbs.db (Windows thumbnails)                     │
│     ├─ desktop.ini (Windows folder config)                │
│     └─ *~ (Linux backup files)                            │
│                                                           │
│  ❌ Editor backups                                        │
│     ├─ *.swp, *.swo (Vim)                                 │
│     ├─ *~ (Emacs)                                         │
│     ├─ .*.swp (Vim hidden)                                │
│     └─ #*# (Emacs auto-save)                              │
│                                                           │
│  ❌ Local configs                                         │
│     ├─ .env.local                                         │
│     ├─ config.local.yml                                   │
│     └─ local_settings.py                                  │
│                                                           │
│  FILOSOFÍA:                                               │
│  "Tu preferencia de IDE no debe imponerse al equipo"      │
│                                                           │
│  NOTA IMPORTANTE:                                         │
│  Muchos de estos deben ir en ~/.gitignore_global,         │
│  NO en el .gitignore del proyecto                         │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  📦 DEPENDENCIES (Ignorar - Package Managers)             │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINICIÓN: Descargados por package managers             │
│                                                           │
│  EJEMPLOS:                                                │
│  ❌ Node.js                                               │
│     └─ node_modules/ (npm/yarn)                           │
│                                                           │
│  ❌ Python                                                │
│     ├─ venv/, .venv/ (virtual env)                        │
│     ├─ __pycache__/                                       │
│     ├─ *.pyc, *.pyo                                       │
│     └─ .Python                                            │
│                                                           │
│  ❌ C++ Package Managers                                  │
│     ├─ vcpkg_installed/ (vcpkg)                           │
│     ├─ build/_deps/ (CMake FetchContent)                  │
│     └─ conan/ (Conan cache)                               │
│                                                           │
│  ❌ Other                                                 │
│     ├─ vendor/ (Go, Ruby)                                 │
│     ├─ packages/ (NuGet)                                  │
│     └─ .bundle/ (Ruby Bundler)                            │
│                                                           │
│  FILOSOFÍA:                                               │
│  "Dependencies se declaran en manifests (package.json,    │
│   vcpkg.json, requirements.txt), no se commitean"         │
│                                                           │
│  TRADE-OFF:                                               │
│  ├─ PRO: Repo pequeño, reproducible                       │
│  └─ CON: Requiere package manager disponible              │
│                                                           │
│  EXCEPCIÓN RARA:                                          │
│  Si dependency no está disponible públicamente,           │
│  considerar vendor/ commitado (documento el por qué)      │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  🔒 SECRETS (SIEMPRE Ignorar - Crítico de Seguridad)      │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINICIÓN: Información sensible/credenciales            │
│                                                           │
│  EJEMPLOS:                                                │
│  🚨 Credenciales                                          │
│     ├─ .env (environment variables con secrets)           │
│     ├─ .env.production                                    │
│     ├─ credentials.json                                   │
│     └─ secrets.yml                                        │
│                                                           │
│  🚨 API Keys & Tokens                                     │
│     ├─ api_token.txt                                      │
│     ├─ .api_key                                           │
│     └─ oauth_tokens.json                                  │
│                                                           │
│  🚨 Certificates & Keys                                   │
│     ├─ *.pem (private keys)                               │
│     ├─ *.key                                              │
│     ├─ *.p12, *.pfx (certificates)                        │
│     └─ id_rsa (SSH keys)                                  │
│                                                           │
│  🚨 Database dumps with data                              │
│     ├─ *.sql (if contains real data)                      │
│     └─ dump.db                                            │
│                                                           │
│  FILOSOFÍA:                                               │
│  "Una vez en Git history = comprometido PARA SIEMPRE"     │
│                                                           │
│  ⚠️ ADVERTENCIA CRÍTICA:                                  │
│  .gitignore NO borra historia. Si commiteaste un secret:  │
│  1. Rotate/revoke el secret INMEDIATAMENTE                │
│  2. Use git filter-branch o BFG Repo-Cleaner              │
│  3. Force push (si es seguro)                             │
│  4. Notifica al equipo                                    │
│                                                           │
│  MEJOR PRÁCTICA:                                          │
│  ├─ Pre-commit hooks que escanean secrets                 │
│  ├─ Template files (.env.example) SÍ commitear            │
│  └─ Documentar dónde conseguir credentials                │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  📝 EPHEMERAL (Ignorar - Temporal/Transitorio)            │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINICIÓN: Datos temporales, regenerables               │
│                                                           │
│  EJEMPLOS:                                                │
│  ❌ Logs                                                  │
│     ├─ *.log                                              │
│     ├─ logs/                                              │
│     └─ npm-debug.log*                                     │
│                                                           │
│  ❌ Temporary files                                       │
│     ├─ tmp/, temp/                                        │
│     ├─ *.tmp                                              │
│     ├─ *.cache                                            │
│     └─ .sass-cache/                                       │
│                                                           │
│  ❌ Test outputs                                          │
│     ├─ test_results/                                      │
│     ├─ coverage/                                          │
│     ├─ .pytest_cache/                                     │
│     └─ htmlcov/                                           │
│                                                           │
│  ❌ Runtime data                                          │
│     ├─ *.pid                                              │
│     ├─ *.seed                                             │
│     └─ .lock (process locks)                              │
│                                                           │
│  ❌ Downloads                                             │
│     ├─ downloads/                                         │
│     └─ *.download                                         │
│                                                           │
│  FILOSOFÍA:                                               │
│  "Datos de runtime no son parte del proyecto"             │
│                                                           │
│  EXCEPCIÓN:                                               │
│  Golden master test results (expected outputs) SÍ pueden  │
│  commitearse si son parte de test fixtures                │
│                                                           │
└───────────────────────────────────────────────────────────┘

La Regla de la Reproducibilidad

┌──────────────────────────────────────────────────────────┐
│          EL TEST DE REPRODUCIBILIDAD                      │
├──────────────────────────────────────────────────────────┤
│                                                           │
│  EXPERIMENTO MENTAL:                                      │
│                                                           │
│  1. Clone el repositorio en máquina completamente nueva   │
│  2. Sigue el README/BUILD instructions                    │
│  3. ¿Puedes recrear TODO lo que está en .gitignore?       │
│                                                           │
│  SI SÍ → .gitignore está CORRECTO                         │
│  SI NO → Algo crítico está siendo ignorado erróneamente   │
│                                                           │
│  EJEMPLO BUENO:                                           │
│  ├─ Source code: En Git ✅                                │
│  ├─ CMakeLists.txt: En Git ✅                             │
│  ├─ vcpkg.json: En Git ✅                                 │
│  ├─ Ejecutar: cmake -B build && cmake --build build      │
│  └─ Resultado: Binary se genera (estaba en .gitignore)    │
│                                                           │
│  EJEMPLO MALO:                                            │
│  ├─ Source code: En Git ✅                                │
│  ├─ Special library: Ignorado ❌                          │
│  ├─ Ejecutar: cmake -B build                             │
│  └─ Error: Cannot find special library                    │
│                                                           │
│  CONCLUSIÓN:                                              │
│  Si algo es NECESARIO para build pero NO regenerable,     │
│  debe estar en Git (NO en .gitignore)                     │
│                                                           │
└──────────────────────────────────────────────────────────┘

📐 CAPÍTULO 2: ARQUITECTURA DE PATTERNS

El Lenguaje de los Patterns

.gitignore tiene su propio lenguaje de patrones. Entender este lenguaje es entender cómo expresar intención.

╔═══════════════════════════════════════════════════════════╗
║          SINTAXIS COMO LENGUAJE DE INTENCIÓN             ║
╚═══════════════════════════════════════════════════════════╝

┌───────────────────────────────────────────────────────────┐
│  📄 LITERAL MATCH (Coincidencia Exacta)                   │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  PATTERN:                                                 │
│    debug.log                                              │
│                                                           │
│  SIGNIFICADO:                                             │
│    Ignora archivo llamado "debug.log" en CUALQUIER        │
│    directorio del proyecto                                │
│                                                           │
│  MATCHES:                                                 │
│    ✅ debug.log                (root)                     │
│    ✅ src/debug.log            (subdirectorio)            │
│    ✅ build/tests/debug.log    (anidado profundo)         │
│                                                           │
│  NO MATCHES:                                              │
│    ❌ debug.log.txt            (diferente nombre)         │
│    ❌ debug_log                (underscore vs dot)        │
│    ❌ Debug.log                (case-sensitive en Linux)  │
│                                                           │
│  USO:                                                     │
│    Archivos específicos que siempre deben ignorarse       │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  📁 DIRECTORY MATCH (Directorio Completo)                 │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  PATTERN:                                                 │
│    build/                                                 │
│         └─► Trailing slash es CRÍTICO                    │
│                                                           │
│  SIGNIFICADO:                                             │
│    Ignora DIRECTORIO "build" y TODO su contenido          │
│    No ignora ARCHIVOS llamados "build"                    │
│                                                           │
│  MATCHES:                                                 │
│    ✅ build/                   (directorio)               │
│    ✅ build/main.exe           (contenido)                │
│    ✅ build/sub/file.o         (contenido anidado)        │
│    ✅ src/build/               (en subdirectorio)         │
│                                                           │
│  NO MATCHES:                                              │
│    ❌ build                    (archivo, no directorio)   │
│    ❌ build.txt                (archivo diferente)        │
│                                                           │
│  COMPARACIÓN:                                             │
│    build/  → Solo directorios                             │
│    build   → Archivos Y directorios llamados "build"      │
│                                                           │
│  USO:                                                     │
│    Build outputs, node_modules, directorios generados     │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  🌟 WILDCARD SINGLE (Asterisco Simple)                    │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  PATTERN:                                                 │
│    *.o                                                    │
│                                                           │
│  SIGNIFICADO:                                             │
│    Cualquier archivo terminando en .o                     │
│    En CUALQUIER nivel de directorio                       │
│                                                           │
│  MATCHES:                                                 │
│    ✅ main.o                                              │
│    ✅ src/utils.o                                         │
│    ✅ build/debug/audio.o                                 │
│                                                           │
│  NO MATCHES:                                              │
│    ❌ main.obj                 (extensión diferente)      │
│    ❌ .o                       (solo extensión)           │
│                                                           │
│  VARIANTES:                                               │
│    test*      → test, test1, testing, test_file.cpp       │
│    *_temp     → audio_temp, file_temp                     │
│    *.log.*    → debug.log.1, error.log.old                │
│                                                           │
│  USO:                                                     │
│    Ignorar por extensión (compiled, temp, backup)         │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  🌐 WILDCARD RECURSIVE (Double Asterisco)                 │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  PATTERN:                                                 │
│    **/logs/*.log                                          │
│                                                           │
│  SIGNIFICADO:                                             │
│    Archivos .log dentro de CUALQUIER directorio "logs"   │
│    a CUALQUIER profundidad                                │
│                                                           │
│  MATCHES:                                                 │
│    ✅ logs/debug.log                                      │
│    ✅ src/logs/error.log                                  │
│    ✅ build/test/logs/output.log                          │
│                                                           │
│  NO MATCHES:                                              │
│    ❌ logs/subdir/debug.log    (* no cruza directorios)   │
│    ❌ debug.log                (no en carpeta "logs")     │
│                                                           │
│  OTROS EJEMPLOS:                                          │
│    **/build/     → build/ a cualquier profundidad         │
│    **/*.tmp      → .tmp files en cualquier lugar          │
│    **/test/**    → Todo bajo carpeta "test"               │
│                                                           │
│  EQUIVALENCIAS:                                           │
│    *.log  ≈  **/*.log  (casi idénticos para archivos)     │
│                                                           │
│  USO:                                                     │
│    Patterns complejos en estructuras anidadas             │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  🔤 CHARACTER CLASS (Clase de Caracteres)                 │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  PATTERN:                                                 │
│    test[0-9].txt                                          │
│                                                           │
│  SIGNIFICADO:                                             │
│    "test" seguido de UN dígito, luego ".txt"              │
│                                                           │
│  MATCHES:                                                 │
│    ✅ test0.txt                                           │
│    ✅ test5.txt                                           │
│    ✅ test9.txt                                           │
│                                                           │
│  NO MATCHES:                                              │
│    ❌ test10.txt               (dos dígitos)              │
│    ❌ testa.txt                (letra, no dígito)         │
│    ❌ test.txt                 (sin dígito)               │
│                                                           │
│  VARIANTES:                                               │
│    [abc]         → a, b, o c                              │
│    [0-9]         → cualquier dígito                       │
│    [a-zA-Z]      → cualquier letra                        │
│    [!0-9]        → cualquier cosa EXCEPTO dígito          │
│                                                           │
│  EJEMPLOS:                                                │
│    backup[0-9][0-9].sql  → backup00.sql hasta backup99   │
│    [Tt]emp*              → Temp o temp files              │
│                                                           │
│  USO:                                                     │
│    Numbered backups, case variations                      │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  ❗ NEGATION (Excepción a la Regla)                       │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  PATTERN:                                                 │
│    !important.log                                         │
│                                                           │
│  SIGNIFICADO:                                             │
│    NO ignorar este archivo (excepción a pattern previo)   │
│                                                           │
│  EJEMPLO COMPLETO:                                        │
│    *.log              # Ignorar todos los logs            │
│    !production.log    # EXCEPTO este                      │
│                                                           │
│  RESULTADO:                                               │
│    ✅ production.log  → NO ignorado (tracked)             │
│    ❌ debug.log       → Ignorado                          │
│    ❌ error.log       → Ignorado                          │
│                                                           │
│  ⚠️ ORDEN IMPORTA:                                        │
│    !production.log    # Esto NO funciona                  │
│    *.log              # Porque *.log viene después        │
│                                                           │
│    *.log              # Correcto                          │
│    !production.log    # Negation después de pattern       │
│                                                           │
│  LIMITACIÓN:                                              │
│    build/             # Ignorar directorio                │
│    !build/README.md   # ❌ NO funciona                    │
│                                                           │
│    No puedes negar un archivo dentro de directorio        │
│    ignorado. Primero debes negar el directorio:           │
│                                                           │
│    build/*            # Ignorar CONTENIDO                 │
│    !build/README.md   # ✅ Ahora sí funciona              │
│                                                           │
│  USO:                                                     │
│    Excepciones específicas a reglas generales             │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  📍 ROOTED PATTERN (Anclado al Root)                      │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  PATTERN:                                                 │
│    /TODO.txt                                              │
│         └─► Leading slash es CRÍTICO                      │
│                                                           │
│  SIGNIFICADO:                                             │
│    Ignorar TODO.txt SOLO en el root del repositorio       │
│    NO en subdirectorios                                   │
│                                                           │
│  MATCHES:                                                 │
│    ✅ /TODO.txt                (root)                     │
│                                                           │
│  NO MATCHES:                                              │
│    ❌ src/TODO.txt             (subdirectorio)            │
│    ❌ docs/TODO.txt            (subdirectorio)            │
│                                                           │
│  COMPARACIÓN:                                             │
│    /TODO.txt  → Solo en root                              │
│    TODO.txt   → En cualquier directorio                   │
│                                                           │
│  EJEMPLO PRÁCTICO:                                        │
│    /build/    → Ignorar /build/ en root                   │
│               → PERO permitir src/build/ (código fuente)  │
│                                                           │
│  USO:                                                     │
│    Distinguir archivos root de subdirectorios con         │
│    mismo nombre                                           │
│                                                           │
└───────────────────────────────────────────────────────────┘

Composición de Reglas

Los patterns pueden combinarse para crear lógica compleja.

╔═══════════════════════════════════════════════════════════╗
║              PATTERN COMPOSITION                          ║
╚═══════════════════════════════════════════════════════════╝

┌───────────────────────────────────────────────────────────┐
│  CASO 1: Ignorar General + Excepción Específica           │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  OBJETIVO:                                                │
│    Ignorar todos los .log EXCEPTO production.log          │
│                                                           │
│  PATTERN:                                                 │
│    # Ignorar todos los logs                               │
│    *.log                                                  │
│                                                           │
│    # EXCEPTO el log de producción                         │
│    !production.log                                        │
│                                                           │
│  RESULTADO:                                               │
│    app.log         ❌ ignorado                            │
│    debug.log       ❌ ignorado                            │
│    error.log       ❌ ignorado                            │
│    production.log  ✅ NO ignorado (tracked)               │
│                                                           │
│  FILOSOFÍA:                                               │
│    "Default deny, explicit allow"                         │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  CASO 2: Ignorar Directorio Pero Preservar Estructura     │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  OBJETIVO:                                                │
│    Ignorar contenido de logs/ pero mantener el directorio │
│    (usando .gitkeep)                                      │
│                                                           │
│  PATTERN:                                                 │
│    # Ignorar todo el contenido                            │
│    logs/*                                                 │
│                                                           │
│    # EXCEPTO .gitkeep (mantiene folder en Git)            │
│    !logs/.gitkeep                                         │
│                                                           │
│  ESTRUCTURA:                                              │
│    logs/                                                  │
│    ├─ .gitkeep        ✅ tracked                          │
│    ├─ app.log         ❌ ignorado                         │
│    ├─ debug.log       ❌ ignorado                         │
│    └─ error.log       ❌ ignorado                         │
│                                                           │
│  POR QUÉ:                                                 │
│    Git no trackea directorios vacíos. .gitkeep es         │
│    convención para preservar estructura de folders.       │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  CASO 3: Ignorar TODO Excepto Tipo Específico             │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  OBJETIVO:                                                │
│    En config/, ignorar todo EXCEPTO archivos .template    │
│                                                           │
│  PATTERN:                                                 │
│    # Ignorar todo en config/                              │
│    config/*                                               │
│                                                           │
│    # PERO mantener templates                              │
│    !config/*.template                                     │
│                                                           │
│    # Y preservar README                                   │
│    !config/README.md                                      │
│                                                           │
│  RESULTADO:                                               │
│    config/                                                │
│    ├─ README.md           ✅ tracked                      │
│    ├─ app.template        ✅ tracked                      │
│    ├─ dev.yaml            ❌ ignorado                     │
│    ├─ prod.yaml           ❌ ignorado                     │
│    └─ local_settings.yml  ❌ ignorado                     │
│                                                           │
│  USO:                                                     │
│    Commitear templates, ignorar configs reales            │
│    (que contienen secrets o settings locales)             │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  CASO 4: Selectividad por Profundidad                     │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  OBJETIVO:                                                │
│    Ignorar /build/ en root, PERO permitir src/build/      │
│    (que es código fuente, no build output)                │
│                                                           │
│  PATTERN:                                                 │
│    # Ignorar build/ solo en root                          │
│    /build/                                                │
│                                                           │
│    # NO afecta src/build/ (código fuente)                 │
│                                                           │
│  RESULTADO:                                               │
│    /build/              ❌ ignorado (build artifacts)     │
│    /build/main.exe      ❌ ignorado                       │
│    src/build/           ✅ tracked (source code)          │
│    src/build/config.h   ✅ tracked                        │
│                                                           │
│  CONTRASTE:                                               │
│    Si usaras: build/  (sin leading slash)                 │
│    Entonces: AMBOS /build/ Y src/build/ se ignorarían     │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  CASO 5: Ignorar Excepto en Ubicación Específica          │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  OBJETIVO:                                                │
│    Ignorar todos los *.config EXCEPTO en etc/             │
│                                                           │
│  PATTERN:                                                 │
│    # Ignorar configs globalmente                          │
│    *.config                                               │
│                                                           │
│    # PERO preservar configs de sistema                    │
│    !etc/*.config                                          │
│                                                           │
│  RESULTADO:                                               │
│    app.config           ❌ ignorado                       │
│    src/test.config      ❌ ignorado                       │
│    etc/system.config    ✅ tracked                        │
│    etc/auth.config      ✅ tracked                        │
│                                                           │
│  USO:                                                     │
│    Configs locales ignorados, configs de sistema tracked  │
│                                                           │
└───────────────────────────────────────────────────────────┘

🏗️ CAPÍTULO 3: ESTRUCTURA ORGANIZACIONAL

Anatomía del .gitignore Ideal

Un .gitignore bien organizado es auto-documentante y mantenible.

╔═══════════════════════════════════════════════════════════╗
║          TEMPLATE ARQUITECTÓNICO                          ║
╚═══════════════════════════════════════════════════════════╝

┌───────────────────────────────────────────────────────────┐
│                                                           │
│  📋 ESTRUCTURA EN CAPAS                                   │
│                                                           │
│  ┌─────────────────────────────────────────┐             │
│  │  🎯 HEADER                               │             │
│  │  Metadata del archivo                    │             │
│  │  ├─ Proyecto/propósito                   │             │
│  │  ├─ Maintainer                           │             │
│  │  └─ Última actualización                 │             │
│  └─────────────────────────────────────────┘             │
│           │                                               │
│           ▼                                               │
│  ┌─────────────────────────────────────────┐             │
│  │  🏗️ BUILD ARTIFACTS                      │             │
│  │  Outputs de compilación                  │             │
│  │  ├─ Binarios (.exe, .dll, .so)           │             │
│  │  ├─ Object files (.o, .obj)              │             │
│  │  ├─ Build directories (build/, out/)     │             │
│  │  └─ Generated code                       │             │
│  └─────────────────────────────────────────┘             │
│           │                                               │
│           ▼                                               │
│  ┌─────────────────────────────────────────┐             │
│  │  📦 DEPENDENCIES                         │             │
│  │  Package managers                        │             │
│  │  ├─ node_modules/                        │             │
│  │  ├─ vcpkg_installed/                     │             │
│  │  ├─ venv/, __pycache__/                  │             │
│  │  └─ Downloaded libraries                 │             │
│  └─────────────────────────────────────────┘             │
│           │                                               │
│           ▼                                               │
│  ┌─────────────────────────────────────────┐             │
│  │  🎨 IDE & EDITORS                        │             │
│  │  Personal preferences                    │             │
│  │  ├─ .vscode/ (mostly)                    │             │
│  │  ├─ .idea/                               │             │
│  │  ├─ .vs/                                 │             │
│  │  └─ *.user                               │             │
│  └─────────────────────────────────────────┘             │
│           │                                               │
│           ▼                                               │
│  ┌─────────────────────────────────────────┐             │
│  │  💻 OPERATING SYSTEMS                    │             │
│  │  OS-specific files                       │             │
│  │  ├─ .DS_Store (macOS)                    │             │
│  │  ├─ Thumbs.db (Windows)                  │             │
│  │  ├─ *~ (Linux backups)                   │             │
│  │  └─ desktop.ini                          │             │
│  └─────────────────────────────────────────┘             │
│           │                                               │
│           ▼                                               │
│  ┌─────────────────────────────────────────┐             │
│  │  🔧 PROJECT SPECIFIC                     │             │
│  │  Unique to this project                  │             │
│  │  ├─ Local configs                        │             │
│  │  ├─ Test outputs                         │             │
│  │  ├─ Generated assets                     │             │
│  │  └─ Temporary files                      │             │
│  └─────────────────────────────────────────┘             │
│           │                                               │
│           ▼                                               │
│  ┌─────────────────────────────────────────┐             │
│  │  🔒 SECRETS & SENSITIVE                  │             │
│  │  CRITICAL SECURITY                       │             │
│  │  ├─ .env, .env.*                         │             │
│  │  ├─ *.key, *.pem                         │             │
│  │  ├─ credentials.*                        │             │
│  │  └─ API tokens                           │             │
│  └─────────────────────────────────────────┘             │
│                                                           │
└───────────────────────────────────────────────────────────┘

Ejemplo Completo y Comentado

# ════════════════════════════════════════════════════════
# AudioLab .gitignore
# Audio Processing Framework & Plugin Suite
# ════════════════════════════════════════════════════════
#
# Purpose: Define files excluded from version control
# Maintainer: AudioLab Core Team
# Last Updated: 2024-01-15
#
# Philosophy:
# - Include: Source code, build configs, documentation
# - Exclude: Build outputs, dependencies, local configs
# - Protect: Secrets and credentials (CRITICAL)
#
# ════════════════════════════════════════════════════════


# ────────────────────────────────────────────────────────
# 🏗️ BUILD ARTIFACTS
# ────────────────────────────────────────────────────────
# Compiled outputs - regenerable from source via CMake
# These bloat repository and change with every build

# Build directories (standard conventions)
/build/
/out/
/dist/
cmake-build-*/
_build/

# CMake artifacts
CMakeCache.txt
CMakeFiles/
cmake_install.cmake
CTestTestfile.cmake
compile_commands.json

# Compiled binaries (platform-specific)
*.exe
*.dll
*.so
*.dylib
*.a
*.lib

# Object files (intermediate compilation)
*.o
*.obj
*.lo
*.slo

# Generated code (auto-generated, don't edit)
*_autogen/
moc_*.cpp
ui_*.h
qrc_*.cpp


# ────────────────────────────────────────────────────────
# 📦 DEPENDENCIES
# ────────────────────────────────────────────────────────
# Package managers - install from manifest files
# (vcpkg.json, package.json, requirements.txt)

# vcpkg (C++ package manager)
/vcpkg_installed/
/vcpkg/
.vcpkg-root

# Node.js (for web interfaces/tools)
node_modules/
npm-debug.log*
yarn-error.log*
.pnpm-debug.log*

# Python (for scripts/automation)
venv/
.venv/
__pycache__/
*.py[cod]
*$py.class
.Python

# Downloaded libraries
/third_party/downloads/
/external/downloads/


# ────────────────────────────────────────────────────────
# 🎨 IDE & EDITORS
# ────────────────────────────────────────────────────────
# Personal development environment preferences
# Most belong in global .gitignore, but some project-specific

# Visual Studio Code
.vscode/settings.json
.vscode/*.code-workspace
.vscode/.ropeproject

# EXCEPT: Team-shared configs
!.vscode/extensions.json
!.vscode/launch.json
!.vscode/tasks.json

# Visual Studio
.vs/
*.user
*.userosscache
*.sln.docstates
*.vcxproj.filters

# JetBrains IDEs (CLion, etc)
.idea/
*.iml
*.ipr
*.iws

# Xcode
*.xcodeproj/*
!*.xcodeproj/project.pbxproj
*.xcworkspace/*
!*.xcworkspace/contents.xcworkspacedata

# Vim/Emacs (consider moving to global)
*.swp
*.swo
*~
\#*\#
.#*


# ────────────────────────────────────────────────────────
# 💻 OPERATING SYSTEMS
# ────────────────────────────────────────────────────────
# OS-generated files (consider global .gitignore)

# macOS
.DS_Store
.AppleDouble
.LSOverride
._*

# Windows
Thumbs.db
ehthumbs.db
Desktop.ini
$RECYCLE.BIN/

# Linux
*~
.directory
.Trash-*


# ────────────────────────────────────────────────────────
# 🔧 PROJECT SPECIFIC (AudioLab)
# ────────────────────────────────────────────────────────

# Audio test outputs (generated by tests)
/tests/output/
/tests/recordings/
*.recorded.wav

# EXCEPT: Golden masters (expected test results)
!tests/golden/*.wav

# Benchmark results (regenerable)
/benchmarks/results/
*.benchmark.json

# Documentation builds (generated from source .md)
/docs/_build/
/docs/html/
/docs/latex/

# EXCEPT: Hand-written guides
!docs/guides/

# Local configuration overrides
*.local.yml
*.local.json
local_settings.py

# BUT: Keep templates for these configs
!*.template.yml
!*.template.json

# Temporary audio processing
/tmp/
/temp/
*.tmp
*.cache

# Logs (runtime data)
*.log
logs/
*.log.*

# EXCEPT: Keep logs directory structure
!logs/.gitkeep

# Coverage reports (regenerable from tests)
/coverage/
.coverage
htmlcov/
*.lcov


# ────────────────────────────────────────────────────────
# 🔒 SECRETS & SENSITIVE DATA
# ────────────────────────────────────────────────────────
# CRITICAL: Never commit credentials
# If accidentally committed, rotate immediately!

# Environment variables with secrets
.env
.env.local
.env.*.local
.env.production

# EXCEPT: Template showing structure
!.env.example
!.env.template

# API keys and tokens
api_key.txt
.api_key
*_token.txt
*_secret.txt

# Certificates and private keys
*.pem
*.key
*.p12
*.pfx
*.cer (if private)
id_rsa
id_dsa

# Database with real data
*.sql (if contains user data)
*.db (if contains sensitive info)

# EXCEPT: Schema definitions (no data)
!schema.sql
!migrations/*.sql


# ────────────────────────────────────────────────────────
# 📝 ADDITIONAL EPHEMERAL
# ────────────────────────────────────────────────────────

# Process IDs
*.pid

# Crash dumps
*.dmp
core.*

# Profiling data
*.prof
*.perf
callgrind.out.*

# Editor artifacts
.*.kate-swp
.*.sw?


# ════════════════════════════════════════════════════════
# END OF .gitignore
# ════════════════════════════════════════════════════════
#
# Maintenance notes:
# - Review quarterly for obsolete patterns
# - Document WHY when adding unusual patterns
# - Keep sections organized and commented
# - Consider .gitignore_global for personal preferences
#
# ════════════════════════════════════════════════════════

🔍 CAPÍTULO 4: ESTRATEGIAS AVANZADAS

Jerarquía de .gitignore Files

Git soporta múltiples niveles de .gitignore, cada uno con su propósito.

╔═══════════════════════════════════════════════════════════╗
║            GITIGNORE HIERARCHY                            ║
╚═══════════════════════════════════════════════════════════╝

🗂️ NIVELES DE .gitignore

     🌍 NIVEL GLOBAL (~/.gitignore_global)
          ├─ ALCANCE: TODOS tus repositorios
          ├─ CONFIGURACIÓN:
          │    git config --global core.excludesfile ~/.gitignore_global
          ├─ USO:
          │    Preferencias PERSONALES
          │    ├─ Tu editor favorito (.idea/, .vscode/settings.json)
          │    ├─ Tu OS (.DS_Store si usas macOS)
          │    ├─ Tus herramientas personales
          │    └─ Backups de tu editor (*~, *.swp)
          ├─ EJEMPLO:
          │    # Mi global .gitignore (macOS + VSCode user)
          │    .DS_Store
          │    .vscode/settings.json
          │    *.swp
          │    .idea/
          └─ FILOSOFÍA:
               "Mis preferencias no deben imponerse al equipo"

     ──────────────────────────────────────────────────

     📁 NIVEL REPOSITORY ROOT (.gitignore)
          ├─ ALCANCE: TODO el proyecto
          ├─ UBICACIÓN: Raíz del repositorio
          ├─ USO:
          │    Standards COMPARTIDOS del proyecto
          │    ├─ Build outputs (build/, *.exe)
          │    ├─ Dependencies (node_modules/, vcpkg_installed/)
          │    ├─ Secrets (*.env, *.key)
          │    └─ Project-specific ignores
          ├─ EJEMPLO:
          │    # Project .gitignore
          │    /build/
          │    *.exe
          │    .env
          │    /vcpkg_installed/
          └─ FILOSOFÍA:
               "Reglas que TODO el equipo debe seguir"

     ──────────────────────────────────────────────────

     📂 NIVEL SUBDIRECTORY (subdir/.gitignore)
          ├─ ALCANCE: Ese directorio y sus hijos
          ├─ UBICACIÓN: Cualquier subdirectorio
          ├─ USO:
          │    Excepciones o refinements LOCALES
          │    ├─ Module-specific ignores
          │    ├─ Overrides a reglas root
          │    └─ Casos especiales
          ├─ EJEMPLO:
          │    # tests/.gitignore
          │    # En tests/, permitir binarios (test fixtures)
          │    !*.exe
          │    # docs/.gitignore
          │    # Ignorar builds de docs
          │    _build/
          └─ FILOSOFÍA:
               "Refinements contextuales"

╔═══════════════════════════════════════════════════════════╗
║               PRECEDENCIA Y COMPOSICIÓN                   ║
╠═══════════════════════════════════════════════════════════╣
║                                                           ║
║  ORDEN DE EVALUACIÓN:                                     ║
║  1. Subdirectory .gitignore (más específico)              ║
║  2. Repository root .gitignore                            ║
║  3. Global .gitignore (menos específico)                  ║
║                                                           ║
║  REGLA: Más específico gana                               ║
║                                                           ║
║  EJEMPLO:                                                 ║
║  ┌────────────────────────────────────────┐              ║
║  │ Global: *.log                          │              ║
║  │ Root:   !important.log                 │              ║
║  │ Subdir: production.log (en logs/)      │              ║
║  └────────────────────────────────────────┘              ║
║                                                           ║
║  RESULTADO:                                               ║
║  ├─ debug.log           → Ignorado (global)               ║
║  ├─ important.log       → NO ignorado (root override)     ║
║  └─ logs/production.log → Depende de logs/.gitignore      ║
║                                                           ║
╚═══════════════════════════════════════════════════════════╝

Uso Estratégico de Niveles

┌──────────────────────────────────────────────────────────┐
│         CUÁNDO USAR CADA NIVEL                            │
├──────────────────────────────────────────────────────────┤
│                                                           │
│  🌍 GLOBAL (~/.gitignore_global)                          │
│  ═══════════════════════════════                          │
│                                                           │
│  ✅ USAR PARA:                                            │
│  ├─ Editor preferences (.idea/ si siempre usas IntelliJ)  │
│  ├─ OS files (.DS_Store si estás en macOS)                │
│  ├─ Personal tools (tu script de backup personal)         │
│  └─ Anything que NUNCA quieres en ningún repo             │
│                                                           │
│  ❌ NO USAR PARA:                                         │
│  ├─ Project-specific outputs (build/)                     │
│  ├─ Language-specific (node_modules/)                     │
│  └─ Team-shared standards                                 │
│                                                           │
│  EJEMPLO COMPLETO:                                        │
│  # ~/.gitignore_global                                    │
│  # Personal preferences - Sam's macOS + VSCode setup      │
│                                                           │
│  # macOS                                                  │
│  .DS_Store                                                │
│  .AppleDouble                                             │
│                                                           │
│  # VSCode (my settings)                                   │
│  .vscode/settings.json                                    │
│                                                           │
│  # Vim (backup editor)                                    │
│  *.swp                                                    │
│  *~                                                       │
│                                                           │
│  # My personal scratch files                              │
│  SCRATCH.txt                                              │
│  TODO_PERSONAL.md                                         │
│                                                           │
├──────────────────────────────────────────────────────────┤
│                                                           │
│  📁 ROOT (.gitignore)                                     │
│  ═════════════════                                        │
│                                                           │
│  ✅ USAR PARA:                                            │
│  ├─ Build outputs estándar (build/, *.exe)                │
│  ├─ Dependencies (node_modules/, vcpkg_installed/)        │
│  ├─ Secrets (.env, *.key)                                 │
│  ├─ Language-specific ignores (*.pyc, *.o)                │
│  └─ Project-wide conventions                              │
│                                                           │
│  ❌ NO USAR PARA:                                         │
│  ├─ Personal editor settings                              │
│  ├─ OS-specific files (a menos que TODO el equipo use     │
│  │   mismo OS, raro)                                      │
│  └─ Module-specific exceptions (usa subdirectory)         │
│                                                           │
│  FILOSOFÍA:                                               │
│  "Si clone el repo, ¿TODOS los developers necesitan       │
│   ignorar esto?"                                          │
│   SÍ → Root .gitignore                                    │
│   NO → Global o subdirectory                              │
│                                                           │
├──────────────────────────────────────────────────────────┤
│                                                           │
│  📂 SUBDIRECTORY (module/.gitignore)                      │
│  ════════════════════════════════════                     │
│                                                           │
│  ✅ USAR PARA:                                            │
│  ├─ Module-specific outputs                               │
│  ├─ Exceptions a reglas root                              │
│  ├─ Local generated files                                 │
│  └─ Context-specific ignores                              │
│                                                           │
│  EJEMPLO 1: tests/.gitignore                              │
│  # En tests/, queremos mantener binary fixtures           │
│  # Pero root ignora *.exe                                 │
│  !*.exe                                                   │
│  !test_data/*.bin                                         │
│                                                           │
│  EJEMPLO 2: docs/.gitignore                               │
│  # Docs module genera HTML                                │
│  _build/                                                  │
│  *.html (generated)                                       │
│  !index.html (hand-written)                               │
│                                                           │
│  EJEMPLO 3: experiments/.gitignore                        │
│  # Experimental code puede ser messy                      │
│  # Ignorar TODO excepto README                            │
│  *                                                        │
│  !README.md                                               │
│  !*.py                                                    │
│                                                           │
└──────────────────────────────────────────────────────────┘

Negation Patterns Avanzados

╔═══════════════════════════════════════════════════════════╗
║          NEGATION PATTERN MASTERY                         ║
╚═══════════════════════════════════════════════════════════╝

┌───────────────────────────────────────────────────────────┐
│  LIMITACIÓN IMPORTANTE DE NEGATION                         │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  ⚠️ NO PUEDES negar archivo dentro de directorio ignorado │
│                                                           │
│  ❌ ESTO NO FUNCIONA:                                     │
│  ────────────────────                                     │
│  build/            # Ignorar directorio completo          │
│  !build/README.md  # ❌ No tiene efecto                   │
│                                                           │
│  POR QUÉ:                                                 │
│  Una vez que Git ignora build/, NO mira su contenido.     │
│  No puede "ver" build/README.md para no ignorarlo.        │
│                                                           │
│  ✅ SOLUCIÓN:                                             │
│  ────────────                                             │
│  build/*           # Ignorar CONTENIDO (no directorio)    │
│  !build/README.md  # ✅ Ahora funciona                    │
│                                                           │
│  O aún mejor:                                             │
│  build/*           # Ignorar todo contenido               │
│  !build/           # Permitir el directorio en sí         │
│  !build/README.md  # Permitir README                      │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  PATTERN: Ignorar Todo Excepto...                         │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  OBJETIVO:                                                │
│  En directorio config/, ignorar TODO excepto templates    │
│                                                           │
│  SOLUCIÓN:                                                │
│  config/*              # Ignorar todo el contenido        │
│  !config/*.template    # Excepto templates                │
│  !config/README.md     # Y el README                      │
│                                                           │
│  RESULTADO:                                               │
│  config/                                                  │
│  ├─ app.template       ✅ tracked                         │
│  ├─ db.template        ✅ tracked                         │
│  ├─ README.md          ✅ tracked                         │
│  ├─ dev.yml            ❌ ignorado                        │
│  ├─ prod.yml           ❌ ignorado                        │
│  └─ local.yml          ❌ ignorado                        │
│                                                           │
│  USO:                                                     │
│  Config templates en Git, actual configs fuera            │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  PATTERN: Preservar Estructura de Directorios Vacíos      │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  PROBLEMA:                                                │
│  Git no trackea directorios vacíos                        │
│                                                           │
│  SOLUCIÓN:                                                │
│  Usar .gitkeep (convención, no feature de Git)            │
│                                                           │
│  EJEMPLO:                                                 │
│  logs/*           # Ignorar todos los logs                │
│  !logs/.gitkeep   # EXCEPTO .gitkeep                      │
│                                                           │
│  ESTRUCTURA RESULTANTE:                                   │
│  logs/                                                    │
│  ├─ .gitkeep          ✅ en Git (preserva directorio)     │
│  ├─ app.log           ❌ ignorado (generado en runtime)   │
│  └─ error.log         ❌ ignorado                         │
│                                                           │
│  POR QUÉ:                                                 │
│  Aplicación espera que logs/ exista. .gitkeep asegura     │
│  que directorio se clone, aunque vacío.                   │
│                                                           │
│  ALTERNATIVA:                                             │
│  logs/.gitkeep con contenido:                             │
│  "This directory stores runtime logs (not in Git)"        │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  PATTERN: Nested Exceptions (Excepciones Anidadas)        │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  OBJETIVO:                                                │
│  Ignorar test_outputs/ EXCEPTO golden_masters/            │
│                                                           │
│  NAIVE (no funciona):                                     │
│  test_outputs/                                            │
│  !test_outputs/golden_masters/  # ❌ No funciona          │
│                                                           │
│  CORRECTO:                                                │
│  test_outputs/*                 # Ignorar contenido       │
│  !test_outputs/golden_masters/  # Permitir este subdir    │
│                                                           │
│  O aún más preciso:                                       │
│  test_outputs/*                           # Ignorar todo  │
│  !test_outputs/golden_masters/            # Excepto este  │
│  !test_outputs/golden_masters/**/*.wav    # Y sus WAVs    │
│                                                           │
│  RESULTADO:                                               │
│  test_outputs/                                            │
│  ├─ golden_masters/                                       │
│  │   ├─ reverb_test.wav       ✅ tracked                  │
│  │   └─ eq_test.wav           ✅ tracked                  │
│  ├─ run_2024_01_15/                                       │
│  │   └─ output.wav            ❌ ignorado                 │
│  └─ latest_run.wav            ❌ ignorado                 │
│                                                           │
└───────────────────────────────────────────────────────────┘

⚠️ CAPÍTULO 5: ANTI-PATTERNS Y PELIGROS

Errores Comunes y Sus Consecuencias

╔═══════════════════════════════════════════════════════════╗
║                ANTI-PATTERNS MORTALES                     ║
╚═══════════════════════════════════════════════════════════╝

┌───────────────────────────────────────────────────────────┐
│  ❌ ANTI-PATTERN 1: Ignorar Demasiado Poco                │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  SÍNTOMA:                                                 │
│  Repositorio crece sin control, clone toma minutos        │
│                                                           │
│  CAUSA:                                                   │
│  .gitignore no cubre build outputs o dependencies         │
│                                                           │
│  EJEMPLO:                                                 │
│  # .gitignore (demasiado permisivo)                       │
│  *.log                                                    │
│  # ❌ Falta: build/, node_modules/, *.exe                 │
│                                                           │
│  CONSECUENCIAS:                                           │
│  ├─ Repo size: 50MB → 2GB (40x crecimiento)               │
│  ├─ Clone time: 5s → 3 minutes                            │
│  ├─ Build conflicts: Binarios diferentes en cada dev      │
│  ├─ Merge hell: Git intenta merge binarios                │
│  └─ History contamination: Binarios en toda la historia   │
│                                                           │
│  SOLUCIÓN:                                                │
│  Auditar qué está en Git (no debería):                    │
│    git ls-files | grep -E '(\.exe|\.o|node_modules)'      │
│                                                           │
│  Añadir a .gitignore:                                     │
│    /build/                                                │
│    node_modules/                                          │
│    *.exe                                                  │
│    *.o                                                    │
│                                                           │
│  Limpiar historia si es necesario (CUIDADO):              │
│    git filter-branch o BFG Repo-Cleaner                   │
│                                                           │
│  PREVENCIÓN:                                              │
│  Use template .gitignore al iniciar proyecto              │
│  (GitHub provides templates por lenguaje)                 │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  ❌ ANTI-PATTERN 2: Ignorar Demasiado                     │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  SÍNTOMA:                                                 │
│  Build falla después de clone: "Cannot find X"            │
│                                                           │
│  CAUSA:                                                   │
│  Pattern demasiado amplio ignora archivos críticos        │
│                                                           │
│  EJEMPLO:                                                 │
│  # .gitignore (demasiado agresivo)                        │
│  *.json                                                   │
│  # ❌ Esto ignora package.json (crítico!)                 │
│  # ❌ Esto ignora tsconfig.json (crítico!)                │
│  # ❌ Esto ignora vcpkg.json (crítico!)                   │
│                                                           │
│  CONSECUENCIAS:                                           │
│  ├─ Build imposible (falta manifest)                      │
│  ├─ Confusion: "Works on my machine" (tú tienes el .json) │
│  ├─ Onboarding pesadilla: Nuevos devs no pueden build     │
│  └─ Lost work: Changes a critical files no se commitean   │
│                                                           │
│  SOLUCIÓN:                                                │
│  Ser ESPECÍFICO, no genérico:                             │
│                                                           │
│  ❌ MAL:                                                  │
│  *.json                                                   │
│                                                           │
│  ✅ BIEN:                                                 │
│  # Ignorar generated JSON                                 │
│  /dist/*.json                                             │
│  /build/*.json                                            │
│  *_generated.json                                         │
│                                                           │
│  # Pero PRESERVE manifests                                │
│  !package.json                                            │
│  !tsconfig.json                                           │
│  !vcpkg.json                                              │
│                                                           │
│  O mejor aún:                                             │
│  # Solo ignorar outputs específicos                       │
│  compile_output.json                                      │
│  test_results.json                                        │
│                                                           │
│  PREVENCIÓN:                                              │
│  Test fresh clone periódicamente                          │
│  CI/CD en clean environment catch estos issues            │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  ❌ ANTI-PATTERN 3: Personal Preferences en Project       │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  SÍNTOMA:                                                 │
│  .gitignore tiene entradas de múltiples IDEs/editors      │
│                                                           │
│  EJEMPLO:                                                 │
│  # .gitignore (project)                                   │
│  .idea/          # JetBrains (John usa IntelliJ)          │
│  .vscode/        # VSCode (Sarah usa VSCode)              │
│  *.sublime-*     # Sublime (Mike usa Sublime)             │
│  .vs/            # Visual Studio (Lisa usa VS)            │
│  *.swp           # Vim (Bob usa Vim)                      │
│                                                           │
│  PROBLEMAS:                                               │
│  ├─ Lista crece sin límite (cada dev añade su editor)     │
│  ├─ Mezcla project concerns con personal preferences      │
│  ├─ Pull requests modifican .gitignore constantemente     │
│  └─ Clutter conceptual                                    │
│                                                           │
│  SOLUCIÓN:                                                │
│  1. PERSONAL preferences → GLOBAL .gitignore              │
│     Each dev configures:                                  │
│       git config --global core.excludesfile \             │
│         ~/.gitignore_global                               │
│                                                           │
│     # ~/.gitignore_global (John's)                        │
│     .idea/                                                │
│     *.iml                                                 │
│                                                           │
│     # ~/.gitignore_global (Sarah's)                       │
│     .vscode/settings.json                                 │
│                                                           │
│  2. PROJECT .gitignore → SHARED configs only              │
│     .vscode/launch.json (shared by team)                  │
│     .vscode/tasks.json (shared by team)                   │
│                                                           │
│     # But ignore personal settings                        │
│     .vscode/settings.json                                 │
│                                                           │
│  FILOSOFÍA:                                               │
│  "Tu elección de editor no debe estar en project history" │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  ❌ ANTI-PATTERN 4: Ignorar DESPUÉS de Commit             │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  SÍNTOMA:                                                 │
│  Añadiste a .gitignore pero archivo sigue apareciendo     │
│  en git status                                            │
│                                                           │
│  CAUSA:                                                   │
│  Archivo ya está TRACKED (commitado previamente)          │
│  .gitignore solo afecta UNTRACKED files                   │
│                                                           │
│  EJEMPLO:                                                 │
│  $ git add config.local.yml                               │
│  $ git commit -m "Add local config"                       │
│  [Después te das cuenta que no debería estar en Git]      │
│  $ echo "config.local.yml" >> .gitignore                  │
│  $ git status                                             │
│  modified: config.local.yml  # ❌ Sigue tracked!          │
│                                                           │
│  POR QUÉ NO FUNCIONA:                                     │
│  .gitignore → "No empiences a track esto"                 │
│  NO significa → "Deja de track esto que ya está tracked"  │
│                                                           │
│  SOLUCIÓN:                                                │
│  1. Untrack el archivo (pero keep locally):               │
│     git rm --cached config.local.yml                      │
│                                                           │
│  2. Añade a .gitignore (si no está ya):                   │
│     echo "config.local.yml" >> .gitignore                 │
│                                                           │
│  3. Commit ambos cambios:                                 │
│     git add .gitignore                                    │
│     git commit -m "Untrack config.local.yml"              │
│                                                           │
│  RESULTADO:                                               │
│  ├─ Archivo removido de Git                               │
│  ├─ PERO sigue existiendo localmente                      │
│  └─ Future changes NO se trackean                         │
│                                                           │
│  ⚠️ ADVERTENCIA:                                          │
│  Otros devs verán archivo DELETED en próximo pull.        │
│  Si tienen cambios uncommitted en ese archivo, conflict.  │
│  Comunica al equipo antes de hacer esto.                  │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  ❌ ANTI-PATTERN 5: Falsa Sensación de Seguridad          │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  MITO PELIGROSO:                                          │
│  "Está en .gitignore, así que secreto está protegido"     │
│                                                           │
│  ⚠️ REALIDAD:                                             │
│  .gitignore NO borra historia                             │
│  Si commiteaste secret UNA VEZ, está en history PARA      │
│  SIEMPRE                                                  │
│                                                           │
│  ESCENARIO:                                               │
│  Day 1:                                                   │
│    $ git add .env                                         │
│    $ git commit -m "Add env"  # ❌ SECRET COMMITTED!      │
│    $ git push                                             │
│                                                           │
│  Day 2 (te das cuenta):                                   │
│    $ echo ".env" >> .gitignore                            │
│    $ git rm .env                                          │
│    $ git commit -m "Remove .env"                          │
│                                                           │
│  ⚠️ PROBLEMA:                                             │
│  .env SIGUE en Git history:                               │
│    git log --all -- .env  # Shows commit from Day 1       │
│    git show abc123:.env   # Can still read it!            │
│                                                           │
│  CONSECUENCIAS:                                           │
│  ├─ API key exposed en public repo → comprometido         │
│  ├─ Cualquiera con acceso puede ver historia              │
│  ├─ GitHub/GitLab scanners detectan y alertan             │
│  └─ Credential YA puede estar comprometido                │
│                                                           │
│  SOLUCIÓN (Damage Control):                               │
│  1. ROTATE/REVOKE credentials INMEDIATAMENTE              │
│     (El secreto está comprometido, asume lo peor)         │
│                                                           │
│  2. Remove de historia:                                   │
│     Option A: BFG Repo-Cleaner (más fácil)                │
│       bfg --delete-files .env                             │
│                                                           │
│     Option B: git filter-branch (más control)             │
│       git filter-branch --force --index-filter \          │
│         "git rm --cached --ignore-unmatch .env" \         │
│         --prune-empty --tag-name-filter cat -- --all      │
│                                                           │
│  3. Force push (⚠️ destructive):                          │
│     git push --force --all                                │
│                                                           │
│  4. Notify team (sus clones tienen old history)           │
│                                                           │
│  5. Audit: ¿Secret fue usado maliciously?                 │
│                                                           │
│  PREVENCIÓN:                                              │
│  ├─ Pre-commit hooks (detect secrets ANTES de commit)     │
│  │   - truffleHog                                         │
│  │   - git-secrets                                        │
│  │   - pre-commit framework                               │
│  │                                                         │
│  ├─ Template .env.example (estructura, no values)         │
│  │   DB_HOST=localhost                                    │
│  │   DB_PASSWORD=<your-password-here>                     │
│  │                                                         │
│  └─ Education: Team training sobre secretos               │
│                                                           │
│  REGLA DE ORO:                                            │
│  "Assume que si fue commiteado alguna vez,                │
│   está comprometido PARA SIEMPRE"                         │
│                                                           │
└───────────────────────────────────────────────────────────┘

🎯 CAPÍTULO 6: AUDIOLAB STRATEGY

Decisiones de Diseño para AudioLab

╔═══════════════════════════════════════════════════════════╗
║         AUDIOLAB GITIGNORE PHILOSOPHY                     ║
╚═══════════════════════════════════════════════════════════╝

📋 POLICY DECISIONS (AudioLab-Specific)

┌───────────────────────────────────────────────────────────┐
│  🎵 AUDIO FILES POLICY                                    │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  CATEGORÍAS:                                              │
│                                                           │
│  1️⃣ TEST SAMPLES (< 1MB) → INCLUDE en Git               │
│     ├─ Críticos para automated testing                    │
│     ├─ CI/CD necesita para validar audio processing       │
│     ├─ Small enough (< 1MB cada uno)                      │
│     └─ Ejemplo: sine_440hz.wav, impulse.wav               │
│                                                           │
│     PATTERN:                                              │
│       # Include small test samples                        │
│       !/tests/fixtures/**/*.wav                           │
│       # But limit size (use pre-commit hook)              │
│                                                           │
│  2️⃣ REFERENCE AUDIO (> 1MB) → GIT LFS                    │
│     ├─ Golden masters para quality validation             │
│     ├─ Large files (> 1MB)                                │
│     ├─ NOT directly in .gitignore                         │
│     ├─ Configured in .gitattributes                       │
│     └─ Ejemplo: reference_mix.wav (50MB)                  │
│                                                           │
│     .gitattributes:                                       │
│       *.wav filter=lfs diff=lfs merge=lfs -text           │
│       # But exclude test fixtures (too many files)        │
│       tests/fixtures/**/*.wav !filter !diff !merge text   │
│                                                           │
│  3️⃣ USER RECORDINGS → IGNORE                             │
│     ├─ Generated durante testing manual                   │
│     ├─ User-specific, no reproducible                     │
│     ├─ Can be large                                       │
│     └─ Ejemplo: my_recording_20240115.wav                 │
│                                                           │
│     PATTERN:                                              │
│       /recordings/                                        │
│       /test_outputs/*.wav                                 │
│       *.recorded.wav                                      │
│                                                           │
│  DECISIÓN RATIONALE:                                      │
│  ├─ Small test samples: Essential for CI, size OK         │
│  ├─ Reference audio: Essential but large, use LFS         │
│  └─ User recordings: Not reproducible, ignore             │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  🏗️ BUILD ARTIFACTS POLICY                                │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  ALL BUILD OUTPUTS → IGNORE                               │
│                                                           │
│  RATIONALE:                                               │
│  ├─ Regenerable from source via CMake                     │
│  ├─ Platform-specific (Windows .dll vs Linux .so)         │
│  ├─ Debug vs Release variants                             │
│  └─ Bloat repository significantly                        │
│                                                           │
│  PATTERNS:                                                │
│    # Build directories                                    │
│    /build/                                                │
│    /out/                                                  │
│    cmake-build-*/                                         │
│                                                           │
│    # Binaries                                             │
│    *.exe                                                  │
│    *.dll                                                  │
│    *.so                                                   │
│    *.dylib                                                │
│    *.vst3                                                 │
│    *.component                                            │
│                                                           │
│    # Intermediate                                         │
│    *.o                                                    │
│    *.obj                                                  │
│                                                           │
│  EXCEPTION:                                               │
│    Release binaries (for distribution) → Separate repo    │
│    or GitHub Releases, NOT in source tree                 │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  🔧 CONFIGURATION FILES POLICY                            │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  CATEGORÍAS:                                              │
│                                                           │
│  SHARED CONFIGS → INCLUDE                                 │
│    ├─ .vscode/launch.json (debug configurations)          │
│    ├─ .vscode/tasks.json (build tasks)                    │
│    ├─ .vscode/extensions.json (recommended extensions)    │
│    └─ .clang-format (code style)                          │
│                                                           │
│    RATIONALE:                                             │
│    Team benefits from shared tooling setup                │
│                                                           │
│  PERSONAL SETTINGS → IGNORE                               │
│    ├─ .vscode/settings.json (editor preferences)          │
│    └─ .vs/ (Visual Studio personal settings)              │
│                                                           │
│    RATIONALE:                                             │
│    Each dev has different preferences                     │
│                                                           │
│  LOCAL OVERRIDES → IGNORE                                 │
│    ├─ *.local.yml                                         │
│    ├─ *.local.json                                        │
│    └─ local_settings.*                                    │
│                                                           │
│    RATIONALE:                                             │
│    Allow local customization without affecting team       │
│                                                           │
│  TEMPLATES → INCLUDE                                      │
│    ├─ config.template.yml                                 │
│    ├─ .env.example                                        │
│    └─ database.template.json                              │
│                                                           │
│    RATIONALE:                                             │
│    Documents structure, onboarding aid                    │
│                                                           │
│  PATTERNS:                                                │
│    # Shared team configs                                  │
│    !.vscode/launch.json                                   │
│    !.vscode/tasks.json                                    │
│    !.vscode/extensions.json                               │
│                                                           │
│    # Personal preferences                                 │
│    .vscode/settings.json                                  │
│    .vs/                                                   │
│                                                           │
│    # Local overrides                                      │
│    *.local.*                                              │
│                                                           │
│    # But keep templates                                   │
│    !*.template.*                                          │
│    !.env.example                                          │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  📚 DOCUMENTATION POLICY                                  │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  SOURCE DOCS → INCLUDE                                    │
│    ├─ *.md (hand-written documentation)                   │
│    ├─ Diagrams source (PlantUML, Mermaid)                 │
│    └─ Architecture docs                                   │
│                                                           │
│    RATIONALE:                                             │
│    Documentation is part of the project essence           │
│                                                           │
│  GENERATED DOCS → IGNORE                                  │
│    ├─ /docs/_build/ (Sphinx output)                       │
│    ├─ /docs/html/ (Doxygen output)                        │
│    ├─ /docs/latex/ (LaTeX builds)                         │
│    └─ site/ (MkDocs output)                               │
│                                                           │
│    RATIONALE:                                             │
│    Regenerable from source, bloats repository             │
│                                                           │
│  API DOCS → CONDITIONAL                                   │
│    IF auto-generated from code → IGNORE                   │
│    IF hand-curated → INCLUDE                              │
│                                                           │
│    EXAMPLE:                                               │
│    # Doxygen auto-generated                               │
│    /docs/api/html/      # Ignore                          │
│                                                           │
│    # Hand-written API guides                              │
│    /docs/api-guides/    # Include                         │
│                                                           │
│  PATTERNS:                                                │
│    # Source documentation                                 │
│    !**/*.md                                               │
│    !docs/**/*.puml                                        │
│                                                           │
│    # Build outputs                                        │
│    docs/_build/                                           │
│    docs/html/                                             │
│    docs/latex/                                            │
│                                                           │
└───────────────────────────────────────────────────────────┘

AudioLab .gitignore Completo

# ════════════════════════════════════════════════════════
# AudioLab .gitignore
# Audio Processing Framework & Plugin Suite
# ════════════════════════════════════════════════════════
# See: docs/git/gitignore-philosophy.md for rationale
# ════════════════════════════════════════════════════════


# ────────────────────────────────────────────────────────
# 🏗️ BUILD ARTIFACTS
# ────────────────────────────────────────────────────────

# Build directories
/build/
/out/
/dist/
cmake-build-*/
_build/

# CMake
CMakeCache.txt
CMakeFiles/
cmake_install.cmake
CTestTestfile.cmake
compile_commands.json
*.cmake (except CMakeLists.txt)
!CMakeLists.txt

# Binaries (platform-specific)
*.exe
*.dll
*.so
*.dylib
*.a
*.lib

# Plugin binaries
*.vst3
*.component
*.aaxplugin

# Object files
*.o
*.obj
*.lo
*.slo

# Generated code
*_autogen/
moc_*.cpp
ui_*.h
qrc_*.cpp


# ────────────────────────────────────────────────────────
# 📦 DEPENDENCIES
# ────────────────────────────────────────────────────────

# vcpkg (C++ package manager)
/vcpkg_installed/
/vcpkg/
.vcpkg-root

# CMake FetchContent
build/_deps/

# Python (for automation scripts)
venv/
.venv/
__pycache__/
*.py[cod]
.Python


# ────────────────────────────────────────────────────────
# 🎨 IDE & EDITORS
# ────────────────────────────────────────────────────────

# VSCode - Personal settings
.vscode/settings.json
.vscode/*.code-workspace

# VSCode - EXCEPT shared configs
!.vscode/launch.json
!.vscode/tasks.json
!.vscode/extensions.json

# Visual Studio
.vs/
*.user
*.userosscache
*.sln.docstates
*.vcxproj.filters

# JetBrains
.idea/
*.iml

# Xcode
*.xcodeproj/*
!*.xcodeproj/project.pbxproj


# ────────────────────────────────────────────────────────
# 💻 OPERATING SYSTEMS
# ────────────────────────────────────────────────────────
# Note: Consider moving these to global .gitignore

# macOS
.DS_Store
.AppleDouble
._*

# Windows
Thumbs.db
Desktop.ini

# Linux
*~


# ────────────────────────────────────────────────────────
# 🎵 AUDIO FILES (AudioLab Specific)
# ────────────────────────────────────────────────────────

# User recordings (generated)
/recordings/
/test_outputs/*.wav
*.recorded.wav

# Large test files (use LFS instead)
# Configured in .gitattributes

# EXCEPT: Small test fixtures
!/tests/fixtures/**/*.wav

# Golden masters (reference audio)
# These use Git LFS (see .gitattributes)
!/tests/golden/**/*.wav


# ────────────────────────────────────────────────────────
# 🔧 CONFIGURATION
# ────────────────────────────────────────────────────────

# Local overrides
*.local.yml
*.local.json
*.local.config

# EXCEPT: Templates
!*.template.*
!.env.example


# ────────────────────────────────────────────────────────
# 📝 LOGS & TEMPORARY
# ────────────────────────────────────────────────────────

# Logs
*.log
logs/*

# Preserve directory structure
!logs/.gitkeep

# Temporary files
/tmp/
/temp/
*.tmp
*.cache

# Benchmark results
/benchmarks/results/


# ────────────────────────────────────────────────────────
# 🧪 TESTING
# ────────────────────────────────────────────────────────

# Test outputs (regenerable)
/tests/output/

# Coverage reports
/coverage/
.coverage
htmlcov/

# EXCEPT: Golden masters
!/tests/golden/


# ────────────────────────────────────────────────────────
# 📚 DOCUMENTATION
# ────────────────────────────────────────────────────────

# Generated docs (Doxygen, Sphinx)
/docs/_build/
/docs/html/
/docs/latex/
/site/

# EXCEPT: Hand-written content
!/docs/**/*.md


# ────────────────────────────────────────────────────────
# 🔒 SECRETS (CRITICAL)
# ────────────────────────────────────────────────────────

# Environment variables
.env
.env.local
.env.*.local
.env.production

# EXCEPT: Template
!.env.example
!.env.template

# Credentials
*.key
*.pem
*.p12
*.pfx
credentials.*
*_secret.*
api_key.*


# ════════════════════════════════════════════════════════
# END AudioLab .gitignore
# ════════════════════════════════════════════════════════

📚 CAPÍTULO 7: CASOS DE ESTUDIO

Caso 1: El Repo Obeso (2GB → 50MB)

PROBLEMA INICIAL:
──────────────────
Repositorio: AudioPlugin
Size: 2.1 GB
Clone time: 3-5 minutes
CI/CD: Timing out (10 minute limit)

INVESTIGACIÓN:
──────────────
$ git ls-files | wc -l
8,234 files

$ git ls-files | grep -E '\.(exe|dll|o|obj)' | wc -l
5,891 binaries (72% de archivos!)

$ du -sh .git
2.1G

ROOT CAUSE:
───────────
.gitignore inadequado:
  # Old .gitignore (casi vacío)
  *.log
  .DS_Store

SOLUCIÓN APLICADA:
──────────────────
1. Crear .gitignore comprehensivo:
   /build/
   *.exe
   *.dll
   *.so
   *.o
   *.obj
   node_modules/
   vcpkg_installed/

2. Untrack archivos (pero keep locally):
   git rm -r --cached build/
   git rm --cached '*.exe' '*.dll' '*.o'

3. Commit el cleanup:
   git add .gitignore
   git commit -m "Clean up tracked binaries"

4. Limpiar historia (DESTRUCTIVE):
   bfg --delete-folders build
   bfg --strip-blobs-bigger-than 1M
   git reflog expire --expire=now --all
   git gc --prune=now --aggressive

5. Force push:
   git push --force --all

RESULTADO:
──────────
Repo size: 2.1GB → 48MB (95% reduction)
Clone time: 3-5 min → 8 seconds
CI/CD: Now completes in 2 minutes
Team happiness: 📈📈📈

LECCIONES:
──────────
├─ Start with good .gitignore DESDE DÍA 1
├─ Auditar repo periódicamente (git ls-files)
├─ BFG Repo-Cleaner es excelente herramienta
└─ Communicate con team antes de history rewrite

Caso 2: Secret Leak Disaster

INCIDENTE:
──────────
Commit accidental de .env con API keys a GitHub público

TIMELINE:
─────────
10:30 - Developer commits .env (contiene AWS keys)
10:31 - Push a GitHub
10:45 - GitHub security alert email recibido
10:47 - Team notified
10:50 - PANIC 😱

DAÑO:
─────
├─ AWS API key exposed públicamente
├─ Database credentials exposed
├─ Slack webhook URL exposed
└─ Tiempo exposed: 20 minutos

RESPUESTA INMEDIATA:
────────────────────
1. ROTATE credentials (FIRST PRIORITY):
   ├─ Disable AWS key en console
   ├─ Generate new AWS key
   ├─ Change database password
   └─ Regenerate Slack webhook

   Tiempo: 5 minutos

2. Remove de Git history:
   git filter-branch --force --index-filter \
     "git rm --cached --ignore-unmatch .env" \
     --prune-empty --tag-name-filter cat -- --all

3. Force push:
   git push --force --all
   git push --force --tags

4. Notify team:
   "URGENT: Force pushed to remove secrets.
    Delete your local repo and re-clone."

5. Audit AWS usage:
   Check CloudTrail for unauthorized API calls
   (Luckily: None found, caught quickly)

PREVENCIÓN IMPLEMENTADA:
────────────────────────
1. Pre-commit hook (git-secrets):
   # .git/hooks/pre-commit
   git secrets --scan

2. .env.example (template):
   AWS_ACCESS_KEY=your-key-here
   AWS_SECRET=your-secret-here
   DB_PASSWORD=your-password-here

3. .gitignore update:
   .env
   .env.*
   !.env.example

4. Team training:
   30-minute session sobre secret management

5. CI check:
   GitHub Action para scan secrets en PRs

COSTO:
──────
├─ Engineering time: 4 hours
├─ Stress level: MAXIMUM
├─ Actual damage: $0 (caught quickly)
└─ Lecciones aprendidas: INVALUABLE

TAKEAWAY:
─────────
"Prevention >>> Cure"
20 minutes para setup git-secrets >> 4 hours cleanup

🔄 CAPÍTULO 8: MANTENIMIENTO Y EVOLUCIÓN

Auditoría Periódica

╔═══════════════════════════════════════════════════════════╗
║          GITIGNORE MAINTENANCE CHECKLIST                  ║
╚═══════════════════════════════════════════════════════════╝

📋 QUARTERLY AUDIT (cada 3 meses)

┌───────────────────────────────────────────────────────────┐
│  ✅ CHECK 1: ¿Qué está tracked que no debería?            │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  COMANDO:                                                 │
│    git ls-files | grep -E '\.(exe|dll|o|obj|log|tmp)$'    │
│                                                           │
│  SI ENCUENTRA ARCHIVOS:                                   │
│    1. Añadir patterns a .gitignore                        │
│    2. Untrack: git rm --cached <files>                    │
│    3. Commit el cleanup                                   │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  ✅ CHECK 2: ¿Repo size está creciendo?                   │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  COMANDO:                                                 │
│    du -sh .git                                            │
│    git count-objects -vH                                  │
│                                                           │
│  SI > 100MB:                                              │
│    Investigar qué lo causa                                │
│    Considerar history cleanup o LFS                       │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  ✅ CHECK 3: ¿New tools/IDEs en uso?                      │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  PREGUNTA AL TEAM:                                        │
│    "¿Alguien usa nuevo IDE que genera archivos?"          │
│                                                           │
│  ACTUALIZAR:                                              │
│    Añadir patterns relevantes                             │
│    Preferiblemente a global .gitignore                    │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  ✅ CHECK 4: ¿Patterns obsoletos?                         │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  REVIEW .gitignore:                                       │
│    ├─ ¿Hay patterns para herramientas ya no usadas?       │
│    ├─ ¿Hay duplicados?                                    │
│    └─ ¿Comentarios están actualizados?                    │
│                                                           │
│  CLEANUP:                                                 │
│    Remove obsolete patterns                               │
│    Consolidate duplicates                                 │
│    Update comments                                        │
│                                                           │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│  ✅ CHECK 5: ¿CI/CD time aumentando?                      │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  MONITOR:                                                 │
│    Clone time en CI                                       │
│                                                           │
│  SI > 1 minuto:                                           │
│    Probable causa: Large files en Git                     │
│    Solución: Move a LFS o ignore                          │
│                                                           │
└───────────────────────────────────────────────────────────┘

Evolución con el Proyecto

PHASE 1: PROJECT INCEPTION
──────────────────────────
.gitignore minimal:
  /build/
  *.exe
  .env

PHASE 2: DEPENDENCIES ADDED
───────────────────────────
Add package managers:
  + node_modules/
  + vcpkg_installed/
  + venv/

PHASE 3: TEAM GROWS
───────────────────
Add IDE variety:
  + .vscode/settings.json
  + .idea/
  + .vs/

PHASE 4: CI/CD SETUP
────────────────────
Add build outputs:
  + /dist/
  + coverage/
  + test_results/

PHASE 5: PRODUCTION
───────────────────
Add secrets management:
  + .env.*
  + *.key
  + credentials.*

FILOSOFÍA:
──────────
.gitignore evoluciona con proyecto
No necesitas TODO desde día 1
Añade patterns cuando se necesitan
Review y cleanup periódicamente

🎓 CONCLUSIÓN

┌──────────────────────────────────────────────────────────┐
│                                                           │
│  .gitignore no es una lista arbitraria de archivos.      │
│  Es una declaración filosófica sobre:                     │
│                                                           │
│  • Qué constituye la ESENCIA de tu proyecto               │
│  • Qué es DERIVABLE y reproducible                        │
│  • Qué es PERSONAL vs compartido                          │
│  • Qué es SECRETO y debe protegerse                       │
│                                                           │
│  La exclusión inteligente protege:                        │
│  ✓ Tamaño del repositorio                                 │
│  ✓ Velocidad de clone/CI                                  │
│  ✓ Claridad de historia                                   │
│  ✓ Seguridad de credentials                               │
│  ✓ Sanidad del equipo                                     │
│                                                           │
│  Invierte tiempo en diseñar .gitignore bien.              │
│  Future you te lo agradecerá.                             │
│                                                           │
└──────────────────────────────────────────────────────────┘

REGLAS DE ORO:

  1. SOURCE, no derived - Si se puede regenerar, ignore
  2. SHARED, no personal - Personal preferences → global
  3. PROTECT secrets - .gitignore + pre-commit hooks
  4. BE SPECIFIC - build/*.json mejor que *.json
  5. DOCUMENT WHY - Comments explican rationale
  6. AUDIT regularly - Quarterly review
  7. TEMPLATES over configs - .env.example, not .env
  8. LFS para large - Audio samples > 1MB
  9. TEST fresh clone - Ensure build works
  10. EVOLVE thoughtfully - Add patterns cuando necesario

Documento versión 1.0 AudioLab Foundation • Version Control • Gitignore Philosophy "La exclusión inteligente es el arte de decidir qué merece ser recordado."