From: Pushkar Singh Date: Sat, 03 Jan 2026 11:34:54 GMT Subject: Re: bug report: git status -z doesn't respect status.relativePaths=true Message-ID: In-Reply-To: <20260103112642.GA2706421@coredump.intra.peff.net> Hi Jeff, Thanks for the detailed explanation. That clarifies why `-z` implies `--porcelain=v1` and why `status.relativePaths` gets ignored in that case. I agree that the `--short -z` behavior is surprising. From the documentation, I would also expect `status.relativePaths=true` to be honored there, so ignoring the prefix entirely does look like a real issue rather than just a quirk. The `--porcelain=v2 -z` case is interesting as well. If v2 is intended to respect the configuration, then the inconsistency when using `-z` does seem like a related bug. If it would be useful, I am happy to help investigate further or work on tests once there is consensus on the intended behavior. Thanks, Pushkar On Sat, Jan 3, 2026 at 4:56 PM Jeff King wrote: > > 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 >