Skip to content

refuse to run when repo root is inside .worktrees - #160

Merged
yourconscience merged 3 commits into
mainfrom
fix/refuse-worktree-root
Sep 6, 2026
Merged

refuse to run when repo root is inside .worktrees#160
yourconscience merged 3 commits into
mainfrom
fix/refuse-worktree-root

Conversation

@yourconscience

@yourconscience yourconscience commented Sep 6, 2026

Copy link
Copy Markdown
Owner

Summary by Sourcery

Refuse setup and configuration loading when the repository root is a linked Git worktree.

Bug Fixes:

  • Prevent commands from running against linked Git worktrees, avoiding dangling managed links after worktree removal.

Enhancements:

  • Detect worktree roots through both Git metadata and the project’s .worktrees directory convention, including symlinked paths.

Tests:

  • Add coverage for canonical checkout acceptance, linked worktree rejection, conventional worktree paths, and symlink aliases.

@sourcery-ai

sourcery-ai Bot commented Sep 6, 2026

Copy link
Copy Markdown

Reviewer's Guide

The PR prevents the command from running against Git worktree checkouts, where sync-created absolute links would become dangling after worktree removal. It validates the resolved repository root early in context loading and adds tests covering direct and symlinked worktree paths.

Flow diagram for rejecting Git worktree repository roots

flowchart TD
    A[loadContext] --> B[resolve repository root]
    B --> C[refuseWorktreeRoot]
    C -->|root contains .worktrees| D[Return error]
    C -->|canonical checkout| E[loadConfig]
    D --> F[Command stops before sync]
Loading

File-Level Changes

Change Details Files
Reject repository roots located under a .worktrees path before loading repository configuration.
  • Resolve symlink aliases before inspecting path components.
  • Return an actionable error explaining that only the canonical checkout is supported.
  • Invoke the validation during context loading before config processing.
cmd/dotagents/config.go
Add coverage for canonical, worktree, and symlinked worktree roots.
  • Verify ordinary temporary roots remain accepted.
  • Verify nested .worktrees roots are rejected.
  • Verify a symlink alias to a worktree is also rejected and errors mention the canonical checkout.
cmd/dotagents/config_worktree_test.go

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Sep 6, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: 94ebb577-d793-4e7c-9ce1-d4b9c0b05865


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="cmd/dotagents/config.go" line_range="24-26" />
<code_context>
 		return "", "", config{}, nil, err
 	}
 	repoRoot := filepath.Dir(configPath)
+	if err := refuseWorktreeRoot(repoRoot); err != nil {
+		return "", "", config{}, nil, err
+	}

 	cfg, err := loadConfig(repoRoot, home, configPath)
</code_context>
<issue_to_address>
**issue (broader_impact):** The new guard is only applied by `loadContext`, so `setup` still performs worktree mutations before its final `runSync` call reaches the guard: it can apply memory-tier changes, import native content, write `dotagents.yaml`, create hook executables, and patch agent configuration before returning the refusal error.

**Triggers:** When `setup` is run with its config under `.worktrees/`.

**Suggested fix:** Call `refuseWorktreeRoot(repoRoot)` immediately after `runSetup` resolves `repoRoot`, before any setup mutation; audit other command paths that resolve repository roots without `loadContext`.
</issue_to_address>

### Comment 2
<location path="cmd/dotagents/config.go" line_range="373-375" />
<code_context>
+	if real, err := filepath.EvalSymlinks(repoRoot); err == nil {
+		resolved = real
+	}
+	for _, seg := range strings.Split(filepath.ToSlash(resolved), "/") {
+		if seg == ".worktrees" {
+			return fmt.Errorf("refusing to run with repo root %s: it lives inside a git worktree (.worktrees/); materialized links would dangle when the worktree is removed — run from the canonical checkout", repoRoot)
+		}
+	}
</code_context>
<issue_to_address>
**issue (bug_risk):** The function refuses any path containing a segment named `.worktrees`, regardless of whether that directory is a Git worktree container. A valid canonical checkout located at a path such as `/srv/.worktrees/project` is rejected even when `.worktrees` is an ordinary directory name.

**Triggers:** When a canonical repository is stored beneath a directory literally named `.worktrees`.

**Suggested fix:** Determine whether the root is actually a linked Git worktree, or restrict the check to the repository's intended worktree layout instead of rejecting every matching path segment.
</issue_to_address>

Sourcery assessment

Approval pending. 2 findings to address first.

Blocking findings: cmd/dotagents/config.go:26, cmd/dotagents/config.go:375


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread cmd/dotagents/config.go
Comment thread cmd/dotagents/config.go Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cbb1be90c9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread cmd/dotagents/config.go Outdated
Comment thread cmd/dotagents/config.go

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0694396191

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread cmd/dotagents/config.go
Comment on lines +381 to +382
if fi, err := os.Stat(filepath.Join(resolved, ".git")); err == nil && fi.Mode().IsRegular() {
return refuse()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Check linked-worktree metadata above nested config roots

When an explicit config is in a subdirectory of an arbitrarily named linked worktree (for example, --config /tmp/agents-test/config/dotagents.yaml), the linked worktree's .git file is at /tmp/agents-test/.git, but this check probes only /tmp/agents-test/config/.git; because the path also lacks a .worktrees segment, the guard permits sync and recreates the dangling-link failure it is intended to prevent. Walk ancestors or query Git for the resolved root rather than checking only the config directory.

AGENTS.md reference: AGENTS.md:L5-L9

Useful? React with 👍 / 👎.

@yourconscience
yourconscience merged commit b27116e into main Sep 6, 2026
6 checks passed
@yourconscience
yourconscience deleted the fix/refuse-worktree-root branch September 6, 2026 09:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant