Skip to content

Commit 15108de

Browse files
committed
Merge branch 'jk/format-patch-ignore-noprefix'
"git format-patch" honors the src/dst prefixes set to nonstandard values with configuration variables like "diff.noprefix", causing receiving end of the patch that expects the standard -p1 format to break. Teach "format-patch" to ignore end-user configuration and always use the standard prefixes. This is a backward compatibility breaking change. * jk/format-patch-ignore-noprefix: rebase: prefer --default-prefix to --{src,dst}-prefix for format-patch format-patch: add format.noprefix option format-patch: do not respect diff.noprefix diff: add --default-prefix option t4013: add tests for diff prefix options diff: factor out src/dst prefix setup
2 parents e25cabb + ab89575 commit 15108de

File tree

8 files changed

+118
-6
lines changed

8 files changed

+118
-6
lines changed

Documentation/config/format.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,10 @@ will only show notes from `refs/notes/bar`.
144144
format.mboxrd::
145145
A boolean value which enables the robust "mboxrd" format when
146146
`--stdout` is in use to escape "^>+From " lines.
147+
148+
format.noprefix::
149+
If set, do not show any source or destination prefix in patches.
150+
This is equivalent to the `diff.noprefix` option used by `git
151+
diff` (but which is not respected by `format-patch`). Note that
152+
by setting this, the receiver of any patches you generate will
153+
have to apply them using the `-p0` option.

Documentation/diff-options.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,11 @@ endif::git-format-patch[]
852852
--no-prefix::
853853
Do not show any source or destination prefix.
854854

855+
--default-prefix::
856+
Use the default source and destination prefixes ("a/" and "b/").
857+
This is usually the default already, but may be used to override
858+
config such as `diff.noprefix`.
859+
855860
--line-prefix=<prefix>::
856861
Prepend an additional prefix to every line of output.
857862

builtin/log.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ static int stdout_mboxrd;
5858
static const char *fmt_patch_subject_prefix = "PATCH";
5959
static int fmt_patch_name_max = FORMAT_PATCH_NAME_MAX_DEFAULT;
6060
static const char *fmt_pretty;
61+
static int format_no_prefix;
6162

6263
static const char * const builtin_log_usage[] = {
6364
N_("git log [<options>] [<revision-range>] [[--] <path>...]"),
@@ -1084,6 +1085,19 @@ static int git_format_config(const char *var, const char *value, void *cb)
10841085
stdout_mboxrd = git_config_bool(var, value);
10851086
return 0;
10861087
}
1088+
if (!strcmp(var, "format.noprefix")) {
1089+
format_no_prefix = 1;
1090+
return 0;
1091+
}
1092+
1093+
/*
1094+
* ignore some porcelain config which would otherwise be parsed by
1095+
* git_diff_ui_config(), via git_log_config(); we can't just avoid
1096+
* diff_ui_config completely, because we do care about some ui options
1097+
* like color.
1098+
*/
1099+
if (!strcmp(var, "diff.noprefix"))
1100+
return 0;
10871101

10881102
return git_log_config(var, value, cb);
10891103
}
@@ -1993,6 +2007,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
19932007
s_r_opt.def = "HEAD";
19942008
s_r_opt.revarg_opt = REVARG_COMMITTISH;
19952009

