format-patch: make format.noprefix a boolean

The config `format.noprefix` was added in 8d5213de (format-patch: add format.noprefix option, 2023-03-09) to support no-prefix on paths. That was immediately after making git-format-patch(1) not respect `diff.noprefix`.[1] The intent was to mirror `diff.noprefix`. But this config was unintentionally[2] implemented by enabling no-prefix if any kind of value is set. † 1: c169af8f (format-patch: do not respect diff.noprefix, 2023-03-09) † 2: https://lore.kernel.org/all/20260211073553.GA1867915@coredump.intra.peff.net/ Let’s indeed mirror `diff.noprefix` by treating it as a boolean. This is a breaking change. And as far as breaking changes go it is pretty benign: • The documentation claims that this config is equivalent to `diff.noprefix`; this is just a bug fix if the documentation is what defines the application interface • Only users with non-boolean values will run into problems when we try to parse it as a boolean. But what would (1) make them suspect they could do that in the first place, and (2) have motivated them to do it? • Users who have set this to `false` and expect that to mean *enable format.noprefix* (current behavior) will now have the opposite experience. Which is not a reasonable setup. Let’s only offer a breaking change fig leaf by advising about the previous behavior before dying. Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Kristoffer Haugsbakk committed Feb 24, 2026 at 00:30 UTC 04657ac02928bbd41fb4352db1bb0ba57488bad6
2 files changed +29 -1
builtin/log.c
+13 -1
@@ -40,6 +40,7 @@
40 #include "mailmap.h"
41 #include "progress.h"
42 #include "commit-slab.h"
43 +#include "advice.h"
44
45 #include "commit-reach.h"
46 #include "range-diff.h"
@@ -1096,7 +1097,18 @@ static int git_format_config(const char *var, const char *value,
1097 return 0;
1098 }
1099 if (!strcmp(var, "format.noprefix")) {
1099 - format_no_prefix = 1;
1100 + format_no_prefix = git_parse_maybe_bool(value);
1101 + if (format_no_prefix < 0) {
1102 + int status = die_message(
1103 + _("bad boolean config value '%s' for '%s'"),
1104 + value, var);
1105 + advise(_("'%s' used to accept any value and "
1106 + "treat that as 'true'.\n"
1107 + "Now it only accepts boolean values, "
1108 + "like what '%s' does.\n"),
1109 + var, "diff.noprefix");
1110 + exit(status);
1111 + }
1112 return 0;
1113 }
1114
t/t4014-format-patch.sh
+16
@@ -2541,10 +2541,26 @@ test_expect_success 'format-patch respects format.noprefix' '
2541 grep "^--- blorp" actual
2542 '
2543
2544 +test_expect_success 'format.noprefix=false' '
2545 + git -c format.noprefix=false format-patch -1 --stdout >actual &&
2546 + grep "^--- a/blorp" actual
2547 +'
2548 +
2549 test_expect_success 'format-patch --default-prefix overrides format.noprefix' '
2550 git -c format.noprefix \
2551 format-patch -1 --default-prefix --stdout >actual &&
2552 grep "^--- a/blorp" actual
2553 '
2554
2555 +test_expect_success 'errors on format.noprefix which is not boolean' '
2556 + cat >expect <<-EOF &&
2557 + fatal: bad boolean config value ${SQ}not-a-bool${SQ} for ${SQ}format.noprefix${SQ}
2558 + hint: ${SQ}format.noprefix${SQ} used to accept any value and treat that as ${SQ}true${SQ}.
2559 + hint: Now it only accepts boolean values, like what ${SQ}diff.noprefix${SQ} does.
2560 + EOF
2561 + test_must_fail git -c format.noprefix=not-a-bool \
2562 + format-patch -1 --stdout 2>actual &&
2563 + test_cmp expect actual
2564 +'
2565 +
2566 test_done