diff-parseopt: restore -U (no argument) behavior

Before d473e2e0e8 (diff.c: convert -U|--unified, 2019-01-27), -U and --unified are implemented with a custom parser opt_arg() in diff.c. I didn't check this code carefully and not realize that it's the equivalent of PARSE_OPT_NONEG | PARSE_OPT_OPTARG. In other words, if -U is specified without any argument, the option should be accepted, and the default value should be used. Without PARSE_OPT_OPTARG, parse_options() will reject this case and cause a regression. Reported-by: Bryan Turner <bturner@atlassian.com> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed May 29, 2019 at 16:11 UTC 8ef05193bcdda6a28cd41fa3ecd8f356061d49e0
5 files changed +100 -4
diff.c
+6 -4
@@ -4875,9 +4875,11 @@ static int diff_opt_unified(const struct option *opt,
4875
4876 BUG_ON_OPT_NEG(unset);
4877
4878 - options->context = strtol(arg, &s, 10);
4879 - if (*s)
4880 - return error(_("%s expects a numerical value"), "--unified");
4878 + if (arg) {
4879 + options->context = strtol(arg, &s, 10);
4880 + if (*s)
4881 + return error(_("%s expects a numerical value"), "--unified");
4882 + }
4883 enable_patch_output(&options->output_format);
4884
4885 return 0;
@@ -4895,7 +4897,7 @@ static void prep_parse_options(struct diff_options *options)
4897 DIFF_FORMAT_PATCH, DIFF_FORMAT_NO_OUTPUT),
4898 OPT_CALLBACK_F('U', "unified", options, N_("<n>"),
4899 N_("generate diffs with <n> lines context"),
4898 - PARSE_OPT_NONEG, diff_opt_unified),
4900 + PARSE_OPT_NONEG | PARSE_OPT_OPTARG, diff_opt_unified),
4901 OPT_BOOL('W', "function-context", &options->flags.funccontext,
4902 N_("generate diffs with <n> lines context")),
4903 OPT_BIT_F(0, "raw", &options->output_format,
t/t4013-diff-various.sh
+2
@@ -330,6 +330,8 @@ format-patch --inline --stdout initial..master^^
330 format-patch --stdout --cover-letter -n initial..master^
331
332 diff --abbrev initial..side
333 +diff -U initial..side
334 +diff -U1 initial..side
335 diff -r initial..side
336 diff --stat initial..side
337 diff -r --stat initial..side
t/t4013/diff.diff_-U1_initial..side new
+29
@@ -0,0 +1,29 @@
1 +$ git diff -U1 initial..side
2 +diff --git a/dir/sub b/dir/sub
3 +index 35d242b..7289e35 100644
4 +--- a/dir/sub
5 ++++ b/dir/sub
6 +@@ -2 +2,3 @@ A
7 + B
8 ++1
9 ++2
10 +diff --git a/file0 b/file0
11 +index 01e79c3..f4615da 100644
12 +--- a/file0
13 ++++ b/file0
14 +@@ -3 +3,4 @@
15 + 3
16 ++A
17 ++B
18 ++C
19 +diff --git a/file3 b/file3
20 +new file mode 100644
21 +index 0000000..7289e35
22 +--- /dev/null
23 ++++ b/file3
24 +@@ -0,0 +1,4 @@
25 ++A
26 ++B
27 ++1
28 ++2
29 +$
t/t4013/diff.diff_-U2_initial..side new
+31
@@ -0,0 +1,31 @@
1 +$ git diff -U2 initial..side
2 +diff --git a/dir/sub b/dir/sub
3 +index 35d242b..7289e35 100644
4 +--- a/dir/sub
5 ++++ b/dir/sub
6 +@@ -1,2 +1,4 @@
7 + A
8 + B
9 ++1
10 ++2
11 +diff --git a/file0 b/file0
12 +index 01e79c3..f4615da 100644
13 +--- a/file0
14 ++++ b/file0
15 +@@ -2,2 +2,5 @@
16 + 2
17 + 3
18 ++A
19 ++B
20 ++C
21 +diff --git a/file3 b/file3
22 +new file mode 100644
23 +index 0000000..7289e35
24 +--- /dev/null
25 ++++ b/file3
26 +@@ -0,0 +1,4 @@
27 ++A
28 ++B
29 ++1
30 ++2
31 +$
t/t4013/diff.diff_-U_initial..side new
+32
@@ -0,0 +1,32 @@
1 +$ git diff -U initial..side
2 +diff --git a/dir/sub b/dir/sub
3 +index 35d242b..7289e35 100644
4 +--- a/dir/sub
5 ++++ b/dir/sub
6 +@@ -1,2 +1,4 @@
7 + A
8 + B
9 ++1
10 ++2
11 +diff --git a/file0 b/file0
12 +index 01e79c3..f4615da 100644
13 +--- a/file0
14 ++++ b/file0
15 +@@ -1,3 +1,6 @@
16 + 1
17 + 2
18 + 3
19 ++A
20 ++B
21 ++C
22 +diff --git a/file3 b/file3
23 +new file mode 100644
24 +index 0000000..7289e35
25 +--- /dev/null
26 ++++ b/file3
27 +@@ -0,0 +1,4 @@
28 ++A
29 ++B
30 ++1
31 ++2
32 +$