From d2a2ea92718d4b2c2ee62e59937a76f82c63c654 Mon Sep 17 00:00:00 2001 From: Matthew Vaught <8752859+MTVaught@users.noreply.github.com> Date: Sun, 20 Sep 2026 11:58:59 -0500 Subject: [PATCH] fix(web): offer unstage for partially staged files in the filtered diff views --- apps/web/src/components/DiffPanel.tsx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/apps/web/src/components/DiffPanel.tsx b/apps/web/src/components/DiffPanel.tsx index bd75adfad87b..d120907f986b 100644 --- a/apps/web/src/components/DiffPanel.tsx +++ b/apps/web/src/components/DiffPanel.tsx @@ -791,15 +791,16 @@ export default function DiffPanel({ workingTreeFilter, ], ); - // The filtered views already say which way a file can go; the unfiltered view asks the - // index, and a partially staged file can go either way. + // A file can be staged while it has edits outside the index and unstaged while it has + // entries in it, so a partially staged file offers both in every view. The filtered views + // imply one direction even before the index state has arrived. const stagingActionsFor = useCallback( (filePath: string): ReadonlyArray<"stage" | "unstage"> => { - if (workingTreeFilter !== "all") - return workingTreeFilter === "staged" ? ["unstage"] : ["stage"]; const staging = fileStagingByPath.get(filePath); - if (!staging?.staged) return ["stage"]; - return staging.unstaged ? ["stage", "unstage"] : ["unstage"]; + const canStage = + workingTreeFilter === "unstaged" || staging === undefined || staging.unstaged; + const canUnstage = workingTreeFilter === "staged" || staging?.staged === true; + return [...(canStage ? ["stage" as const] : []), ...(canUnstage ? ["unstage" as const] : [])]; }, [fileStagingByPath, workingTreeFilter], );