Skip to content

fix: improve worktree sync reliability for refresh operations#361

Open
whitmo wants to merge 1 commit intodlorenc:mainfrom
whitmo:work/swift-owl
Open

fix: improve worktree sync reliability for refresh operations#361
whitmo wants to merge 1 commit intodlorenc:mainfrom
whitmo:work/swift-owl

Conversation

@whitmo
Copy link
Copy Markdown

@whitmo whitmo commented Mar 3, 2026

Summary

P0 Roadmap item: Worktree sync — Keep agent worktrees in sync with main as PRs merge.

Audited internal/worktree/ and the daemon refresh path, found and fixed several issues that could cause worktrees to drift out of sync or be left in broken states:

  • Fix relative gitdir path resolution — Both GetWorktreeState() and RefreshWorktree() extracted gitdir from the .git file but didn't resolve relative paths to absolute. This caused os.Stat() checks for rebase-merge/rebase-apply/MERGE_HEAD to silently fail, potentially allowing refresh attempts on worktrees in mid-rebase or mid-merge state. Extracted a shared resolveGitDir() helper.

  • Fix rebase abort error handling — When rebase conflicts occurred, git rebase --abort was called but its error was silently discarded. If abort failed, the code would then attempt git stash pop on a dirty worktree, potentially corrupting state. Now explicitly checks abort result and returns early if abort fails.

  • Detect stash pop conflicts — After a successful rebase, if git stash pop failed due to conflicts, HasConflicts and ConflictFiles were not set, leaving the agent with an unclear error message and no conflict file list. Now checks for conflicts on stash pop failure.

  • Eliminate double fetch in daemon path — The daemon's refreshWorktrees() fetched once per repo, then each RefreshWorktree() call fetched again internally. Added RefreshWorktreePreFetched() variant that skips the fetch, used by the daemon to avoid redundant network calls.

Test plan

  • New TestRefreshWorktree_RebaseConflict — verifies conflict detection, abort, and clean worktree state after conflict
  • New TestRefreshWorktreePreFetched — verifies pre-fetched variant works correctly
  • New TestResolveGitDir — verifies gitdir resolution for both worktrees and regular repos
  • Updated existing tests to use resolveGitDir() helper
  • All 48 worktree tests pass
  • Full test suite passes (go test ./...)

Opportunities noted (not implemented)

  • Workspace/supervisor agent types are not refreshed by the daemon loop (only workers) — may want to extend
  • CommitsRebased count silently ignores rev-list errors — informational only, not critical

🤖 Generated with Claude Code

Fix several issues in the worktree refresh path that could cause
worktrees to drift out of sync or be left in broken states:

- Extract resolveGitDir() helper that properly resolves relative gitdir
  paths to absolute, fixing silent failures in mid-rebase/merge detection
- Handle rebase --abort failures explicitly instead of silently ignoring
- Detect conflicts from stash pop after successful rebase
- Add RefreshWorktreePreFetched() to eliminate redundant fetch when
  daemon has already fetched once per repo
- Add tests for rebase conflict handling, pre-fetched refresh, and
  gitdir resolution

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@whitmo
Copy link
Copy Markdown
Author

whitmo commented Mar 7, 2026

Triage Review

Priority: P0 (Worktree sync - roadmap item)
Build: Pass
Tests: Pass (new tests: TestRefreshWorktree_RebaseConflict, helper refactoring)
Merge conflicts: None - merges cleanly with main and all other open PRs
Roadmap alignment: Directly addresses P0 "Worktree sync" item

Changes:

  • Uses RefreshWorktreePreFetched in daemon refresh loop (avoids redundant fetches)
  • Extracts resolveGitDir helper to reduce test code duplication
  • Adds conflict detection and clean abort tests

Recommendation: Safe to merge anytime - no conflicts with any other PR.

@whitmo
Copy link
Copy Markdown
Author

whitmo commented Mar 12, 2026

Local CI Verification (2026-03-12)

Check Result
go build PASS
go vet PASS
go test ./... PASS (all packages)

CI Status: No GitHub Actions checks are running — this is expected for first-time fork PRs. GitHub requires a maintainer to approve workflow runs for PRs from forks.

Branch is rebased on upstream/main (0 commits behind). Ready for maintainer review and CI approval.

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