From: Jeff King Date: Sat, 03 Jan 2026 11:26:42 GMT Subject: Re: bug report: git status -z doesn't respect status.relativePaths=true Message-ID: <20260103112642.GA2706421@coredump.intra.peff.net> In-Reply-To: On Sat, Jan 03, 2026 at 02:47:36AM -0800, Artur Pyrogovskyi wrote: > According to the man page of git-status: "-z Terminate entries with > NUL, instead of LF." > > However, it ignores status.relativePaths=true and always shows absolute paths. This matches the documented behavior. In --porcelain=v1 mode, we ignore most configuration options (like status.relativePaths). And -z puts us into v1 porcelain mode by default: -z Terminate entries with NUL, instead of LF. This implies the --porcelain=v1 output format if no other format is given. I do think there is at least one bug here, though. I'd expect from that documentation to be able to do: git -c status.relativePaths=true status --short -z and get relative paths. But it doesn't work. The --short output code that handles "-z" ignores the prefix entirely. Something like this would fix it: diff --git a/wt-status.c b/wt-status.c index e12adb26b9..22797371a6 100644 --- a/wt-status.c +++ b/wt-status.c @@ -2005,6 +2005,13 @@ static void wt_shortstatus_unmerged(struct string_list_item *it, } } +static void print_with_nul(struct wt_status *s, const char *fn) +{ + struct strbuf scratch = STRBUF_INIT; + fprintf(s->fp, "%s%c", relative_path(fn, s->prefix, &scratch), 0); + strbuf_release(&scratch); +} + static void wt_shortstatus_status(struct string_list_item *it, struct wt_status *s) { @@ -2020,9 +2027,9 @@ static void wt_shortstatus_status(struct string_list_item *it, fputc(' ', s->fp); fputc(' ', s->fp); if (s->null_termination) { - fprintf(s->fp, "%s%c", it->string, 0); + print_with_nul(s, it->string); if (d->rename_source) - fprintf(s->fp, "%s%c", d->rename_source, 0); + print_with_nul(s, d->rename_source); } else { struct strbuf onebuf = STRBUF_INIT; const char *one; but: 1. it would need similar adjustments to a few other printing functions; and 2. it's not clear to me if we want to change this behavior or keep it as a historical quirk and document it as such. I guess nobody noticed because using "-z" with "--short" is a bit of an odd thing to want to do. There's another oddity, which is this: > Repro steps: > $ mkdir test-repo && cd test-repo && git init . > $ mkdir subdir && touch subdir/test-file.txt && cd subdir && git add > test-file.txt > $ git -c status.relativePaths=true status --porcelain=2 > 1 A. N... 000000 100644 100644 > 0000000000000000000000000000000000000000 > e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 test-file.txt I am surprised to see that the v2 porcelain respects that config option at all. I don't know if that's a bug, or a subtle change from v1. I don't see it mentioned in the documentation. If it isn't a bug, and we expect v2 porcelain to respect the config, then this: > $ git -c status.relativePaths=true status --porcelain=2 -z > 1 A. N... 000000 100644 100644 > 0000000000000000000000000000000000000000 > e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 subdir/test-file.txt% is another bug similar to the --short one. -Peff