Skip to content

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

Open
IBondarenko-iwg wants to merge 2 commits into
andresharpe:mainfrom
IBondarenko-iwg:fix/570-orphan-worktree-unrelated-history
Open

fix(worktree): classify orphan unrelated-history merge conflicts (#570)#578
IBondarenko-iwg wants to merge 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Inbox

Development

Successfully merging this pull request may close these issues.

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

2 participants