Skip to content

fix(worktree): fetch target branch before branching on stale local refs - #182

Merged
getappz merged 2 commits into
masterfrom
task/42
Jul 14, 2026
Merged

fix(worktree): fetch target branch before branching on stale local refs#182
getappz merged 2 commits into
masterfrom
task/42

Conversation

@getappz

@getappz getappz commented Jul 14, 2026

Copy link
Copy Markdown
Owner

Fixes item #42: create_worktree branched new task worktrees off whatever target_branch pointed to LOCALLY in repo_root — there was no git fetch anywhere in worktree.rs. If the main checkout hadn't synced recent merges, every new claim silently started from stale code, risking wasted work and conflicts when the resulting PR opens. Concretely hit earlier this session — had to manually git pull --ff-only origin master after merging PRs #178/#179 because the local checkout had drifted.

Fix

Before git worktree add, create_worktree now runs git fetch origin <target_branch> (scoped to just that branch) and verifies origin/<target_branch> resolves; if so, branches off that instead of the bare local ref. Soft-fails to today's behavior (branch off the local ref as-is) when there's no origin remote, we're offline, or the branch was never pushed (common for a parent item's task/N branch) — never blocks a claim on network reachability, matching every other soft-fail in this file. Skipped entirely on the already_isolated_for fast-path (re-claiming an existing worktree — nothing to sync).

Test

New test: clones a remote repo, lands a commit on the remote after the clone (so the local clone's own master and origin/master both go stale), then asserts the resulting worktree is based on the fresh remote commit, not the stale local one.

432/432 tests pass (431 + 1 new), clippy clean (-D warnings -A unsafe_code -A clippy::pedantic), fmt clean.

Summary by CodeRabbit

  • Bug Fixes
    • Worktrees now use the latest commit from the target branch when remote updates are available.
    • If remote fetching or verification fails, worktrees fall back to the local target branch.
  • Tests
    • Added a regression test ensuring worktree HEAD matches the remote’s latest commit rather than a stale local ref.

…orktrees on stale local refs

create_worktree branched new task worktrees off whatever target_branch
pointed to LOCALLY, with no git fetch anywhere in worktree.rs. If the
main checkout hadn't synced recent merges, every new claim silently
started from stale code.

Now fetches origin/<target_branch> first and branches off that when
reachable; soft-fails to the old local-ref behavior when there's no
remote, we're offline, or the branch was never pushed (never blocks a
claim on network reachability). New test clones a remote, lands a
commit on it after the clone (so the local clone's own refs go stale),
and asserts the resulting worktree is based on the fresh remote commit
rather than the stale local one.
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 56e2747b-9f45-48d7-8deb-085add84fbe1

📥 Commits

Reviewing files that changed from the base of the PR and between ecc33e3 and a911abe.

📒 Files selected for processing (1)
  • src/worktree.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/worktree.rs

📝 Walkthrough

Walkthrough

Changes

The worktree branch start point is fetched from and verified against the remote target branch when available, with fallback to the local target branch. A regression test validates remote-only commits are included when the local clone is stale.

Worktree branch source

Layer / File(s) Summary
Remote start-point selection
src/worktree.rs
create_worktree fetches and verifies the remote target branch, falls back to the local branch on failure, and uses the selected start point for git worktree add.
Stale-clone regression coverage
src/worktree.rs
The test advances the remote after cloning and verifies the created worktree matches the remote’s latest commit.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly states the main worktree change and the stale-local-ref problem it fixes.
Description check ✅ Passed The description covers the summary and test results, though it does not follow the template sections exactly.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch task/42

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

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/worktree.rs`:
- Around line 166-183: The fetch in the start_point selection must fail fast
instead of blocking on unreachable remotes or credential prompts. Update the
fetch invocation to use the existing timeout helper, or ensure it runs with
GIT_TERMINAL_PROMPT=0, while preserving the current soft-fallback to
target_branch when fetching or remote-ref verification fails.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: bc2e204b-56fe-4bdd-8075-bc22047b3740

📥 Commits

Reviewing files that changed from the base of the PR and between 23ec32e and ecc33e3.

📒 Files selected for processing (1)
  • src/worktree.rs

Comment thread src/worktree.rs
Routed through run_output_timeout (already used for push/PR) instead of
the plain blocking run_git_in — an unreachable remote or a credential
prompt must not be able to hang a claim indefinitely.
@getappz
getappz enabled auto-merge (squash) July 14, 2026 10:00

@getappz getappz left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

merge

@getappz
getappz disabled auto-merge July 14, 2026 10:03
@getappz
getappz enabled auto-merge (squash) July 14, 2026 10:04
@getappz
getappz merged commit 184a560 into master Jul 14, 2026
14 checks passed
@getappz
getappz deleted the task/42 branch July 14, 2026 10:24
getappz added a commit that referenced this pull request Jul 14, 2026
* feat(mcp): consolidate 6 tools into action-dispatch pattern

- Merge skill/search+load, gateway/search+execute, claim/5-actions,
  review/5-actions, artifact/6-actions, memory/6-actions into one
  consolidated #[tool(...)] method each with action dispatch
- Reconcile with #182 (fetch target branch before branching) and
  #183 (deferred claim release, mark_completed split)

* fix(mcp): finish artifact/skill/gateway test migration, fix consolidation regressions

CI was red: ~35 test call sites in mcp_server.rs still called the old
per-action methods (artifact_publish/get/list/delete/diff/search,
skill_search/load, gateway_search/execute) that this consolidation removed.
Migrated them all to the unified action-dispatch tools.

Also fixes real bugs the consolidation introduced along the way:
- artifact()'s get/diff/search arms called store methods with a signature
  they no longer have (get takes no version, diff's to is a required u32,
  and there's no store.search at all) — restored the pre-consolidation
  logic (get_version fallback, latest-version resolution, inline
  list+filter+snippet search).
- review()'s "consensus" arm called crate::review::consensus with the wrong
  arguments entirely (a Connection/ids instead of findings+changed-lines);
  now loads findings and computes the diff/changed-lines first, matching
  "record"'s already-correct pattern. Also dropped record's dead base/head
  locals that shadowed the actual req.base/req.head usage.
- memory()'s "curate" arm passed the outer "curate" action into
  CurateInput.action, so update/delete/pin/unpin could never be reached;
  added a dedicated curate_action field.
- mark_completed's ownership check and completion write weren't in the
  same transaction, leaving a window for a concurrent release+claim by a
  different owner to complete the item out from under its new owner.

Also ran cargo fmt across the branch (had never been formatted).

* fix(fmt): collapse tool() signature onto one line per rustfmt
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