fix: use merge-base for diffStat in merger and show files changed on done task cards

The merger was using `git diff HEAD..branch --stat` which includes
artifacts from other tasks when branches fork from older main commits.
Switch to `git diff $(merge-base)..branch --stat` so commit messages
only describe the branch's own changes.

Also surface the "files changed" button on done task cards using
mergeDetails, opening the same ChangedFilesModal with commit-backed
diffs (matching the Changes tab in the task modal).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-04-04 08:33:53 -07:00
parent f882c5aed9
commit d3a3cc71d6
9 changed files with 74 additions and 17 deletions

View File

@@ -1,5 +1,6 @@
import { useEffect, useState, useCallback } from "react";
import { fetchTaskFileDiffs, type TaskFileDiff } from "../api";
import { fetchTaskFileDiffs, fetchCommitDiff, type TaskFileDiff } from "../api";
import { parsePatch } from "../components/CommitDiffTab";
const ACTIVE_COLUMNS = new Set(["in-progress", "in-review"]);
@@ -17,14 +18,19 @@ export function useChangedFiles(
worktree: string | undefined,
column: string,
projectId?: string,
commitSha?: string,
): UseChangedFilesResult {
const [files, setFiles] = useState<TaskFileDiff[]>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [selectedFile, setSelectedFile] = useState<TaskFileDiff | null>(null);
const isDone = column === "done";
useEffect(() => {
if (!taskId || !worktree || !ACTIVE_COLUMNS.has(column)) {
// For active tasks: need worktree
// For done tasks: need commitSha
if (!taskId || (!isDone && (!worktree || !ACTIVE_COLUMNS.has(column))) || (isDone && !commitSha)) {
setFiles([]);
setLoading(false);
setError(null);
@@ -38,7 +44,21 @@ export function useChangedFiles(
setLoading(true);
setError(null);
try {
const result = await fetchTaskFileDiffs(taskId, projectId);
let result: TaskFileDiff[];
if (isDone && commitSha) {
// Done task: fetch from commit history
const data = await fetchCommitDiff(commitSha);
const parsed = parsePatch(data.patch || "");
result = parsed.map((f) => ({
path: f.path,
status: f.status === "unknown" ? "modified" as const : f.status,
diff: f.patch,
oldPath: undefined,
}));
} else {
// Active task: fetch from worktree
result = await fetchTaskFileDiffs(taskId, projectId);
}
if (cancelled) return;
setFiles(result);
setSelectedFile((current) => {
@@ -68,7 +88,7 @@ export function useChangedFiles(
return () => {
cancelled = true;
};
}, [taskId, worktree, column, projectId]);
}, [taskId, worktree, column, projectId, commitSha, isDone]);
const resetSelection = useCallback(() => {
setSelectedFile(null);