Skip to content

Git workflow

Branch

  • main è sempre verde e rilasciabile. Nessun push diretto: si entra via Pull Request.
  • Branch di lavoro: <tipo>/<descrizione-breve>, es. feat/langfuse-sessions-pipeline, fix/cursor-batch-size.
  • Tipi: feat, fix, refactor, docs, test, chore, perf.

Worktree: un'attività, un worktree

Ogni attività si sviluppa in un worktree suo, sotto .claude/worktrees/<descrizione>/ (già in .gitignore), con il proprio branch <tipo>/<descrizione> staccato da origin/dev. La cartella principale resta su dev: serve a creare worktree e ad aggiornarsi, non a lavorare.

Perché. La cartella principale è condivisa da tutte le sessioni, umane e agenti. Un git checkout lì sposta il branch anche sotto chi ci sta lavorando, e il suo commit successivo finisce sul branch sbagliato: è successo il 14 settembre 2026, con un commit di doc atterrato su feat/lookup-postgres di un'altra sessione. Con un worktree per attività ognuno ha cartella, branch e node_modules propri: le attività avanzano in parallelo e confluiscono su dev via PR.

Ciclo di vita

bash
# 1. Crea: branch nuovo da origin/dev aggiornato
git fetch origin
git worktree add --no-track -b feat/<descrizione> .claude/worktrees/<descrizione> origin/dev
cd .claude/worktrees/<descrizione>

# 2. Setup: node_modules e .env non sono condivisi fra worktree
pnpm install
cp ../../../.env .env          # solo se l'attività esegue pipeline contro sistemi reali

# 3. Lavora e committa qui; poi push esplicito del branch e PR verso dev
git push -u origin feat/<descrizione>
gh pr create --base dev

# 4. Dopo il merge: via worktree e branch, dalla cartella principale
cd ../../..
git worktree remove .claude/worktrees/<descrizione>
git branch -d feat/<descrizione>
git push origin --delete feat/<descrizione>

Insidie

  • --no-track è voluto. Senza, il branch traccia origin/dev e un git push senza argomenti prova a spingere su dev. Il primo push si fa sempre con -u origin <branch>.
  • Il nome della cartella ripete la descrizione del branch, così git worktree list dice subito chi lavora su cosa.
  • Submodule noeva-etl-ui: nel worktree è vuoto. Si popola con git submodule update --init noeva-etl-ui solo se l'attività tocca la UI.
  • Lo stash è condiviso fra tutti i worktree: per mettere da parte lavoro si fa un commit WIP sul proprio branch, così niente finisce nello stash di un'altra sessione.
  • Gitdir fuori dalla cartella. noeva-etl è un submodule di noeva-server: la sua gitdir è ../.git/modules/noeva-etl. git worktree add, fetch e commit scrivono lì, quindi un sandbox che limita le scritture alla cartella di lavoro li fa fallire con Operation not permitted.

Commit (Conventional Commits)

Formato: <tipo>(<scope>): <descrizione>

feat(langfuse-sessions): aggiungi conteggio environment distinti nel fatto
fix(core): correggi conteggio extracted in modalità streaming
docs(adr): registra scelta di Zod per i contratti
test(postgres): copri l'upsert idempotente del sink

Regole:

  • Un commit = un cambiamento coerente. Codice + test + doc dello stesso cambiamento stanno insieme.
  • Messaggio all'imperativo, in italiano, conciso. Il perché va nel corpo se non ovvio.

Pull Request

  • Compila il template PR: cosa, perché, come testato.
  • La PR deve passare la CI (typecheck + lint + format + test + coverage). PR rossa non si fonde.
  • Almeno una review approvata. Per le pipeline dati, eseguire /etl-review prima di richiedere review.
  • PR piccole e focalizzate: più facili da rivedere, più sicure da rilasciare.

Definition of Done prima del merge

Vedi CLAUDE.md §5. In sintesi: check verde, test sul nuovo comportamento, doc allineata, idempotenza verificata, nessun segreto.

Noeva è un marchio registrato di 4D S.R.L.