fix(workflow): detect nested git worktree in new-project bootstrap (#3491)
The `has_git` boolean returned by `init new-project` and `init ingest-docs` was derived from a shallow `pathExists(cwd, '.git')` check, so a subdirectory of an existing repo reported `has_git: false`. The workflow then ran `git init`, creating a nested `.git` inside the outer worktree and silently diverting subsequent `gsd-sdk commit` calls into the nested repo. Replace the shallow check with `git rev-parse --is-inside-work-tree` semantics in both CJS (`get-shit-done/bin/lib/init.cjs`) and TS (`sdk/src/query/init.ts`, `sdk/src/query/init-complex.ts`) handlers via a new shared `gitWorktreeInfoInternal` helper, and expose `git_worktree_root` + `in_nested_subdir` so the workflows can refuse `git init` inside an existing worktree and warn that planning files will track to the outer repo. Regression test: `tests/bug-3491-nested-git-worktree.test.cjs`. Fixes #3491 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -56,7 +56,7 @@ INIT=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" init ingest-docs)
|
||||
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
||||
```
|
||||
|
||||
Parse `project_exists`, `planning_exists`, `has_git`, `project_path` from INIT.
|
||||
Parse `project_exists`, `planning_exists`, `has_git`, `git_worktree_root`, `in_nested_subdir`, `project_path` from INIT.
|
||||
|
||||
**Auto-detect MODE** if not set:
|
||||
- `planning_exists: true` → `MODE=merge`
|
||||
@@ -64,7 +64,12 @@ Parse `project_exists`, `planning_exists`, `has_git`, `project_path` from INIT.
|
||||
|
||||
If user passed `--mode new` but `.planning/` already exists: display warning and require explicit confirm via `AskUserQuestion` (approve-revise-abort from `references/gate-prompts.md`) before overwriting.
|
||||
|
||||
If `has_git: false` and `MODE=new`: initialize git:
|
||||
Git initialisation (Bug #3491 — never create a nested `.git` inside an existing worktree):
|
||||
|
||||
- If `has_git: true` and `in_nested_subdir: true`: do NOT run `git init`. Surface a warning that planning files will be tracked by the outer repo at `git_worktree_root`.
|
||||
- If `has_git: true` and `in_nested_subdir: false`: already at a worktree root, skip `git init`.
|
||||
- If `has_git: false` and `MODE=new`: initialize git:
|
||||
|
||||
```bash
|
||||
git init
|
||||
```
|
||||
|
||||
@@ -64,7 +64,7 @@ AGENT_SKILLS_SYNTHESIZER=$(gsd-sdk query agent-skills gsd-research-synthesizer)
|
||||
AGENT_SKILLS_ROADMAPPER=$(gsd-sdk query agent-skills gsd-roadmapper)
|
||||
```
|
||||
|
||||
Parse JSON for: `researcher_model`, `synthesizer_model`, `roadmapper_model`, `commit_docs`, `project_exists`, `has_codebase_map`, `planning_exists`, `has_existing_code`, `has_package_file`, `is_brownfield`, `needs_codebase_map`, `has_git`, `project_path`, `agents_installed`, `missing_agents`, `agent_runtime`, `agents_dir`, `required_agents`, `required_agents_installed`, `missing_required_agents`, `agent_skill_payloads_available`, `agent_skill_payload_agents`.
|
||||
Parse JSON for: `researcher_model`, `synthesizer_model`, `roadmapper_model`, `commit_docs`, `project_exists`, `has_codebase_map`, `planning_exists`, `has_existing_code`, `has_package_file`, `is_brownfield`, `needs_codebase_map`, `has_git`, `git_worktree_root`, `in_nested_subdir`, `project_path`, `agents_installed`, `missing_agents`, `agent_runtime`, `agents_dir`, `required_agents`, `required_agents_installed`, `missing_required_agents`, `agent_skill_payloads_available`, `agent_skill_payload_agents`.
|
||||
|
||||
**If `agents_installed` is false:** Display a warning before proceeding:
|
||||
```text
|
||||
@@ -117,11 +117,11 @@ All subsequent references to the project instruction file use `$INSTRUCTION_FILE
|
||||
|
||||
**If `project_exists` is true:** Error — project already initialized. Use `/gsd:progress`.
|
||||
|
||||
**If `has_git` is false:** Initialize git:
|
||||
**Git init (#3491 — never nest `.git` inside an existing worktree):**
|
||||
|
||||
```bash
|
||||
git init
|
||||
```
|
||||
- If `has_git` true and `in_nested_subdir` true: skip `git init`; warn `⚠ Initializing inside existing worktree (${git_worktree_root}); planning files will track to outer repo.`
|
||||
- If `has_git` true and `in_nested_subdir` false: skip `git init` (already at worktree root).
|
||||
- If `has_git` false: `git init`.
|
||||
|
||||
## 2. Brownfield Offer
|
||||
|
||||
|
||||
Reference in New Issue
Block a user