From 044a93014b677914870a872a9c317a46a5a81699 Mon Sep 17 00:00:00 2001 From: Leon Michalak Date: Sat, 10 May 2025 09:19:51 +0100 Subject: [PATCH 1/4] test: use "test_grep" Use the modern "test_grep" test utility instead of regular "grep" which provides better debug information if tests fail. This is a prerequisite to the commits that follow which add to both test files. Signed-off-by: Leon Michalak --- t/t3701-add-interactive.sh | 48 +++++++++++++++++++------------------- t/t4055-diff-context.sh | 28 +++++++++++----------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index b8a05d95f3f130..b088ee141ff4d5 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -63,7 +63,7 @@ test_expect_success 'setup (initial)' ' ' test_expect_success 'status works (initial)' ' git add -i output && - grep "+1/-0 *+2/-0 file" output + test_grep "+1/-0 *+2/-0 file" output ' test_expect_success 'setup expected' ' @@ -86,7 +86,7 @@ test_expect_success 'revert works (initial)' ' git add file && test_write_lines r 1 | git add -i && git ls-files >output && - ! grep . output + test_grep ! . output ' test_expect_success 'add untracked (multiple)' ' @@ -109,7 +109,7 @@ test_expect_success 'setup (commit)' ' ' test_expect_success 'status works (commit)' ' git add -i output && - grep "+1/-0 *+2/-0 file" output + test_grep "+1/-0 *+2/-0 file" output ' test_expect_success 'update can stage deletions' ' @@ -141,7 +141,7 @@ test_expect_success 'revert works (commit)' ' git add file && test_write_lines r 1 | git add -i && git add -i output && - grep "unchanged *+3/-0 file" output + test_grep "unchanged *+3/-0 file" output ' test_expect_success 'reject multi-key input' ' @@ -185,7 +185,7 @@ test_expect_success 'setup fake editor' ' test_expect_success 'bad edit rejected' ' git reset && test_write_lines e n d | git add -p >output && - grep "hunk does not apply" output + test_grep "hunk does not apply" output ' test_expect_success 'setup patch' ' @@ -198,7 +198,7 @@ test_expect_success 'setup patch' ' test_expect_success 'garbage edit rejected' ' git reset && test_write_lines e n d | git add -p >output && - grep "hunk does not apply" output + test_grep "hunk does not apply" output ' test_expect_success 'setup patch' ' @@ -313,8 +313,8 @@ test_expect_success FILEMODE 'stage mode and hunk' ' chmod +x file && printf "y\\ny\\n" | git add -p && git diff --cached file >out && - grep "new mode" out && - grep "+content" out && + test_grep "new mode" out && + test_grep "+content" out && git diff file >out && test_must_be_empty out ' @@ -636,7 +636,7 @@ test_expect_success 'split hunk "add -p (edit)"' ' printf "%s\n" s e q n q q | EDITOR=: git add -p && git diff >actual && - ! grep "^+15" actual + test_grep ! "^+15" actual ' test_expect_success 'split hunk "add -p (no, yes, edit)"' ' @@ -648,7 +648,7 @@ test_expect_success 'split hunk "add -p (no, yes, edit)"' ' EDITOR=: git add -p 2>error && test_must_be_empty error && git diff >actual && - ! grep "^+31" actual + test_grep ! "^+31" actual ' test_expect_success 'split hunk with incomplete line at end' ' @@ -682,7 +682,7 @@ test_expect_success 'edit, adding lines to the first hunk' ' EDITOR=./fake_editor.sh git add -p 2>error && test_must_be_empty error && git diff --cached >actual && - grep "^+22" actual + test_grep "^+22" actual ' test_expect_success 'patch mode ignores unmerged entries' ' @@ -696,7 +696,7 @@ test_expect_success 'patch mode ignores unmerged entries' ' test_must_fail git merge side && echo changed >non-conflict.t && echo y | git add -p >output && - ! grep a/conflict.t output && + test_grep ! a/conflict.t output && cat >expected <<-\EOF && * Unmerged path conflict.t diff --git a/non-conflict.t b/non-conflict.t @@ -728,7 +728,7 @@ test_expect_success 'diffs can be colorized' ' # We do not want to depend on the exact coloring scheme # git uses for diffs, so just check that we saw some kind of color. - grep "$(printf "\\033")" output + test_grep "$(printf "\\033")" output ' test_expect_success 'colors can be overridden' ' @@ -743,7 +743,7 @@ test_expect_success 'colors can be overridden' ' -c color.interactive.error=blue \ add -i 2>err.raw err && - grep "Huh (trigger)?" err && + test_grep "Huh (trigger)?" err && test_write_lines help quit >input && force_color git \ @@ -863,7 +863,7 @@ test_expect_success 'colorized diffs respect diff.wsErrorHighlight' ' printf y >y && force_color git -c diff.wsErrorHighlight=all add -p >output.raw 2>&1 output && - grep "old<" output + test_grep "old<" output ' test_expect_success 'diffFilter filters diff' ' @@ -876,7 +876,7 @@ test_expect_success 'diffFilter filters diff' ' # avoid depending on the exact coloring or content of the prompts, # and just make sure we saw our diff prefixed - grep foo:.*content output + test_grep foo:.*content output ' test_expect_success 'detect bogus diffFilter output' ' @@ -886,7 +886,7 @@ test_expect_success 'detect bogus diffFilter output' ' test_config interactive.diffFilter "sed 6d" && printf y >y && force_color test_must_fail git add -p output 2>&1 && - grep "mismatched output" output + test_grep "mismatched output" output ' test_expect_success 'handle iffy colored hunk headers' ' @@ -896,7 +896,7 @@ test_expect_success 'handle iffy colored hunk headers' ' printf n >n && force_color git -c interactive.diffFilter="sed s/.*@@.*/XX/" \ add -p >output 2>&1 output && - grep dirty-head output && - grep dirty-both-ways output && - ! grep dirty-otherwise output + test_grep dirty-head output && + test_grep dirty-both-ways output && + test_grep ! dirty-otherwise output ' test_expect_success 'handle submodules' ' echo 123 >>for-submodules/dirty-otherwise/initial.t && force_color git -C for-submodules add -p dirty-otherwise >output 2>&1 && - grep "No changes" output && + test_grep "No changes" output && force_color git -C for-submodules add -p dirty-head >output 2>&1 actual && rev="$(git -C for-submodules/dirty-head rev-parse HEAD)" && - grep "$rev" actual + test_grep "$rev" actual ' test_expect_success 'set up pathological context' ' diff --git a/t/t4055-diff-context.sh b/t/t4055-diff-context.sh index ec2804eea67cf1..c66f966a3ab324 100755 --- a/t/t4055-diff-context.sh +++ b/t/t4055-diff-context.sh @@ -38,36 +38,36 @@ test_expect_success 'setup' ' test_expect_success 'the default number of context lines is 3' ' git diff >output && - ! grep "^ d" output && - grep "^ e" output && - grep "^ j" output && - ! grep "^ k" output + test_grep ! "^ d" output && + test_grep "^ e" output && + test_grep "^ j" output && + test_grep ! "^ k" output ' test_expect_success 'diff.context honored by "log"' ' git log -1 -p >output && - ! grep firstline output && + test_grep ! firstline output && git config diff.context 8 && git log -1 -p >output && - grep "^ firstline" output + test_grep "^ firstline" output ' test_expect_success 'The -U option overrides diff.context' ' git config diff.context 8 && git log -U4 -1 >output && - ! grep "^ firstline" output + test_grep ! "^ firstline" output ' test_expect_success 'diff.context honored by "diff"' ' git config diff.context 8 && git diff >output && - grep "^ firstline" output + test_grep "^ firstline" output ' test_expect_success 'plumbing not affected' ' git config diff.context 8 && git diff-files -p >output && - ! grep "^ firstline" output + test_grep ! "^ firstline" output ' test_expect_success 'non-integer config parsing' ' @@ -85,8 +85,8 @@ test_expect_success 'negative integer config parsing' ' test_expect_success '-U0 is valid, so is diff.context=0' ' git config diff.context 0 && git diff >output && - grep "^-ADDED" output && - grep "^+MODIFIED" output + test_grep "^-ADDED" output && + test_grep "^+MODIFIED" output ' test_expect_success '-U2147483647 works' ' @@ -94,9 +94,9 @@ test_expect_success '-U2147483647 works' ' test_line_count = 16 x && git diff -U2147483647 >output && test_line_count = 22 output && - grep "^-ADDED" output && - grep "^+MODIFIED" output && - grep "^+APPENDED" output + test_grep "^-ADDED" output && + test_grep "^+MODIFIED" output && + test_grep "^+APPENDED" output ' test_done From e5c40d37750fe7effa95e8bf2cc24945150364d7 Mon Sep 17 00:00:00 2001 From: Leon Michalak Date: Sat, 10 May 2025 09:23:43 +0100 Subject: [PATCH 2/4] test: use "test_config" Use the modern "test_config" test utility instead of manual"git config" as the former provides clean up on test completion. This is a prerequisite to the commits that follow which add to this test file. Signed-off-by: Leon Michalak --- t/t4055-diff-context.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/t/t4055-diff-context.sh b/t/t4055-diff-context.sh index c66f966a3ab324..1384a8195705e3 100755 --- a/t/t4055-diff-context.sh +++ b/t/t4055-diff-context.sh @@ -47,43 +47,43 @@ test_expect_success 'the default number of context lines is 3' ' test_expect_success 'diff.context honored by "log"' ' git log -1 -p >output && test_grep ! firstline output && - git config diff.context 8 && + test_config diff.context 8 && git log -1 -p >output && test_grep "^ firstline" output ' test_expect_success 'The -U option overrides diff.context' ' - git config diff.context 8 && + test_config diff.context 8 && git log -U4 -1 >output && test_grep ! "^ firstline" output ' test_expect_success 'diff.context honored by "diff"' ' - git config diff.context 8 && + test_config diff.context 8 && git diff >output && test_grep "^ firstline" output ' test_expect_success 'plumbing not affected' ' - git config diff.context 8 && + test_config diff.context 8 && git diff-files -p >output && test_grep ! "^ firstline" output ' test_expect_success 'non-integer config parsing' ' - git config diff.context no && + test_config diff.context no && test_must_fail git diff 2>output && test_grep "bad numeric config value" output ' test_expect_success 'negative integer config parsing' ' - git config diff.context -1 && + test_config diff.context -1 && test_must_fail git diff 2>output && test_grep "bad config variable" output ' test_expect_success '-U0 is valid, so is diff.context=0' ' - git config diff.context 0 && + test_config diff.context 0 && git diff >output && test_grep "^-ADDED" output && test_grep "^+MODIFIED" output From 1ec8a1384862765795f17e2d0fcb7b601ef2b25f Mon Sep 17 00:00:00 2001 From: Leon Michalak Date: Sun, 4 May 2025 09:47:40 +0100 Subject: [PATCH 3/4] add-patch: respect diff.context configuration Various builtins that use add-patch infrastructure do not respect the user's diff.context and diff.interHunkContext file configurations. This patch fixes this inconsistency. This is because the plumbing commands used by "git add -p" to generate the diff do not read those config settings. Fix this by reading the config before generating the patch and passing it along to the diff command with the "-U" and "--inter-hunk-context" command-line options. Signed-off-by: Leon Michalak --- add-interactive.c | 17 +++++++++++++++++ add-interactive.h | 1 + add-patch.c | 6 ++++++ t/t3701-add-interactive.sh | 22 ++++++++++++++++++++++ 4 files changed, 46 insertions(+) diff --git a/add-interactive.c b/add-interactive.c index 97ff35b6f12a32..e0aafb8dd02a36 100644 --- a/add-interactive.c +++ b/add-interactive.c @@ -39,8 +39,12 @@ static void init_color(struct repository *r, struct add_i_state *s, void init_add_i_state(struct add_i_state *s, struct repository *r) { const char *value; + int context; + int interhunkcontext; s->r = r; + s->context = -1; + s->interhunkcontext = -1; if (repo_config_get_value(r, "color.interactive", &value)) s->use_color = -1; @@ -78,6 +82,19 @@ void init_add_i_state(struct add_i_state *s, struct repository *r) repo_config_get_string(r, "diff.algorithm", &s->interactive_diff_algorithm); + if (!repo_config_get_int(r, "diff.context", &context)) { + if (context < 0) + die(_("%s cannot be negative"), "diff.context"); + else + s->context = context; + } + if (!repo_config_get_int(r, "diff.interHunkContext", &interhunkcontext)) { + if (interhunkcontext < 0) + die(_("%s cannot be negative"), "diff.interHunkContext"); + else + s->interhunkcontext = interhunkcontext; + } + repo_config_get_bool(r, "interactive.singlekey", &s->use_single_key); if (s->use_single_key) setbuf(stdin, NULL); diff --git a/add-interactive.h b/add-interactive.h index 693f125e8e4bc6..c63f35b14be868 100644 --- a/add-interactive.h +++ b/add-interactive.h @@ -18,6 +18,7 @@ struct add_i_state { int use_single_key; char *interactive_diff_filter, *interactive_diff_algorithm; + int context, interhunkcontext; }; void init_add_i_state(struct add_i_state *s, struct repository *r); diff --git a/add-patch.c b/add-patch.c index 95c67d8c80c4f3..b43ca1600738d1 100644 --- a/add-patch.c +++ b/add-patch.c @@ -415,6 +415,8 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps) { struct strvec args = STRVEC_INIT; const char *diff_algorithm = s->s.interactive_diff_algorithm; + int diff_context = s->s.context; + int diff_interhunkcontext = s->s.interhunkcontext; struct strbuf *plain = &s->plain, *colored = NULL; struct child_process cp = CHILD_PROCESS_INIT; char *p, *pend, *colored_p = NULL, *colored_pend = NULL, marker = '\0'; @@ -424,6 +426,10 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps) int res; strvec_pushv(&args, s->mode->diff_cmd); + if (diff_context != -1) + strvec_pushf(&args, "--unified=%i", diff_context); + if (diff_interhunkcontext != -1) + strvec_pushf(&args, "--inter-hunk-context=%i", diff_interhunkcontext); if (diff_algorithm) strvec_pushf(&args, "--diff-algorithm=%s", diff_algorithm); if (s->revision) { diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index b088ee141ff4d5..18dc329ea1f697 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -1230,4 +1230,26 @@ test_expect_success 'hunk splitting works with diff.suppressBlankEmpty' ' test_cmp expect actual ' +test_expect_success 'add -p respects diff.context' ' + test_write_lines a b c d e f g h i j k l m >file && + git add file && + test_write_lines a b c d e f G h i j k l m >file && + echo y | git -c diff.context=5 add -p >actual && + test_grep "@@ -2,11 +2,11 @@" actual +' + +test_expect_success 'add -p respects diff.interHunkContext' ' + test_write_lines a b c d e f g h i j k l m n o p q r s >file && + git add file && + test_write_lines a b c d E f g i i j k l m N o p q r s >file && + echo y | git -c diff.interhunkcontext=2 add -p >actual && + test_grep "@@ -2,16 +2,16 @@" actual +' + +test_expect_success 'add -p rejects negative diff.context' ' + test_config diff.context -1 && + test_must_fail git add -p 2>output && + test_grep "diff.context cannot be negative" output +' + test_done From b68c58b667c29c66433b4634ad44ee9ec5257e80 Mon Sep 17 00:00:00 2001 From: Leon Michalak Date: Sun, 4 May 2025 09:56:26 +0100 Subject: [PATCH 4/4] add-patch: add diff.context command line overrides This patch compliments the previous commit, where builtins that use add-patch infrastructure now respect diff.context and diff.interHunkContext file configurations. In particular, this patch helps users who don't want to set persistent context configurations or just want a way to override them on a one-time basis, by allowing the relevant builtins to accept corresponding command line options that override the file configurations. This mimics commands such as diff and log, which allow for both context file configuration and command line overrides. Signed-off-by: Leon Michalak --- Documentation/diff-context-options.adoc | 10 +++++ Documentation/git-add.adoc | 2 + Documentation/git-checkout.adoc | 2 + Documentation/git-commit.adoc | 2 + Documentation/git-reset.adoc | 2 + Documentation/git-restore.adoc | 2 + Documentation/git-stash.adoc | 2 + add-interactive.c | 36 ++++++++++++---- add-interactive.h | 16 +++++-- add-patch.c | 5 ++- builtin/add.c | 21 ++++++++-- builtin/checkout.c | 31 ++++++++++++-- builtin/commit.c | 16 ++++++- builtin/reset.c | 17 +++++++- builtin/stash.c | 56 ++++++++++++++++++++----- commit.h | 3 +- parse-options.h | 2 + t/t3701-add-interactive.sh | 49 ++++++++++++++++++++++ t/t4055-diff-context.sh | 30 +++++++++++++ t/t9902-completion.sh | 2 + 20 files changed, 271 insertions(+), 35 deletions(-) create mode 100644 Documentation/diff-context-options.adoc diff --git a/Documentation/diff-context-options.adoc b/Documentation/diff-context-options.adoc new file mode 100644 index 00000000000000..e161260358fff5 --- /dev/null +++ b/Documentation/diff-context-options.adoc @@ -0,0 +1,10 @@ +`-U`:: +`--unified=`:: + Generate diffs with __ lines of context. Defaults to `diff.context` + or 3 if the config option is unset. + +`--inter-hunk-context=`:: + Show the context between diff hunks, up to the specified __ + of lines, thereby fusing hunks that are close to each other. + Defaults to `diff.interHunkContext` or 0 if the config option + is unset. diff --git a/Documentation/git-add.adoc b/Documentation/git-add.adoc index eba0b419ce508f..b7a735824d6ce0 100644 --- a/Documentation/git-add.adoc +++ b/Documentation/git-add.adoc @@ -104,6 +104,8 @@ This effectively runs `add --interactive`, but bypasses the initial command menu and directly jumps to the `patch` subcommand. See ``Interactive mode'' for details. +include::diff-context-options.adoc[] + `-e`:: `--edit`:: Open the diff vs. the index in an editor and let the user diff --git a/Documentation/git-checkout.adoc b/Documentation/git-checkout.adoc index ee83b6d9ba9a9b..40e02cfd6562ae 100644 --- a/Documentation/git-checkout.adoc +++ b/Documentation/git-checkout.adoc @@ -289,6 +289,8 @@ section of linkgit:git-add[1] to learn how to operate the `--patch` mode. Note that this option uses the no overlay mode by default (see also `--overlay`), and currently doesn't support overlay mode. +include::diff-context-options.adoc[] + `--ignore-other-worktrees`:: `git checkout` refuses when the wanted branch is already checked out or otherwise in use by another worktree. This option makes diff --git a/Documentation/git-commit.adoc b/Documentation/git-commit.adoc index dc219025f1eb0b..ae988a883b5b86 100644 --- a/Documentation/git-commit.adoc +++ b/Documentation/git-commit.adoc @@ -76,6 +76,8 @@ OPTIONS which changes to commit. See linkgit:git-add[1] for details. +include::diff-context-options.adoc[] + `-C `:: `--reuse-message=`:: Take an existing __ object, and reuse the log message diff --git a/Documentation/git-reset.adoc b/Documentation/git-reset.adoc index 53ab88c5451c44..50e8a0ba6f6612 100644 --- a/Documentation/git-reset.adoc +++ b/Documentation/git-reset.adoc @@ -125,6 +125,8 @@ OPTIONS separated with _NUL_ character and all other characters are taken literally (including newlines and quotes). +include::diff-context-options.adoc[] + `--`:: Do not interpret any more arguments as options. diff --git a/Documentation/git-restore.adoc b/Documentation/git-restore.adoc index 877b7772e66735..1dcc2bb7aea387 100644 --- a/Documentation/git-restore.adoc +++ b/Documentation/git-restore.adoc @@ -52,6 +52,8 @@ leave out at most one of ___ and __, in which case it defaults to Mode" section of linkgit:git-add[1] to learn how to operate the `--patch` mode. +include::diff-context-options.adoc[] + `-W`:: `--worktree`:: `-S`:: diff --git a/Documentation/git-stash.adoc b/Documentation/git-stash.adoc index 1a5177f4986ca4..0578c619c410c6 100644 --- a/Documentation/git-stash.adoc +++ b/Documentation/git-stash.adoc @@ -208,6 +208,8 @@ to learn how to operate the `--patch` mode. The `--patch` option implies `--keep-index`. You can use `--no-keep-index` to override this. +include::diff-context-options.adoc[] + -S:: --staged:: This option is only valid for `push` and `save` commands. diff --git a/add-interactive.c b/add-interactive.c index e0aafb8dd02a36..c343568bf7ecac 100644 --- a/add-interactive.c +++ b/add-interactive.c @@ -36,7 +36,8 @@ static void init_color(struct repository *r, struct add_i_state *s, free(key); } -void init_add_i_state(struct add_i_state *s, struct repository *r) +void init_add_i_state(struct add_i_state *s, struct repository *r, + struct add_p_opt *add_p_opt) { const char *value; int context; @@ -98,6 +99,17 @@ void init_add_i_state(struct add_i_state *s, struct repository *r) repo_config_get_bool(r, "interactive.singlekey", &s->use_single_key); if (s->use_single_key) setbuf(stdin, NULL); + + if (add_p_opt->context != -1) { + if (add_p_opt->context < 0) + die(_("%s cannot be negative"), "--unified"); + s->context = add_p_opt->context; + } + if (add_p_opt->interhunkcontext != -1) { + if (add_p_opt->interhunkcontext < 0) + die(_("%s cannot be negative"), "--inter-hunk-context"); + s->interhunkcontext = add_p_opt->interhunkcontext; + } } void clear_add_i_state(struct add_i_state *s) @@ -986,6 +998,10 @@ static int run_patch(struct add_i_state *s, const struct pathspec *ps, opts->prompt = N_("Patch update"); count = list_and_choose(s, files, opts); if (count > 0) { + struct add_p_opt add_p_opt = { + .context = s->context, + .interhunkcontext = s->interhunkcontext, + }; struct strvec args = STRVEC_INIT; struct pathspec ps_selected = { 0 }; @@ -996,7 +1012,7 @@ static int run_patch(struct add_i_state *s, const struct pathspec *ps, parse_pathspec(&ps_selected, PATHSPEC_ALL_MAGIC & ~PATHSPEC_LITERAL, PATHSPEC_LITERAL_PATH, "", args.v); - res = run_add_p(s->r, ADD_P_ADD, NULL, &ps_selected); + res = run_add_p(s->r, ADD_P_ADD, &add_p_opt, NULL, &ps_selected); strvec_clear(&args); clear_pathspec(&ps_selected); } @@ -1031,10 +1047,13 @@ static int run_diff(struct add_i_state *s, const struct pathspec *ps, if (count > 0) { struct child_process cmd = CHILD_PROCESS_INIT; - strvec_pushl(&cmd.args, "git", "diff", "-p", "--cached", - oid_to_hex(!is_initial ? &oid : - s->r->hash_algo->empty_tree), - "--", NULL); + strvec_pushl(&cmd.args, "git", "diff", "-p", "--cached", NULL); + if (s->context != -1) + strvec_pushf(&cmd.args, "--unified=%i", s->context); + if (s->interhunkcontext != -1) + strvec_pushf(&cmd.args, "--inter-hunk-context=%i", s->interhunkcontext); + strvec_pushl(&cmd.args, oid_to_hex(!is_initial ? &oid : + s->r->hash_algo->empty_tree), "--", NULL); for (i = 0; i < files->items.nr; i++) if (files->selected[i]) strvec_push(&cmd.args, @@ -1127,7 +1146,8 @@ static void command_prompt_help(struct add_i_state *s) _("(empty) select nothing")); } -int run_add_i(struct repository *r, const struct pathspec *ps) +int run_add_i(struct repository *r, const struct pathspec *ps, + struct add_p_opt *add_p_opt) { struct add_i_state s = { NULL }; struct print_command_item_data data = { "[", "]" }; @@ -1170,7 +1190,7 @@ int run_add_i(struct repository *r, const struct pathspec *ps) ->util = util; } - init_add_i_state(&s, r); + init_add_i_state(&s, r, add_p_opt); /* * When color was asked for, use the prompt color for diff --git a/add-interactive.h b/add-interactive.h index c63f35b14be868..4213dcd67b9a8e 100644 --- a/add-interactive.h +++ b/add-interactive.h @@ -3,6 +3,13 @@ #include "color.h" +struct add_p_opt { + int context; + int interhunkcontext; +}; + +#define ADD_P_OPT_INIT { .context = -1, .interhunkcontext = -1 } + struct add_i_state { struct repository *r; int use_color; @@ -21,12 +28,14 @@ struct add_i_state { int context, interhunkcontext; }; -void init_add_i_state(struct add_i_state *s, struct repository *r); +void init_add_i_state(struct add_i_state *s, struct repository *r, + struct add_p_opt *add_p_opt); void clear_add_i_state(struct add_i_state *s); struct repository; struct pathspec; -int run_add_i(struct repository *r, const struct pathspec *ps); +int run_add_i(struct repository *r, const struct pathspec *ps, + struct add_p_opt *add_p_opt); enum add_p_mode { ADD_P_ADD, @@ -37,6 +46,7 @@ enum add_p_mode { }; int run_add_p(struct repository *r, enum add_p_mode mode, - const char *revision, const struct pathspec *ps); + struct add_p_opt *o, const char *revision, + const struct pathspec *ps); #endif diff --git a/add-patch.c b/add-patch.c index b43ca1600738d1..c0d33820c55841 100644 --- a/add-patch.c +++ b/add-patch.c @@ -1766,14 +1766,15 @@ static int patch_update_file(struct add_p_state *s, } int run_add_p(struct repository *r, enum add_p_mode mode, - const char *revision, const struct pathspec *ps) + struct add_p_opt *o, const char *revision, + const struct pathspec *ps) { struct add_p_state s = { { r }, STRBUF_INIT, STRBUF_INIT, STRBUF_INIT, STRBUF_INIT }; size_t i, binary_count = 0; - init_add_i_state(&s.s, r); + init_add_i_state(&s.s, r, o); if (mode == ADD_P_STASH) s.mode = &patch_mode_stash; diff --git a/builtin/add.c b/builtin/add.c index 7c292ffdc6c2c9..a00dab9b8fa094 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -29,6 +29,7 @@ static const char * const builtin_add_usage[] = { NULL }; static int patch_interactive, add_interactive, edit_interactive; +static struct add_p_opt add_p_opt = ADD_P_OPT_INIT; static int take_worktree_changes; static int add_renormalize; static int pathspec_file_nul; @@ -157,7 +158,7 @@ static int refresh(struct repository *repo, int verbose, const struct pathspec * int interactive_add(struct repository *repo, const char **argv, const char *prefix, - int patch) + int patch, struct add_p_opt *add_p_opt) { struct pathspec pathspec; int ret; @@ -169,9 +170,9 @@ int interactive_add(struct repository *repo, prefix, argv); if (patch) - ret = !!run_add_p(repo, ADD_P_ADD, NULL, &pathspec); + ret = !!run_add_p(repo, ADD_P_ADD, add_p_opt, NULL, &pathspec); else - ret = !!run_add_i(repo, &pathspec); + ret = !!run_add_i(repo, &pathspec, add_p_opt); clear_pathspec(&pathspec); return ret; @@ -253,6 +254,8 @@ static struct option builtin_add_options[] = { OPT_GROUP(""), OPT_BOOL('i', "interactive", &add_interactive, N_("interactive picking")), OPT_BOOL('p', "patch", &patch_interactive, N_("select hunks interactively")), + OPT_DIFF_UNIFIED(&add_p_opt.context), + OPT_DIFF_INTERHUNK_CONTEXT(&add_p_opt.interhunkcontext), OPT_BOOL('e', "edit", &edit_interactive, N_("edit current diff and apply")), OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files"), 0), OPT_BOOL('u', "update", &take_worktree_changes, N_("update tracked files")), @@ -394,6 +397,11 @@ int cmd_add(int argc, prepare_repo_settings(repo); repo->settings.command_requires_full_index = 0; + if (add_p_opt.context < -1) + die(_("'%s' cannot be negative"), "--unified"); + if (add_p_opt.interhunkcontext < -1) + die(_("'%s' cannot be negative"), "--inter-hunk-context"); + if (patch_interactive) add_interactive = 1; if (add_interactive) { @@ -401,7 +409,12 @@ int cmd_add(int argc, die(_("options '%s' and '%s' cannot be used together"), "--dry-run", "--interactive/--patch"); if (pathspec_from_file) die(_("options '%s' and '%s' cannot be used together"), "--pathspec-from-file", "--interactive/--patch"); - exit(interactive_add(repo, argv + 1, prefix, patch_interactive)); + exit(interactive_add(repo, argv + 1, prefix, patch_interactive, &add_p_opt)); + } else { + if (add_p_opt.context != -1) + die(_("the option '%s' requires '%s'"), "--unified", "--interactive/--patch"); + if (add_p_opt.interhunkcontext != -1) + die(_("the option '%s' requires '%s'"), "--inter-hunk-context", "--interactive/--patch"); } if (edit_interactive) { diff --git a/builtin/checkout.c b/builtin/checkout.c index 536192d3456c19..3737ba4c3920f7 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -61,6 +61,8 @@ static const char * const restore_usage[] = { struct checkout_opts { int patch_mode; + int patch_context; + int patch_interhunk_context; int quiet; int merge; int force; @@ -104,7 +106,12 @@ struct checkout_opts { struct tree *source_tree; }; -#define CHECKOUT_OPTS_INIT { .conflict_style = -1, .merge = -1 } +#define CHECKOUT_OPTS_INIT { \ + .conflict_style = -1, \ + .merge = -1, \ + .patch_context = -1, \ + .patch_interhunk_context = -1, \ +} struct branch_info { char *name; /* The short name used */ @@ -539,6 +546,10 @@ static int checkout_paths(const struct checkout_opts *opts, if (opts->patch_mode) { enum add_p_mode patch_mode; + struct add_p_opt add_p_opt = { + .context = opts->patch_context, + .interhunkcontext = opts->patch_interhunk_context, + }; const char *rev = new_branch_info->name; char rev_oid[GIT_MAX_HEXSZ + 1]; @@ -564,8 +575,8 @@ static int checkout_paths(const struct checkout_opts *opts, else BUG("either flag must have been set, worktree=%d, index=%d", opts->checkout_worktree, opts->checkout_index); - return !!run_add_p(the_repository, patch_mode, rev, - &opts->pathspec); + return !!run_add_p(the_repository, patch_mode, &add_p_opt, + rev, &opts->pathspec); } repo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR); @@ -1738,6 +1749,8 @@ static struct option *add_checkout_path_options(struct checkout_opts *opts, N_("checkout their version for unmerged files"), 3, PARSE_OPT_NONEG), OPT_BOOL('p', "patch", &opts->patch_mode, N_("select hunks interactively")), + OPT_DIFF_UNIFIED(&opts->patch_context), + OPT_DIFF_INTERHUNK_CONTEXT(&opts->patch_interhunk_context), OPT_BOOL(0, "ignore-skip-worktree-bits", &opts->ignore_skipworktree, N_("do not limit pathspecs to sparse entries only")), OPT_PATHSPEC_FROM_FILE(&opts->pathspec_from_file), @@ -1780,6 +1793,18 @@ static int checkout_main(int argc, const char **argv, const char *prefix, argc = parse_options(argc, argv, prefix, options, usagestr, parseopt_flags); + if (opts->patch_context < -1) + die(_("'%s' cannot be negative"), "--unified"); + if (opts->patch_interhunk_context < -1) + die(_("'%s' cannot be negative"), "--inter-hunk-context"); + + if (!opts->patch_mode) { + if (opts->patch_context != -1) + die(_("the option '%s' requires '%s'"), "--unified", "--patch"); + if (opts->patch_interhunk_context != -1) + die(_("the option '%s' requires '%s'"), "--inter-hunk-context", "--patch"); + } + if (opts->show_progress < 0) { if (opts->quiet) opts->show_progress = 0; diff --git a/builtin/commit.c b/builtin/commit.c index fba0dded64a718..73673bc7db9ff8 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -19,6 +19,7 @@ #include "environment.h" #include "diff.h" #include "commit.h" +#include "add-interactive.h" #include "gettext.h" #include "revision.h" #include "wt-status.h" @@ -122,6 +123,7 @@ static const char *edit_message, *use_message; static char *fixup_message, *fixup_commit, *squash_message; static const char *fixup_prefix; static int all, also, interactive, patch_interactive, only, amend, signoff; +static struct add_p_opt add_p_opt = ADD_P_OPT_INIT; static int edit_flag = -1; /* unspecified */ static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship; static int config_commit_verbose = -1; /* unspecified */ @@ -354,6 +356,11 @@ static const char *prepare_index(const char **argv, const char *prefix, const char *ret; char *path = NULL; + if (add_p_opt.context < -1) + die(_("'%s' cannot be negative"), "--unified"); + if (add_p_opt.interhunkcontext < -1) + die(_("'%s' cannot be negative"), "--inter-hunk-context"); + if (is_status) refresh_flags |= REFRESH_UNMERGED; parse_pathspec(&pathspec, 0, @@ -400,7 +407,7 @@ static const char *prepare_index(const char **argv, const char *prefix, old_index_env = xstrdup_or_null(getenv(INDEX_ENVIRONMENT)); setenv(INDEX_ENVIRONMENT, the_repository->index_file, 1); - if (interactive_add(the_repository, argv, prefix, patch_interactive) != 0) + if (interactive_add(the_repository, argv, prefix, patch_interactive, &add_p_opt) != 0) die(_("interactive add failed")); the_repository->index_file = old_repo_index_file; @@ -424,6 +431,11 @@ static const char *prepare_index(const char **argv, const char *prefix, commit_style = COMMIT_NORMAL; ret = get_lock_file_path(&index_lock); goto out; + } else { + if (add_p_opt.context != -1) + die(_("the option '%s' requires '%s'"), "--unified", "--interactive/--patch"); + if (add_p_opt.interhunkcontext != -1) + die(_("the option '%s' requires '%s'"), "--inter-hunk-context", "--interactive/--patch"); } /* @@ -1722,6 +1734,8 @@ int cmd_commit(int argc, OPT_BOOL('i', "include", &also, N_("add specified files to index for commit")), OPT_BOOL(0, "interactive", &interactive, N_("interactively add files")), OPT_BOOL('p', "patch", &patch_interactive, N_("interactively add changes")), + OPT_DIFF_UNIFIED(&add_p_opt.context), + OPT_DIFF_INTERHUNK_CONTEXT(&add_p_opt.interhunkcontext), OPT_BOOL('o', "only", &only, N_("commit only specified files")), OPT_BOOL('n', "no-verify", &no_verify, N_("bypass pre-commit and commit-msg hooks")), OPT_BOOL(0, "dry-run", &dry_run, N_("show what would be committed")), diff --git a/builtin/reset.c b/builtin/reset.c index dc50ffc1ac59e8..9fb32795c9c53d 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -346,6 +346,7 @@ int cmd_reset(int argc, struct object_id oid; struct pathspec pathspec; int intent_to_add = 0; + struct add_p_opt add_p_opt = ADD_P_OPT_INIT; const struct option options[] = { OPT__QUIET(&quiet, N_("be quiet, only report errors")), OPT_BOOL(0, "no-refresh", &no_refresh, @@ -370,6 +371,8 @@ int cmd_reset(int argc, PARSE_OPT_OPTARG, option_parse_recurse_submodules_worktree_updater), OPT_BOOL('p', "patch", &patch_mode, N_("select hunks interactively")), + OPT_DIFF_UNIFIED(&add_p_opt.context), + OPT_DIFF_INTERHUNK_CONTEXT(&add_p_opt.interhunkcontext), OPT_BOOL('N', "intent-to-add", &intent_to_add, N_("record only the fact that removed paths will be added later")), OPT_PATHSPEC_FROM_FILE(&pathspec_from_file), @@ -420,6 +423,11 @@ int cmd_reset(int argc, oidcpy(&oid, &tree->object.oid); } + if (add_p_opt.context < -1) + die(_("'%s' cannot be negative"), "--unified"); + if (add_p_opt.interhunkcontext < -1) + die(_("'%s' cannot be negative"), "--inter-hunk-context"); + prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; @@ -427,9 +435,14 @@ int cmd_reset(int argc, if (reset_type != NONE) die(_("options '%s' and '%s' cannot be used together"), "--patch", "--{hard,mixed,soft}"); trace2_cmd_mode("patch-interactive"); - update_ref_status = !!run_add_p(the_repository, ADD_P_RESET, rev, - &pathspec); + update_ref_status = !!run_add_p(the_repository, ADD_P_RESET, + &add_p_opt, rev, &pathspec); goto cleanup; + } else { + if (add_p_opt.context != -1) + die(_("the option '%s' requires '%s'"), "--unified", "--patch"); + if (add_p_opt.interhunkcontext != -1) + die(_("the option '%s' requires '%s'"), "--inter-hunk-context", "--patch"); } /* git reset tree [--] paths... can be used to diff --git a/builtin/stash.c b/builtin/stash.c index 7cd3ad8aa48ed9..6da162e5e69a45 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -1242,7 +1242,8 @@ static int stash_staged(struct stash_info *info, struct strbuf *out_patch, } static int stash_patch(struct stash_info *info, const struct pathspec *ps, - struct strbuf *out_patch, int quiet) + struct strbuf *out_patch, int quiet, + struct add_p_opt *add_p_opt) { int ret = 0; struct child_process cp_read_tree = CHILD_PROCESS_INIT; @@ -1267,7 +1268,7 @@ static int stash_patch(struct stash_info *info, const struct pathspec *ps, old_index_env = xstrdup_or_null(getenv(INDEX_ENVIRONMENT)); setenv(INDEX_ENVIRONMENT, the_repository->index_file, 1); - ret = !!run_add_p(the_repository, ADD_P_STASH, NULL, ps); + ret = !!run_add_p(the_repository, ADD_P_STASH, add_p_opt, NULL, ps); the_repository->index_file = old_repo_index_file; if (old_index_env && *old_index_env) @@ -1362,8 +1363,8 @@ static int stash_working_tree(struct stash_info *info, const struct pathspec *ps } static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_buf, - int include_untracked, int patch_mode, int only_staged, - struct stash_info *info, struct strbuf *patch, + int include_untracked, int patch_mode, struct add_p_opt *add_p_opt, + int only_staged, struct stash_info *info, struct strbuf *patch, int quiet) { int ret = 0; @@ -1444,7 +1445,7 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b untracked_commit_option = 1; } if (patch_mode) { - ret = stash_patch(info, ps, patch, quiet); + ret = stash_patch(info, ps, patch, quiet, add_p_opt); if (ret < 0) { if (!quiet) fprintf_ln(stderr, _("Cannot save the current " @@ -1519,7 +1520,7 @@ static int create_stash(int argc, const char **argv, const char *prefix UNUSED, if (!check_changes_tracked_files(&ps)) return 0; - ret = do_create_stash(&ps, &stash_msg_buf, 0, 0, 0, &info, + ret = do_create_stash(&ps, &stash_msg_buf, 0, 0, NULL, 0, &info, NULL, 0); if (!ret) printf_ln("%s", oid_to_hex(&info.w_commit)); @@ -1530,7 +1531,8 @@ static int create_stash(int argc, const char **argv, const char *prefix UNUSED, } static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int quiet, - int keep_index, int patch_mode, int include_untracked, int only_staged) + int keep_index, int patch_mode, struct add_p_opt *add_p_opt, + int include_untracked, int only_staged) { int ret = 0; struct stash_info info = STASH_INFO_INIT; @@ -1600,8 +1602,8 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q if (stash_msg) strbuf_addstr(&stash_msg_buf, stash_msg); - if (do_create_stash(ps, &stash_msg_buf, include_untracked, patch_mode, only_staged, - &info, &patch, quiet)) { + if (do_create_stash(ps, &stash_msg_buf, include_untracked, patch_mode, + add_p_opt, only_staged, &info, &patch, quiet)) { ret = -1; goto done; } @@ -1774,6 +1776,7 @@ static int push_stash(int argc, const char **argv, const char *prefix, const char *stash_msg = NULL; char *pathspec_from_file = NULL; struct pathspec ps; + struct add_p_opt add_p_opt = ADD_P_OPT_INIT; struct option options[] = { OPT_BOOL('k', "keep-index", &keep_index, N_("keep index")), @@ -1781,6 +1784,8 @@ static int push_stash(int argc, const char **argv, const char *prefix, N_("stash staged changes only")), OPT_BOOL('p', "patch", &patch_mode, N_("stash in patch mode")), + OPT_DIFF_UNIFIED(&add_p_opt.context), + OPT_DIFF_INTERHUNK_CONTEXT(&add_p_opt.interhunkcontext), OPT__QUIET(&quiet, N_("quiet mode")), OPT_BOOL('u', "include-untracked", &include_untracked, N_("include untracked files in stash")), @@ -1836,8 +1841,20 @@ static int push_stash(int argc, const char **argv, const char *prefix, die(_("the option '%s' requires '%s'"), "--pathspec-file-nul", "--pathspec-from-file"); } + if (!patch_mode) { + if (add_p_opt.context != -1) + die(_("the option '%s' requires '%s'"), "--unified", "--patch"); + if (add_p_opt.interhunkcontext != -1) + die(_("the option '%s' requires '%s'"), "--inter-hunk-context", "--patch"); + } + + if (add_p_opt.context < -1) + die(_("'%s' cannot be negative"), "--unified"); + if (add_p_opt.interhunkcontext < -1) + die(_("'%s' cannot be negative"), "--inter-hunk-context"); + ret = do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode, - include_untracked, only_staged); + &add_p_opt, include_untracked, only_staged); clear_pathspec(&ps); free(pathspec_from_file); @@ -1862,6 +1879,7 @@ static int save_stash(int argc, const char **argv, const char *prefix, const char *stash_msg = NULL; struct pathspec ps; struct strbuf stash_msg_buf = STRBUF_INIT; + struct add_p_opt add_p_opt = ADD_P_OPT_INIT; struct option options[] = { OPT_BOOL('k', "keep-index", &keep_index, N_("keep index")), @@ -1869,6 +1887,8 @@ static int save_stash(int argc, const char **argv, const char *prefix, N_("stash staged changes only")), OPT_BOOL('p', "patch", &patch_mode, N_("stash in patch mode")), + OPT_DIFF_UNIFIED(&add_p_opt.context), + OPT_DIFF_INTERHUNK_CONTEXT(&add_p_opt.interhunkcontext), OPT__QUIET(&quiet, N_("quiet mode")), OPT_BOOL('u', "include-untracked", &include_untracked, N_("include untracked files in stash")), @@ -1887,8 +1907,22 @@ static int save_stash(int argc, const char **argv, const char *prefix, stash_msg = strbuf_join_argv(&stash_msg_buf, argc, argv, ' '); memset(&ps, 0, sizeof(ps)); + + if (add_p_opt.context < -1) + die(_("'%s' cannot be negative"), "--unified"); + if (add_p_opt.interhunkcontext < -1) + die(_("'%s' cannot be negative"), "--inter-hunk-context"); + + if (!patch_mode) { + if (add_p_opt.context != -1) + die(_("the option '%s' requires '%s'"), "--unified", "--patch"); + if (add_p_opt.interhunkcontext != -1) + die(_("the option '%s' requires '%s'"), "--inter-hunk-context", "--patch"); + } + ret = do_push_stash(&ps, stash_msg, quiet, keep_index, - patch_mode, include_untracked, only_staged); + patch_mode, &add_p_opt, include_untracked, + only_staged); strbuf_release(&stash_msg_buf); return ret; diff --git a/commit.h b/commit.h index 70c870dae4d4b9..7a7fedbc2f1484 100644 --- a/commit.h +++ b/commit.h @@ -2,6 +2,7 @@ #define COMMIT_H #include "object.h" +#include "add-interactive.h" struct signature_check; struct strbuf; @@ -257,7 +258,7 @@ int for_each_commit_graft(each_commit_graft_fn, void *); int interactive_add(struct repository *repo, const char **argv, const char *prefix, - int patch); + int patch, struct add_p_opt *add_p_opt); struct commit_extra_header { struct commit_extra_header *next; diff --git a/parse-options.h b/parse-options.h index 91c3e3c29b3dda..bdae8f116198d6 100644 --- a/parse-options.h +++ b/parse-options.h @@ -616,6 +616,8 @@ int parse_opt_tracking_mode(const struct option *, const char *, int); #define OPT_PATHSPEC_FROM_FILE(v) OPT_FILENAME(0, "pathspec-from-file", v, N_("read pathspec from file")) #define OPT_PATHSPEC_FILE_NUL(v) OPT_BOOL(0, "pathspec-file-nul", v, N_("with --pathspec-from-file, pathspec elements are separated with NUL character")) #define OPT_AUTOSTASH(v) OPT_BOOL(0, "autostash", v, N_("automatically stash/stash pop before and after")) +#define OPT_DIFF_UNIFIED(v) OPT_INTEGER_F('U', "unified", v, N_("generate diffs with lines context"), PARSE_OPT_NONEG) +#define OPT_DIFF_INTERHUNK_CONTEXT(v) OPT_INTEGER_F(0, "inter-hunk-context", v, N_("show context between diff hunks up to the specified number of lines"), PARSE_OPT_NONEG) #define OPT_IPVERSION(v) \ OPT_SET_INT_F('4', "ipv4", (v), N_("use IPv4 addresses only"), \ diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index 18dc329ea1f697..d08a87f9ec5319 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -1252,4 +1252,53 @@ test_expect_success 'add -p rejects negative diff.context' ' test_grep "diff.context cannot be negative" output ' +for cmd in add checkout restore 'commit -m file' +do + test_expect_success "${cmd%% *} accepts -U and --inter-hunk-context" " + test_write_lines a b c d e f g h i j k l m n o p q r s t u v >file && + git add file && + test_write_lines a b c d e F g h i j k l m n o p Q r s t u v >file && + echo y | git -c diff.context=5 -c diff.interhunkcontext=1 \ + $cmd -p -U 4 --inter-hunk-context 2 >actual && + test_grep \"@@ -2,20 +2,20 @@\" actual + " +done + +test_expect_success 'reset accepts -U and --inter-hunk-context' ' + test_write_lines a b c d e f g h i j k l m n o p q r s t u v >file && + git commit -m file file && + test_write_lines a b c d e F g h i j k l m n o p Q r s t u v >file && + git add file && + echo y | git -c diff.context=5 -c diff.interhunkcontext=1 \ + reset -p -U 4 --inter-hunk-context 2 >actual && + test_grep "@@ -2,20 +2,20 @@" actual +' + +test_expect_success 'stash accepts -U and --inter-hunk-context' ' + test_write_lines a b c d e F g h i j k l m n o p Q r s t u v >file && + git commit -m file file && + test_write_lines a b c d e f g h i j k l m n o p q r s t u v >file && + echo y | git -c diff.context=5 -c diff.interhunkcontext=1 \ + stash -p -U 4 --inter-hunk-context 2 >actual && + test_grep "@@ -2,20 +2,20 @@" actual +' + +for cmd in add checkout commit reset restore 'stash save' 'stash push' +do + test_expect_success "$cmd rejects invalid context options" " + test_must_fail git $cmd -p -U -3 2>actual && + cat actual | echo && + test_grep -e \"'--unified' cannot be negative\" actual && + + test_must_fail git $cmd -p --inter-hunk-context -3 2>actual && + test_grep -e \"'--inter-hunk-context' cannot be negative\" actual && + + test_must_fail git $cmd -U 7 2>actual && + test_grep -E \"'--unified' requires '(--interactive/)?--patch'\" actual && + + test_must_fail git $cmd --inter-hunk-context 2 2>actual && + test_grep -E \"'--inter-hunk-context' requires '(--interactive/)?--patch'\" actual + " +done + test_done diff --git a/t/t4055-diff-context.sh b/t/t4055-diff-context.sh index 1384a8195705e3..0158fe6568cbf2 100755 --- a/t/t4055-diff-context.sh +++ b/t/t4055-diff-context.sh @@ -58,6 +58,36 @@ test_expect_success 'The -U option overrides diff.context' ' test_grep ! "^ firstline" output ' +test_expect_success 'The -U option overrides diff.context for "add"' ' + test_config diff.context 8 && + git add -U4 -p >output && + test_grep ! "^ firstline" output +' + +test_expect_success 'The -U option overrides diff.context for "commit"' ' + test_config diff.context 8 && + ! git commit -U4 -p >output && + test_grep ! "^ firstline" output +' + +test_expect_success 'The -U option overrides diff.context for "checkout"' ' + test_config diff.context 8 && + git checkout -U4 -p >output && + test_grep ! "^ firstline" output +' + +test_expect_success 'The -U option overrides diff.context for "stash"' ' + test_config diff.context 8 && + ! git stash -U4 -p >output && + test_grep ! "^ firstline" output +' + +test_expect_success 'The -U option overrides diff.context for "restore"' ' + test_config diff.context 8 && + git restore -U4 -p >output && + test_grep ! "^ firstline" output +' + test_expect_success 'diff.context honored by "diff"' ' test_config diff.context 8 && git diff >output && diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index 343b8cd1912bd5..6650d33fba69c8 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -2596,6 +2596,8 @@ test_expect_success 'double dash "git checkout"' ' --merge Z --conflict=Z --patch Z + --unified=Z + --inter-hunk-context=Z --ignore-skip-worktree-bits Z --ignore-other-worktrees Z --recurse-submodules Z