Git Workflow · git:20261007.7682d9b · 2026-10-07 · sha256 9b52d55653c17df6
Git Workflow git:20261007.7682d9bA
Immutable. This exact content never changes and is served at /api/v1/blob/9b52d55653c17df6.
--- name: Git Workflow description: > Trunk-based git workflow for NXTG-Forge — branching strategy, commit conventions, PR practices, rebase/conflict resolution, and how the plugin's own hooks guard git operations. Use when creating a feature branch, writing a commit message or PR, rebasing onto main, resolving merge conflicts, choosing a merge strategy, recovering from a bad commit/reset/detached HEAD, or when a git push is blocked by a security hook. when_to_use: > "how do I branch", "commit message format", "open a PR", "rebase onto main", "fix merge conflict", "squash vs rebase merge", "undo my last commit", "force push", "my push got blocked", "recover a deleted branch", "detached HEAD", "cherry-pick". allowed-tools: Bash(git *), Bash(gh *) --- # Git Workflow and Branching Strategy NXTG-Forge uses **trunk-based development**: `main` stays always-deployable, work happens on short-lived feature branches, and changes land via squash-merged PRs. This SKILL.md is the lean operating guide; deep tables (commit/PR conventions, recovery recipes) live in the linked reference files. ## Branch strategy - **`main`** — always deployable, protected, requires PR + passing CI. Single source of truth. - **Feature branches** — short-lived (1–3 days), single-purpose, named `type/description`: `feat/user-authentication`, `fix/login-validation-bug`, `refactor/state-migration`, `docs/api-guide`, `chore/dep-bump`. - **No long-lived branches** — no `develop`, no `release/*`, no `hotfix/*`. Fix directly from `main` on a `fix/*` branch. (Reversing this needs an ADR.) ## The core loop ```bash # 1. Branch off fresh main git checkout main && git pull origin main git checkout -b feat/user-authentication # 2. Work → stage EXPLICIT paths (never `git add -A` / `git add .`) → commit git add src/auth/ tests/auth.test.mjs git commit -m "feat: add JWT auth middleware" # 3. Stay current — rebase, don't merge main in git fetch origin && git rebase origin/main # 4. Push (first push sets upstream) git push -u origin feat/user-authentication # later pushes: git push git push --force-with-lease # ONLY after a rebase, never plain --force # 5. Open PR gh pr create --title "feat: add user authentication" --body "$(cat <<'EOF' ## Summary - JWT-based authentication middleware + login/logout endpoints ## Test Plan - [x] Unit tests for token validation - [x] Integration test for the auth flow EOF )" # 6. After approval + green CI gh pr merge --squash --delete-branch ``` Stage explicit paths, not `git add -A` — it sweeps in unrelated dirty files and secrets. Rebase (not merge-from-main) keeps history linear. Push new work with `-u`; after a rebase that rewrote your branch, reconcile the remote with `--force-with-lease` (safe: it refuses if someone else pushed). See [reference/commit-and-pr.md](reference/commit-and-pr.md) for the full commit-type list, PR template, size guidance, and merge-strategy trade-offs. ## Merge strategy **Squash and merge is the default** — collapses WIP commits into one clean commit on `main`, so the whole feature reverts as a unit. Use **rebase and merge** only when the branch's commits are already well-curated and worth preserving individually. **Never** create a merge commit (`git merge feat/x` into main) — it clutters history and complicates `git bisect`. ## When something goes wrong The high-frequency recoveries — undo last commit, committed to main by accident, amend a message, split a commit, cherry-pick, detached HEAD, recover a deleted branch, purge a large file — are in [reference/scenarios-and-recovery.md](reference/scenarios-and-recovery.md). Quick reflexes: - **Undo last commit, keep changes:** `git reset --soft HEAD~1` - **Already pushed?** Don't rewrite public history — `git revert <sha>` instead. - **Rebase gone bad:** `git rebase --abort` returns you to the pre-rebase state. ## Gotchas Real, non-obvious traps specific to this repo and the Claude Code environment: - **The plugin's own security hook BLOCKS force-push to main.** `hooks/scripts/security-command-guard.sh` (PreToolUse on Bash) exits 2 — denying the tool call — on any `git push --force … main`/`master`. It also blocks `git reset --hard origin/*`. Push force-updates to a *branch* with `--force-with-lease`; stash or `git reset --soft` instead of `--hard origin/…`. - **A quiet working tree is NOT a clean one.** The `pre-task.sh` uncommitted-changes advisory fires only at **>10 dirty files OR a tracked file modified >30 min ago** — small, fresh changes are treated as sync noise and stay silent. Absence of the warning ≠ nothing to commit; run `git status` yourself. - **Interactive rebase/add don't work here.** The Claude Code Bash environment does not support `-i` (`git rebase -i`, `git add -i`). Use non-interactive equivalents: `git reset HEAD~N` + re-commit to split, `git commit --amend` for the tip, explicit `git rebase --onto`. - **Don't hardcode a `Co-Authored-By` trailer.** Commit trailers are a per-repo convention, not a git requirement — follow the target repo's canon (each NXTG repo defines its own). Never paste a boilerplate co-author line into a repo that doesn't use it. - **Stop-hook nudges are advisory, not gates.** `post-task.sh` (checkpoint/smaller-commit hints) and `smoke-test-reminder.sh` (test-after-server-change reminder) run on Stop and never block a commit or push — they're prompts, so acting on them is on you. - **`--force-with-lease`, never bare `--force`.** Lease refuses the push if the remote moved since your last fetch, catching the case where a teammate pushed to your branch. Bare `--force` silently clobbers it. ## Forge integration Git behavior is shaped by the plugin's Claude Code lifecycle hooks (`hooks/scripts/`), NOT by classic `.git/hooks` pre-commit scripts: | Hook (trigger) | Git-relevant effect | |---|---| | `security-command-guard.sh` (PreToolUse: Bash) | **Blocks** force-push to main/master and `git reset --hard origin/*` (exit 2 = deny) | | `pre-task.sh` (UserPromptSubmit) | Advisory: warns of uncommitted changes past the >10-file / >30-min threshold; posts branch + dirty count to session tracking | | `post-task.sh` (Stop) | Advisory: suggests `/nxtg-forge:checkpoint` after major work, hints at smaller commits | | `smoke-test-reminder.sh` (Stop) | Advisory: reminds you to smoke-test after editing server/test files | `/nxtg-forge:checkpoint` and `/nxtg-forge:restore` provide governance-state snapshots that complement git — use them at milestone boundaries, not as a replacement for commits. ## Additional resources - [reference/commit-and-pr.md](reference/commit-and-pr.md) — commit message format + type glossary, good/poor examples, commit-frequency rules, PR title/description template, PR size guidance, review process, and the squash-vs-rebase-vs-merge-commit trade-off in full. - [reference/scenarios-and-recovery.md](reference/scenarios-and-recovery.md) — conflict resolution walkthrough, the five common scenarios (update branch, accidental main commit, amend message, split commit, cherry-pick), troubleshooting (detached HEAD, deleted branch, large files, undo commit), recommended `git config`, and the essential-command quick reference.