JSON `--status-after` omits per-commit file lists (works in human mode, not JSON)
Summary
--status-after --json never includes per-commit file lists ("changes" is always null), even though the equivalent human-readable --status-after output does include them. This looks like an asymmetry between the two branches of run_status_after() rather than intended behavior.
Repro
but branch new feat-a
echo one > a.txt
FID=$(but diff --json | jq -r '.changes[0].id')
but commit "$FID" -m first -b feat-a --status-after --json | jq '.status.stacks[0].branches[0].commits[0].changes'
# -> null
but status -f --json | jq '.stacks[0].branches[0].commits[0].changes'
# -> [{"cliId": "...", "filePath": "a.txt", "changeType": "modified"}]Same workspace, same commit, immediately after — -f-style file detail exists and is queryable, just not through --status-after's JSON path.
Where it comes from
In crates/but/src/lib.rs, run_status_after():
if out.is_json() {
let status_result = command::legacy::status::worktree(
ctx, out,
StatusFlags::all_false(), // show_files: FilesStatusFlag::None
StatusRenderMode::Oneshot,
);
// combined = {"result": mutation_json, "status": status_json}
} else {
command::legacy::status::worktree(
ctx, out,
StatusFlags {
show_files: FilesStatusFlag::All, // human path asks for files
verbose: true,
hint: true,
..StatusFlags::all_false()
},
StatusRenderMode::Oneshot,
)
}The human-mode branch explicitly requests FilesStatusFlag::All; the JSON-mode branch calls StatusFlags::all_false(), which sets show_files: FilesStatusFlag::None. That's the entire reason JSON output loses per-commit file detail — there's no flag on commit/amend/move/squash/uncommit etc. to opt back in.
Why it matters
--status-after is documented as folding a mutation and its resulting workspace status into a single call, avoiding a separate but status -f --json round trip. For any tool that renders per-commit file lists (e.g. a TUI showing which files are in a commit), the JSON path currently can't be used for that purpose at all — every mutation would need the extra but status -f --json call anyway, defeating the point of --status-after.
Expected
JSON-mode --status-after includes file details the same way the human-mode path does — either always (matching human mode), or behind a flag consistent with but status -f.
Environment
but 0.22.3(also present as far back as0.22.1, where--status-afterwas introduced)- macOS
Source: gitbutlerapp/gitbutler