Skip to content

fix(worktree): classify orphan unrelated-history merge conflicts (#570) - #578

Merged
carlospedreira merged 2 commits into
andresharpe:mainfrom
IBondarenko-iwg:fix/570-orphan-worktree-unrelated-history
Jul 7, 2026
Merged

fix(worktree): classify orphan unrelated-history merge conflicts (#570)#578
carlospedreira merged 2 commits into
andresharpe:mainfrom
IBondarenko-iwg:fix/570-orphan-worktree-unrelated-history

Conversation

@IBondarenko-iwg

Copy link
Copy Markdown
Contributor

Linked issue

Closes #570
Refs #557

Child PR of the 8-bug epic #557, delivering bug 2. Merging Closes #570; #557 stays open until the last child lands.

Summary of changes

Two task worktrees both cut while the project has no commits are unrelated orphan roots (--orphan is intentional — the base is the user's repo, so no synthetic bootstrap commit). The first task initializes main; a second orphan then has no merge-base, so Apply-TaskBranchPatch falls back to the empty-tree base. When both tasks touched the same file, the git apply --3way add/add conflict was returned as the generic, unrecoverable rebase_conflict. (Different-file orphans already merge cleanly — unchanged.)

  • Dotbot.Worktree.psm1 — flag the empty-tree fallback and classify the resulting conflict as unrelated_history (vs rebase_conflict), with a distinct completion message.
  • Dotbot.Task.psm1 — new unrelated_history pending_question arm: the task predates the first commit and collides with an earlier task on <files>; operator chooses keep task / keep main / merge by hand (advisory labels).
  • Latent bug fixed en route: Complete-TaskWorktree read conflict_files via $mergeResult.PSObject.Properties[...], which is always empty for the hashtable Apply-TaskBranchPatch returns — so conflict file lists were silently dropped for every merge failure (incl. rebase_conflict). Now uses hashtable-safe access.

Future work (deferred, not in this PR): auto-merge non-overlapping same-file orphan edits by rebasing the orphan branch --onto <base> --root (by completion time main holds the earlier task's file → a real 3-way base). Deferred because it's the riskiest merge-path change and its payoff is uncertain for full-rewrite doc collisions (which fall back to this PR's prompt anyway). Revisit only if real runs show frequent auto-resolvable collisions.

Testing notes

tests/Test-Components.ps1 (Layer 2): new end-to-end same-file orphan-collision test (two orphan worktrees write the same file; first merges → initializes main; second → asserts failure_kind = 'unrelated_history' and non-empty conflict_files), a unrelated_history kind-dispatch case, and an updated source-pin for the refactored failure_kind assignment. Regression guard: different-file orphans still merge clean (pre-existing test). Reviewed with /pwsh-review (diff-bug + idioms + history): ship, 0 blockers/majors. PARSE OK.

Checklist

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes task worktree squash-merge behavior when multiple task branches were created while the base branch had no commits (orphan roots with unrelated history). It improves failure classification so operators get a specific, actionable escalation (unrelated_history) instead of a generic rebase_conflict, and it restores lost conflict file reporting due to a hashtable access bug.

Changes:

  • Detect when Apply-TaskBranchPatch falls back to the empty-tree base (no merge-base) and classify resulting add/add conflicts as unrelated_history.
  • Extend merge-failure escalation to include an unrelated_history pending_question template with dedicated guidance/options.
  • Fix Complete-TaskWorktree conflict file extraction to work with hashtable merge results (restoring conflict_files reporting for all merge failures).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
tests/Test-Components.ps1 Adds regression coverage for same-file orphan collision; extends kind→template dispatch tests for unrelated_history.
src/runtime/Modules/Dotbot.Worktree/Dotbot.Worktree.psm1 Tracks empty-tree fallback, returns unrelated_history on conflict, and fixes hashtable-safe conflict_files access + messaging.
src/runtime/Modules/Dotbot.Task/Dotbot.Task.psm1 Adds unrelated_history arm to merge-failure pending_question builder.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/runtime/Modules/Dotbot.Worktree/Dotbot.Worktree.psm1 Outdated
@IBondarenko-iwg

Copy link
Copy Markdown
Contributor Author

@carlospedreira Ready for review.

@carlospedreira carlospedreira left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approved. I reviewed the diff and ran layers 1-3 locally; all passed.

@carlospedreira
carlospedreira merged commit 43253e0 into andresharpe:main Jul 7, 2026
6 checks passed
@github-project-automation github-project-automation Bot moved this from Inbox to Done in Dotbot Product Backlog Jul 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Orphan worktrees break squash-merge (unborn master) (#557 bug 2)

3 participants