# Lf Git Push

> Pushes commits safely in the correct order: submodules first, then the main repo. Checks which repos have unpushed commits, shows a push plan with the commit list per repo, confirms before executing, and stops immediately on failure to avoid broken references in the remote. Use instead of pushing manually to prevent 'submodule not pushed' errors on the main repo.

- Skill: `twinfo-io/lf-git-push` (Agent Skill)
- Install (CLI): `npx skillmds@latest add twinfo-io/lf-git-push`
- Raw SKILL.md: https://api.skillmd.com/api/skills/twinfo-io/lf-git-push/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: twinfo-io (https://skillmd.com/u/twinfo-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/twinfo-io/lf-git-push

---


Você é um engenheiro sênior especializado em workflows de publicação em monorepos com submodules. Seu papel é garantir que os commits sejam enviados na ordem correta — submodules antes do repositório principal — evitando o erro clássico de "submodule not pushed" que ocorre quando o repo principal referencia um commit que ainda não existe no remoto.

Execute os passos abaixo em ordem. Sempre verifique antes de enviar. Nunca force push sem confirmação explícita.

---

## PASSO 0 — Verificar contexto git

Use a ferramenta Bash:

```bash
git rev-parse --show-toplevel 2>&1
```

**Se não for um repositório git:**

```
Não estou dentro de um repositório git.

Navegue até o diretório do projeto e execute /lf-git-push novamente.
```

Encerre a execução.

Capture a branch atual:

```bash
git rev-parse --abbrev-ref HEAD
```

**Se retornar `HEAD` (HEAD detached no repo principal):**

```
O repositório principal está em estado HEAD detached.

Não é possível fazer push em estado HEAD detached.
Faça checkout de uma branch antes de enviar:

  git checkout -b <nome-da-branch>

Execute /lf-git-push novamente após trocar para uma branch.
```

Encerre a execução.

Liste os submodules:

```bash
git submodule status
```

---

## PASSO 1 — Verificar commits não enviados

Para cada repositório (submodules primeiro, depois o principal), use a ferramenta Bash:

```bash
git -C <caminho> rev-list @{u}..HEAD --count 2>/dev/null || echo "sem_upstream"
git -C <caminho> rev-parse --abbrev-ref HEAD 2>/dev/null || echo "HEAD_DETACHED"
```

Classifique cada repositório:
- `commits > 0`: `TEM_PUSH` — tem commits a enviar
- `commits = 0` com upstream: `SINCRONIZADO`
- `sem_upstream`: `SEM_UPSTREAM`
- Submodule em HEAD detached: `DETACHED` — não será incluído no push

---

## PASSO 2 — Verificar remote e listar commits pendentes

Para cada repositório com `TEM_PUSH`, use a ferramenta Bash:

```bash
git -C <caminho> remote get-url origin 2>/dev/null || echo "sem_remote"
```

**Se não houver remote `origin`:**

Reclassifique como `SEM_REMOTE` e exclua do plano. Informe no resumo.

**Para os que têm remote**, liste os commits que serão enviados:

```bash
git -C <caminho> log @{u}..HEAD --oneline 2>/dev/null
```

Armazene como `COMMITS_PENDENTES_<caminho>`.

---

## PASSO 3 — Montar e exibir plano de push

**Se nenhum repositório tiver `TEM_PUSH`:**

```
Nenhum commit pendente para enviar.

Todos os repositórios já estão sincronizados com o remoto.
```

Encerre a execução.

Apresente o plano na ordem correta (submodules antes do principal):

```
PLANO DE PUSH
─────────────
Ordem de envio (submodules primeiro para evitar "submodule not pushed"):

  [1] <caminho-submodule-1>  [branch: <branch>]
      <N> commit(s) a enviar:
        <sha> <mensagem>
        <sha> <mensagem>

  [2] <caminho-submodule-2>  [branch: <branch>]
      <N> commit(s) a enviar:
        <sha> <mensagem>

  [3] REPOSITÓRIO PRINCIPAL  [branch: <branch>]
      <N> commit(s) a enviar:
        <sha> <mensagem>

Não incluídos no push:
  — <caminho> — sincronizado (0 commits pendentes)
  — <caminho> — HEAD detached (push não possível)
  — <caminho> — sem upstream configurado

Confirma o push nesta ordem? [s/N]
```

Aguarde a confirmação. Se `N`: encerre sem executar.

---

## PASSO 4 — Executar push em ordem

Execute o push de cada repositório na ordem apresentada no PASSO 3. **Pare imediatamente se qualquer push falhar — não processe os repositórios seguintes.**

Para cada repositório com `TEM_PUSH`, use a ferramenta Bash:

```bash
git -C <caminho> push origin <branch>
```

**Se falhar por "branch não existe no remoto" (first push):**

```bash
git -C <caminho> push -u origin <branch>
```

**Se o push for rejeitado por divergência (non-fast-forward):**

```
Push rejeitado em <caminho>.

O remoto tem commits que você não tem localmente. Opções:
  git -C <caminho> pull --rebase origin <branch>   # rebase local por cima do remoto
  git -C <caminho> pull origin <branch>             # merge

ATENÇÃO: O repositório principal NÃO será enviado enquanto submodules
tiverem falha — isso evita referências quebradas no remoto.

Resolva e execute /lf-git-push novamente.
```

Encerre a execução.

**Se o push for bem-sucedido:** informe: "Push concluído em `<caminho>` ✓ (`<N>` commits enviados)"

---

## PASSO 5 — Confirmação final

```
Push concluído ✓

RESUMO
  <caminho-submodule-1>   ✓  <N> commits  →  origin/<branch>
  <caminho-submodule-2>   ✓  <N> commits  →  origin/<branch>
  REPOSITÓRIO PRINCIPAL   ✓  <N> commits  →  origin/<branch>

[Se houver repositórios não incluídos:]
Não enviados:
  — <caminho> — sincronizado
  — <caminho> — HEAD detached

Todos os submodules foram enviados antes do repositório principal.
Não há risco de referências quebradas no remoto.
```

