feat: squash merge for clean one-commit-per-task history

- git merge --squash replaces git merge --no-ff
- Merge agent prompt updated for squash flow
- Fallback detection uses staged changes instead of MERGE_HEAD
- Abort uses git reset --merge instead of git merge --abort
- Store fallback merge also squashes + commits
This commit is contained in:
Dustin Byrne
2026-03-25 22:02:33 -04:00
parent 005e504565
commit 69ff2f7aa0
2 changed files with 27 additions and 25 deletions

View File

@@ -494,22 +494,26 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
// 2. Merge the branch
try {
execSync(`git merge "${branch}" --no-edit`, {
execSync(`git merge --squash "${branch}"`, {
cwd: this.rootDir,
stdio: "pipe",
});
execSync(`git commit --no-edit -m "feat(${id}): merge ${branch}"`, {
cwd: this.rootDir,
stdio: "pipe",
});
result.merged = true;
} catch (err: any) {
// Merge conflict — abort and report
// Squash conflict — reset and report
try {
execSync("git merge --abort", { cwd: this.rootDir, stdio: "pipe" });
execSync("git reset --merge", { cwd: this.rootDir, stdio: "pipe" });
} catch {
// already clean
}
throw new Error(
`Merge conflict merging '${branch}'. Resolve manually:\n` +
` cd ${this.rootDir}\n` +
` git merge ${branch}\n` +
` git merge --squash ${branch}\n` +
` # resolve conflicts, then: hai task move ${id} done`,
);
}