--- version: 1.0.0 updated: 2026-03-12 tags: [workspace, gitea, import, repos] --- # Command: import-repo Importa repositorios existentes al sistema Dataforge: desde GitHub/GitLab/otra instancia Gitea (URL remota), o adoptando un repo local en `workspaces/` que aún no está en Gitea. ## Para el usuario ### Cuándo usar este comando Usar cuando necesites incorporar un repositorio existente al sistema Dataforge: - Tienes un repo en GitHub/GitLab y quieres migrarlo a Gitea - Tienes un repo en otra instancia de Gitea y quieres clonarlo a la tuya - Tienes un directorio en `workspaces/` con git, pero sin estar en Gitea - Quieres adoptar un proyecto legacy en el ecosistema Dataforge ### Prerequisitos - Variables de entorno configuradas: `GITEA_URL` y `GITEA_TOKEN` - Acceso de lectura al repositorio origen (si es remoto) - Feature flag `workspace_commands` habilitado ### Variables de entorno requeridas ```bash export GITEA_URL="https://gitea.example.com" export GITEA_TOKEN="tu-token-de-api" export DATAFORGE_REPOS="./workspaces" # opcional, default: ./workspaces ``` ### Modos de importación #### Caso 1: Importar desde URL remota ```bash /workspace:import-repo # Fuente: https://github.com/Bl4cksmith/analytics-pipeline # Destino en Gitea: analytics-pipeline (por defecto) ``` Flujo interno: 1. Crear repo vacío en Gitea 2. Clonar origen con `git clone --mirror` (preserva historial completo) 3. Push a Gitea con `git push --mirror` 4. Clonar en `workspaces/` para desarrollo local 5. Registrar en BD SQLite 6. Limpiar temporales #### Caso 2: Adoptar repo local ```bash /workspace:import-repo # Fuente: legacy-tool (nombre del dir en workspaces/) # Destino en Gitea: legacy-tool (por defecto) ``` Flujo interno: 1. Verificar que `workspaces/legacy-tool/.git` existe 2. Crear repo vacío en Gitea 3. Añadir Gitea como remote `gitea` 4. Push de todos los branches y tags a Gitea 5. Registrar en BD SQLite --- ## Para Claude ### Flujo interactivo #### Paso 1: Solicitar fuente ``` Fuente del repositorio: - URL remota (ej: https://github.com/user/repo) - Nombre local en workspaces/ (ej: legacy-tool) ¿Fuente? ``` Leer la respuesta del usuario. #### Paso 2: Detectar modo y analizar Usar funciones del core Go: - `core.ValidateImportSource(source)` — validar que es segura - `core.DetectImportMode(source)` — detectar si es remota o local - `core.GenerateDestinationName(source)` — sugerir nombre de destino Si es remota, informar al usuario: ``` ✓ Modo: importar desde URL remota Fuente: https://github.com/user/analytics-pipeline Historia Git: se preservará completa (--mirror) ``` Si es local, informar: ``` ✓ Modo: adoptar repositorio local Directorio: workspaces/legacy-tool Verificando .git... ``` Si es local, verificar que existe `workspaces/{source}/.git`. Si no existe, informar error: ``` ✗ No se encontró .git en workspaces/legacy-tool ¿Quizás quisiste usar la URL completa? ``` #### Paso 3: Solicitar nombre de destino ``` Nombre en Gitea (Enter para usar '{nombre-generado}'): ``` Si el usuario presiona Enter, usar el nombre generado. Si escribe otro, validar con `core.ValidateRepoName`. #### Paso 4: Verificar que no existe en Gitea Llamar `GET /api/v1/repos/{owner}/{destName}`. Si ya existe: ``` ✗ El repositorio {owner}/{destName} ya existe en Gitea. Opciones: 1. Usar otro nombre 2. Cancelar ``` #### Paso 5: Solicitar opciones adicionales ``` ¿Repositorio privado? (s/N): Descripción (opcional): ``` #### Paso 6: Mostrar resumen y confirmar ``` Resumen de importación: Fuente: {source} Destino Gitea: {gitea_url}/{owner}/{destName} Workspace local: workspaces/{destName} Tipo detectado: {tipo} Historia Git: se preservará completa Privado: {sí/no} ¿Importar repositorio? (s/N): ``` Si el usuario responde "n" o Enter, cancelar: ``` Importación cancelada. ``` #### Paso 7: Ejecutar importación Llamar `app.ImportRepositoryCommand(config, params)` con los parámetros recogidos. Mostrar progreso: ``` Ejecutando importación... ✓ Creando repositorio en Gitea... ✓ Clonando fuente... ✓ Subiendo contenido a Gitea... ✓ Clonando en workspaces/... ✓ Registrando en base de datos... ✓ Limpiando temporales... ``` O para modo adopción local: ``` Ejecutando adopción... ✓ Creando repositorio en Gitea... ✓ Añadiendo remote 'gitea'... ✓ Subiendo branches y tags... ✓ Registrando en base de datos... ``` #### Paso 8: Mostrar resultado **Éxito:** ``` Repositorio importado exitosamente. Workspace: workspaces/{destName} Gitea URL: {gitea_url}/{owner}/{destName} Tipo: {tipo} Pasos siguientes: cd workspaces/{destName} # El repositorio está listo para usar # Para sincronizar en otros nodos: /workspace:sync-repos ``` **Error:** ``` ✗ Error durante la importación: {mensaje de error} Rollback completado: no quedaron cambios parciales. Sugerencias: - Verifica que tienes acceso al repositorio origen - Verifica que GITEA_TOKEN tiene permisos de escritura - Verifica la conectividad de red ``` ### Manejo de errores comunes #### Repo ya existe en Gitea - Detectar en Paso 4, antes de iniciar la operación - Ofrecer cambiar el nombre #### Credenciales inválidas / sin acceso - Ocurre al intentar clonar repo privado sin credenciales - Mensaje: "Acceso denegado al repositorio origen. Verifica que tienes acceso de lectura." #### Tamaño excesivo - Si la operación tarda más de 10 minutos, el comando tiene timeout - Mensaje: "Timeout: el repositorio puede ser muy grande. Intenta clonar manualmente." #### Fallo de red - Puede ocurrir durante clone o push - Rollback automático: se elimina el repo creado en Gitea #### .git no encontrado (modo local) - Verificar antes de crear repo en Gitea - Mensaje: "No se encontró .git en workspaces/{source}" ### Integración con el sistema Después de una importación exitosa: - El repo está en Gitea (fuente de verdad) - El repo está en `workspaces/{name}` (desarrollo local) - El repo está en la BD SQLite (consultable con `/workspace:list-repos`) - Compatible con `/workspace:sync-repos` para sincronizar en otros nodos ### Troubleshooting **Error: "fuente inválida"** - La fuente contiene caracteres especiales (`;`, `|`, etc.) - Verificar que la URL es correcta **Error: "nombre de destino inválido"** - El nombre contiene caracteres no permitidos - Solo letras, números, guiones y puntos. Entre 2-100 caracteres. **Error: "rollback falló"** - Estado inconsistente: repo puede existir en Gitea pero no localmente - Verificar manualmente: `GET /api/v1/repos/{owner}/{name}` - Si existe en Gitea pero no localmente, ejecutar `/workspace:sync-repos` ## Convenciones - Confirmación obligatoria antes de ejecutar - Rollback automático si falla cualquier paso - Historia Git siempre preservada (--mirror para remotos, --all + --tags para locales) - El remote `gitea` se añade sin sobrescribir `origin` existente - Feature flag `workspace_commands` debe estar habilitado ## Referencias - Issue 0011e: Especificación completa - `app.ImportRepositoryCommand`: Implementación Go - `core.ValidateImportSource`, `core.DetectImportMode`: Validación pura - `shell.CloneRemoteToTemp`, `shell.AdoptLocalRepo`: Operaciones I/O - Gitea API: GET /api/v1/repos/{owner}/{repo}