2010+
if (format_no_prefix)
2011+
diff_set_noprefix(&rev.diffopt);
2012+
19962013
if (default_attach) {
19972014
rev.mime_boundary = default_attach;
19982015
rev.no_inline = 1;

builtin/rebase.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,7 @@ static int run_am(struct rebase_options *opts)
661661
format_patch.git_cmd = 1;
662662
strvec_pushl(&format_patch.args, "format-patch", "-k", "--stdout",
663663
"--full-index", "--cherry-pick", "--right-only",
664-
"--src-prefix=a/", "--dst-prefix=b/", "--no-renames",
664+
"--default-prefix", "--no-renames",
665665
"--no-cover-letter", "--pretty=mboxrd", "--topo-order",
666666
"--no-base", NULL);
667667
if (opts->git_format_patch_opt.len)

diff.c

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3376,6 +3376,17 @@ void diff_set_mnemonic_prefix(struct diff_options *options, const char *a, const
33763376
options->b_prefix = b;
33773377
}
33783378

3379+
void diff_set_noprefix(struct diff_options *options)
3380+
{
3381+
options->a_prefix = options->b_prefix = "";
3382+
}
3383+
3384+
void diff_set_default_prefix(struct diff_options *options)
3385+
{
3386+
options->a_prefix = "a/";
3387+
options->b_prefix = "b/";
3388+
}
3389+
33793390
struct userdiff_driver *get_textconv(struct repository *r,
33803391
struct diff_filespec *one)
33813392
{
@@ -4676,10 +4687,9 @@ void repo_diff_setup(struct repository *r, struct diff_options *options)
46764687
options->flags.ignore_untracked_in_submodules = 1;
46774688

46784689
if (diff_no_prefix) {
4679-
options->a_prefix = options->b_prefix = "";
4690+
diff_set_noprefix(options);
46804691
} else if (!diff_mnemonic_prefix) {
4681-
options->a_prefix = "a/";
4682-
options->b_prefix = "b/";
4692+
diff_set_default_prefix(options);
46834693
}
46844694

46854695
options->color_moved = diff_color_moved_default;
@@ -5263,8 +5273,18 @@ static int diff_opt_no_prefix(const struct option *opt,
52635273

52645274
BUG_ON_OPT_NEG(unset);
52655275
BUG_ON_OPT_ARG(optarg);
5266-
options->a_prefix = "";
5267-
options->b_prefix = "";
5276+
diff_set_noprefix(options);
5277+
return 0;
5278+
}
5279+
5280+
static int diff_opt_default_prefix(const struct option *opt,
5281+
const char *optarg, int unset)
5282+
{
5283+
struct diff_options *options = opt->value;
5284+
5285+
BUG_ON_OPT_NEG(unset);
5286+
BUG_ON_OPT_ARG(optarg);
5287+
diff_set_default_prefix(options);
52685288
return 0;
52695289
}
52705290

@@ -5557,6 +5577,9 @@ struct option *add_diff_options(const struct option *opts,
55575577
OPT_CALLBACK_F(0, "no-prefix", options, NULL,
55585578
N_("do not show any source or destination prefix"),
55595579
PARSE_OPT_NONEG | PARSE_OPT_NOARG, diff_opt_no_prefix),
5580+
OPT_CALLBACK_F(0, "default-prefix", options, NULL,
5581+
N_("use default prefixes a/ and b/"),
5582+
PARSE_OPT_NONEG | PARSE_OPT_NOARG, diff_opt_default_prefix),
55605583
OPT_INTEGER_F(0, "inter-hunk-context", &options->interhunkcontext,
55615584
N_("show context between diff hunks up to the specified number of lines"),
55625585
PARSE_OPT_NONEG),

diff.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,8 @@ void diff_tree_combined(const struct object_id *oid, const struct oid_array *par
496496
void diff_tree_combined_merge(const struct commit *commit, struct rev_info *rev);
497497

498498
void diff_set_mnemonic_prefix(struct diff_options *options, const char *a, const char *b);
499+
void diff_set_noprefix(struct diff_options *options);
500+
void diff_set_default_prefix(struct diff_options *options);
499501

500502
int diff_can_quit_early(struct diff_options *);
501503

t/t4013-diff-various.sh

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,4 +616,46 @@ test_expect_success 'diff -I<regex>: detect malformed regex' '
616616
test_i18ngrep "invalid regex given to -I: " error
617617
'
618618

619+
# check_prefix <patch> <src> <dst>
620+
# check only lines with paths to avoid dependency on exact oid/contents
621+
check_prefix () {
622+
grep -E '^(diff|---|\+\+\+) ' "$1" >actual.paths &&
623+
cat >expect <<-EOF &&
624+
diff --git $2 $3
625+
--- $2
626+
+++ $3
627+
EOF
628+
test_cmp expect actual.paths
629+
}
630+
631+
test_expect_success 'diff-files does not respect diff.noprefix' '
632+
git -c diff.noprefix diff-files -p >actual &&
633+
check_prefix actual a/file0 b/file0
634+
'
635+
636+
test_expect_success 'diff-files respects --no-prefix' '
637+
git diff-files -p --no-prefix >actual &&
638+
check_prefix actual file0 file0
639+
'
640+
641+
test_expect_success 'diff respects diff.noprefix' '
642+
git -c diff.noprefix diff >actual &&
643+
check_prefix actual file0 file0
644+
'
645+
646+
test_expect_success 'diff --default-prefix overrides diff.noprefix' '
647+
git -c diff.noprefix diff --default-prefix >actual &&
648+
check_prefix actual a/file0 b/file0
649+
'
650+
651+
test_expect_success 'diff respects diff.mnemonicprefix' '
652+
git -c diff.mnemonicprefix diff >actual &&
653+
check_prefix actual i/file0 w/file0
654+
'
655+
656+
test_expect_success 'diff --default-prefix overrides diff.mnemonicprefix' '
657+
git -c diff.mnemonicprefix diff --default-prefix >actual &&
658+
check_prefix actual a/file0 b/file0
659+
'
660+
619661
test_done

t/t4014-format-patch.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2396,4 +2396,20 @@ test_expect_success 'interdiff: solo-patch' '
23962396
test_cmp expect actual
23972397
'
23982398

2399+
test_expect_success 'format-patch does not respect diff.noprefix' '
2400+
git -c diff.noprefix format-patch -1 --stdout >actual &&
2401+
grep "^--- a/blorp" actual
2402+
'
2403+
2404+
test_expect_success 'format-patch respects format.noprefix' '
2405+
git -c format.noprefix format-patch -1 --stdout >actual &&
2406+
grep "^--- blorp" actual
2407+
'
2408+
2409+
test_expect_success 'format-patch --default-prefix overrides format.noprefix' '
2410+
git -c format.noprefix \
2411+
format-patch -1 --default-prefix --stdout >actual &&
2412+
grep "^--- a/blorp" actual
2413+
'
2414+
23992415
test_done

0 commit comments

Comments
 (0)