# /full-git-pull — Pull de fn_registry + todos los sub-repos + submodules + fn sync

Trae los últimos cambios del remote para el repo principal `fn_registry`, todos los sub-repos git anidados, y los submodules de `cpp/vendor/`. Después regenera `registry.db` y corre `fn sync` para tirar de la metadata del `registry_api` (apps, projects, analysis, vaults, pc_locations registrados desde otros PCs).

## Argumento

`$ARGUMENTS` — sin uso, ignorar.

## Pasos

### 1. Descubrir repos + clonar dataforge/<name> faltantes

```bash
cd /home/lucas/fn_registry  # ajustar al PC

REPOS=$(find . -name ".git" -type d \
  -not -path "./.git/*" \
  -not -path "*/node_modules/*" \
  -not -path "*/.venv/*" \
  -not -path "*/cpp/vendor/*" \
  -not -path "*/cpp/build/*" \
  -not -path "*/sources/*" \
  -not -path "*/temp/*" \
  -not -path "*/subrepos/*" 2>/dev/null | sed 's|/.git$||')
REPOS=". $REPOS"
```

Despues, despues de `fn sync` (paso 5), hacer **una segunda pasada** para clonar repos `dataforge/<name>` que esten registrados en `pc_locations` o `apps`/`analysis` pero no existan localmente — la metadata vino del API y los repos hay que clonarlos:

```bash
# Listar apps + analysis registradas con dir_path
sqlite3 registry.db "SELECT name, dir_path FROM apps WHERE dir_path != '' UNION SELECT name, dir_path FROM analysis WHERE dir_path != '';" | while IFS='|' read name path; do
  full="$path"
  if [[ ! -d "$full/.git" && ! -d "$full" ]]; then
    GITEA_URL=$(pass agentes/gitea-url | head -n1)
    GITEA_TOKEN=$(pass gitea/dataforge-git-token | head -n1)
    git clone "https://${GITEA_TOKEN}@${GITEA_URL#https://}/dataforge/${name}.git" "$full" 2>&1 | tail -2
  fi
done
```

### 2. Para cada repo: stash si dirty, pull --ff-only, pop

```bash
for r in $REPOS; do
  ( cd "$r" \
    && DIRTY=$(git status --porcelain | wc -l) \
    && if [ "$DIRTY" -gt 0 ]; then
         git stash push -m "auto-stash before /full-git-pull" --include-untracked >/dev/null
         STASHED=1
       else
         STASHED=0
       fi \
    && git fetch origin 2>&1 | tail -1 \
    && git pull --ff-only 2>&1 | tail -3 \
    && if [ "$STASHED" = "1" ]; then
         git stash pop 2>&1 | tail -3
       fi
  )
done
```

- Si `--ff-only` falla por divergencia, abortar el pull de ese repo y reportar (no rebasear sin permiso).
- Si `stash pop` produce conflictos, **avisar** y dejar el conflicto al usuario; no resolverlo automáticamente.

### 3. Submodules del repo principal

```bash
git submodule update --init --recursive 2>&1 | tail -10
```

### 4. Regenerar registry.db local

```bash
CGO_ENABLED=1 ./fn index 2>&1 | tail -3
```

### 5. fn sync con credenciales de pass

```bash
USER=$(pass registry/basicauth-user | head -1)
PASSWD=$(pass registry/basicauth-pass | head -1)
TOKEN=$(pass registry/api-token | head -1)
export FN_REGISTRY_API="https://${USER}:${PASSWD}@registry.organic-machine.com"
export REGISTRY_API_TOKEN="$TOKEN"
./fn sync
```

Si `pass` falla → gpg-agent locked, pedir al usuario `pass show registry/api-token` en su terminal real.

### 6. Resumen

Tabla concisa: por repo, commits pulleados o "ya estaba al día"; submodules actualizados; result de `fn index`; result de `fn sync`.

## Notas

- Pull solo es fast-forward — nunca rebase ni merge automático.
- Si el repo principal pulleó cambios y eliminó archivos referenciados por sub-repos (raro), el usuario debe resolverlo manualmente.
- `fn index` se corre **antes** de `fn sync` para que las locations locales reflejen el estado actual.
