Merge branch 'cursor/6b8a5e62'
This commit is contained in:
commit
fb2af739fc
1 changed files with 86 additions and 24 deletions
|
|
@ -2,10 +2,11 @@
|
|||
name: rebase-on-main
|
||||
description: >-
|
||||
Sync the current feature branch with latest origin/main via fetch + rebase,
|
||||
then resolve conflicts intelligently. Use after /simplify & /impeccable and
|
||||
before capture-review-debts when the user says "pull main, rebase on main,
|
||||
resolve conflicts", "rebase on main", "atualiza com main", "sincroniza com
|
||||
main", or asks to bring the worktree branch up to date with main.
|
||||
then resolve conflicts intelligently. Auto-handles a dirty tree (commit WIP
|
||||
or stash+pop — no asking). Use after /simplify & /impeccable and before
|
||||
capture-review-debts when the user says "pull main, rebase on main, resolve
|
||||
conflicts", "rebase on main", "atualiza com main", "sincroniza com main",
|
||||
or asks to bring the worktree branch up to date with main.
|
||||
---
|
||||
|
||||
# Rebase on main
|
||||
|
|
@ -20,9 +21,11 @@ Etapa do fluxo de entrega Teqo (worktree) **depois** de `/simplify` + `/impeccab
|
|||
|
||||
```
|
||||
- [ ] 1. Detectar ambiente (branch, worktree, dirty tree)
|
||||
- [ ] 1b. Se dirty: decidir commit vs stash (sem perguntar) e limpar a árvore
|
||||
- [ ] 2. Fetch origin/main
|
||||
- [ ] 3. Rebase da branch atual em cima de origin/main
|
||||
- [ ] 4. Resolver conflitos (ou abortar e perguntar se intents colidem)
|
||||
- [ ] 4. Resolver conflitos do rebase (ou abortar e perguntar se intents colidem)
|
||||
- [ ] 4b. Se usou stash: stash pop e resolver conflitos do pop
|
||||
- [ ] 5. Verificar resultado e reportar
|
||||
```
|
||||
|
||||
|
|
@ -40,17 +43,71 @@ git log --oneline -5 HEAD
|
|||
git log --oneline -3 origin/main 2>/dev/null || true
|
||||
```
|
||||
|
||||
Se dirty, também colete (em paralelo com o restante do diagnóstico):
|
||||
|
||||
```bash
|
||||
git diff --stat
|
||||
git diff --cached --stat
|
||||
git diff --name-only
|
||||
git diff --cached --name-only
|
||||
git status --porcelain
|
||||
git log --oneline origin/main..HEAD 2>/dev/null | head -20
|
||||
git diff --name-only origin/main...HEAD 2>/dev/null
|
||||
```
|
||||
|
||||
**Guards (pare e explique se verdadeiros):**
|
||||
|
||||
| Condição | Ação |
|
||||
| -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Branch é `main` / `master` | Não rebasear main em si. Pare. |
|
||||
| Detached HEAD | Pare; peça branch nomeada ou checkout. |
|
||||
| Working tree dirty (uncommitted) | Stash **só** se o usuário autorizar; preferência: commit primeiro via `ship-to-main` parcial, ou stash com mensagem `rebase-on-main:<branch>`. Sem dirty tree limpa → não invente stash. |
|
||||
| Rebase / merge / cherry-pick já em andamento | Continue ou `git rebase --abort` **só** com confirmação explícita. |
|
||||
| Condição | Ação |
|
||||
| -------------------------------------------- | ------------------------------------------------------------------------------------------ |
|
||||
| Branch é `main` / `master` | Não rebasear main em si. Pare. |
|
||||
| Detached HEAD | Pare; peça branch nomeada ou checkout. |
|
||||
| Working tree dirty (uncommitted) | **Não pergunte.** Decida e execute sozinho — ver [Passo 1b](#passo-1b--árvore-suja-auto). |
|
||||
| Rebase / merge / cherry-pick já em andamento | Continue ou `git rebase --abort` **só** com confirmação explícita. |
|
||||
|
||||
Se `GIT_DIR != GIT_COMMON` (e não é submodule): está em worktree — OK; rebase acontece **aqui**, na feature branch.
|
||||
|
||||
## Passo 1b — Árvore suja (auto)
|
||||
|
||||
Objetivo: working tree limpa **antes** do rebase, sem pedir autorização. Escolha **um** caminho e anuncie em uma linha (“dirty → commit …” ou “dirty → stash …”).
|
||||
|
||||
### Decisão (avaliar nesta ordem; primeira que bater vence)
|
||||
|
||||
| # | Condição | Caminho |
|
||||
| --- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- |
|
||||
| 1 | Há secretos / credenciais / env local no dirty set (`.env`, `.env.*`, `credentials.json`, `*.pem`, tokens óbvios no diff) | **stash** |
|
||||
| 2 | Dirty é só ruído local / efêmero: untracked scratch, IDE/OS (`.DS_Store`, `.idea/`, `*.swp`), cache, arquivos fora de `src/` `tests/` `docs/` `scripts/` `.cursor/skills/` `.github/` e sem relação com o tip da branch | **stash** |
|
||||
| 3 | Dirty é mistura: parte parece WIP da feature **e** parte é ruído/local/secrets → **não** faça commit parcial no escuro | **stash** |
|
||||
| 4 | Diff é WIP intencional da feature: toca os mesmos paths (ou domínio) de `origin/main...HEAD`, ou continua o intent dos commits recentes da branch; dá para redigir **uma** mensagem de commit coerente com o estilo do repo | **commit** |
|
||||
| 5 | Branch ainda sem commits próprios (`origin/main..HEAD` vazio) mas o dirty é claramente o trabalho da feature (plano/roadmap item, arquivos de entrega) e a mensagem fecha em uma frase | **commit** |
|
||||
| 6 | Caso ambíguo / WIP quebrado demais para descrever sem inventar história / não passa no feeling de “um commit” | **stash** |
|
||||
|
||||
**Default se empatar:** **stash** (reversível; não polui o histórico). **Nunca** invente stash/commit com árvore já limpa.
|
||||
|
||||
### Caminho A — commit + rebase
|
||||
|
||||
Siga o protocolo de commit do usuário (status/diff/log → mensagem → `git add` seletivo → `git commit` via HEREDOC). Regras extras desta skill:
|
||||
|
||||
- Commit **só** o dirty set da feature; não stageie secrets (se aparecerem no meio, **mude para stash** em vez de commitar o resto).
|
||||
- Mensagem: 1–2 frases no estilo do `git log` da branch; foque no porquê (evitar “wip:” genérico salvo se o log local já usa isso).
|
||||
- Se o pre-commit hook **falhar**: corrija e faça um **novo** commit (não `--amend`, salvo as regras do usuário). Se ficar claro que o dirty não era commitável, e o commit desta invocação ainda é o tip local não-pushed que **você** criou agora: `git reset --soft HEAD~1`, então mude para **stash** e siga.
|
||||
- Depois do commit limpo → Passo 2 → rebase → conflitos do rebase → Passo 5.
|
||||
- Esse commit fica na branch (entra no `ship-to-main` depois). Não faça push aqui.
|
||||
|
||||
### Caminho B — stash + rebase + stash pop
|
||||
|
||||
```bash
|
||||
git stash push -u -m "rebase-on-main:<branch>"
|
||||
# … Passo 2 + rebase (Passo 3–4) até a branch estar rebased e limpa …
|
||||
git stash pop
|
||||
```
|
||||
|
||||
- Use `-u` para incluir untracked (senão o rebase ainda pode falhar / o “limpo” é mentira).
|
||||
- Se o Passo 2 concluir “já sincronizado” (no-op): **mesmo assim** faça o `stash pop` (Passo 4b) antes de encerrar — o stash não pode ficar órfão.
|
||||
- Se `stash pop` gerar conflitos: resolva como no Passo 4 (ler os dois lados; preservar intent). Depois `git add` nos resolvidos — **não** crie commit só do pop; deixe o resultado como dirty working tree restaurada, a menos que o usuário peça commit.
|
||||
- Se `stash pop` falhar de forma estranha (stash parcialmente aplicado): pare, reporte `git stash list` + status, e **não** rode `stash drop` no escuro.
|
||||
- Em sucesso do pop sem conflitos, o stash entry costuma dropar sozinho; confirme com `git stash list`.
|
||||
- Conflitos de produto irreconciliáveis no pop → explique e pergunte (mesmo critério do Passo 4); não descarte o stash.
|
||||
|
||||
## Passo 2 — Fetch
|
||||
|
||||
```bash
|
||||
|
|
@ -65,7 +122,7 @@ git merge-base HEAD origin/main
|
|||
git log --oneline --left-right HEAD...origin/main | head -40
|
||||
```
|
||||
|
||||
Se já está up-to-date (`HEAD` contém `origin/main` e não há commits de main à frente): reporte "já sincronizado" e pare (sucesso no-op).
|
||||
Se já está up-to-date (`HEAD` contém `origin/main` e não há commits de main à frente): reporte "já sincronizado". Se o Passo 1b usou **stash**, ainda assim execute o Passo 4b (`stash pop`) antes de encerrar; senão pare (sucesso no-op).
|
||||
|
||||
## Passo 3 — Rebase
|
||||
|
||||
|
|
@ -122,21 +179,26 @@ Opcional e leve (se o rebase tocou schema/types): `pnpm exec tsc --noEmit` nos a
|
|||
**Resumo ao usuário (curto):**
|
||||
|
||||
1. Branch + worktree path
|
||||
2. Quantos commits rebased / se no-op
|
||||
3. Conflitos resolvidos (paths + uma linha de racional cada) **ou** “nenhum”
|
||||
4. Se abortou: por quê + o que precisa de decisão
|
||||
5. Próximo passo natural: `capture-review-debts` (se ainda não rodou), `ship-to-main`, ou o atalho `close-delivery` (rebase+debts+ship)
|
||||
2. Se a árvore estava suja: caminho escolhido (**commit** com hash/msg **ou** **stash** + resultado do pop) e a regra da tabela que decidiu
|
||||
3. Quantos commits rebased / se no-op
|
||||
4. Conflitos resolvidos — rebase e/ou stash pop (paths + uma linha de racional cada) **ou** “nenhum”
|
||||
5. Se abortou: por quê + o que precisa de decisão
|
||||
6. Próximo passo natural: `capture-review-debts` (se ainda não rodou), `ship-to-main`, ou o atalho `close-delivery` (rebase+debts+ship)
|
||||
|
||||
## Anti-padrões
|
||||
|
||||
| Nunca | Em vez disso |
|
||||
| -------------------------------------------- | ------------------------------------------------------------- |
|
||||
| `git push --force` sem pedido | Deixe force-with-lease para `ship-to-main` / pedido explícito |
|
||||
| Resolver conflito sem ler os dois lados | Abra o arquivo + `git show :1/:2/:3:` se precisar |
|
||||
| Continuar rebase com markers `<<<<<<<` | Grep por `^<<<<<<<` antes de `--continue` |
|
||||
| Rebasear em cima de `main` local stale | Sempre `fetch` + `origin/main` |
|
||||
| `reset --hard` para “limpar” conflito | Abort ou resolve; hard reset só com pedido explícito |
|
||||
| Expandir escopo (refatorar além do conflito) | Só o necessário para o rebase passar |
|
||||
| Nunca | Em vez disso |
|
||||
| ----------------------------------------------- | ----------------------------------------------------------------------------- |
|
||||
| Perguntar commit vs stash com árvore suja | Decida pela tabela do Passo 1b e execute |
|
||||
| `git push --force` sem pedido | Deixe force-with-lease para `ship-to-main` / pedido explícito |
|
||||
| Commitar `.env` / secrets para “limpar” a árvore | Stash (regra 1); nunca stageie secret |
|
||||
| Stash sem `-u` deixando untracked no caminho | `git stash push -u -m "rebase-on-main:<branch>"` |
|
||||
| Resolver conflito sem ler os dois lados | Abra o arquivo + `git show :1/:2/:3:` se precisar |
|
||||
| Continuar rebase com markers `<<<<<<<` | Grep por `^<<<<<<<` antes de `--continue` |
|
||||
| Rebasear em cima de `main` local stale | Sempre `fetch` + `origin/main` |
|
||||
| `reset --hard` para “limpar” conflito | Abort ou resolve; hard reset só com pedido explícito |
|
||||
| Expandir escopo (refatorar além do conflito) | Só o necessário para o rebase passar |
|
||||
| Dropar stash após pop conflictivo | Preserve o entry; reporte e pergunte |
|
||||
|
||||
## Posição no fluxo
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue