git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 3/3] add-interactive: add new "context" subcommand

From
Leon Michalak via GitGitGadget <gitgitgadget@gmail.com>
Date
May 5, 2025, 09:18 UTC
Message-ID
<b4b7854f330af7588b12e3361bed40723febddad.1746436719.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.1915.git.1746436719.gitgitgadget@gmail.com>
From: Leon Michalak <leonmichalak6@gmail.com>

This teaches `add/commit --interactive` a new "context" subcommand, which changes the amount of context lines subsequent subcommands like "patch" or "diff" generate in their diffs.

Signed-off-by: Leon Michalak <leonmichalak6@gmail.com>
---
 Documentation/git-add.adoc | 10 ++++--
 add-interactive.c          | 72 +++++++++++++++++++++++++++++++++++++-
 t/t3701-add-interactive.sh | 36 ++++++++++++++++---
 3 files changed, 110 insertions(+), 8 deletions(-)
diff --git a/Documentation/git-add.adoc b/Documentation/git-add.adoc
index e3a50706acd5..1ab98c9b876e 100644
--- a/Documentation/git-add.adoc
+++ b/Documentation/git-add.adoc
@@ -265,14 +265,15 @@ and type return, like this:
 ------------
     *** Commands ***
       1: status       2: update       3: revert       4: add untracked
-      5: patch        6: diff         7: quit         8: help
+      5: patch        6: diff         7: context      8: quit
+      9: help
     What now> 1
 ------------
 
 You also could say `s` or `sta` or `status` above as long as the
 choice is unique.
 
-The main command loop has 6 subcommands (plus help and quit).
+The main command loop has 7 subcommands (plus help and quit).
 
 status::
 
@@ -373,6 +374,11 @@ diff::
   This lets you review what will be committed (i.e. between
   `HEAD` and index).
 
+context::
+
+  This lets you change the amount of context lines shown in diffs that
+  the 'patch' and 'diff' subcommands generate.
+
 
 EDITING PATCHES
 ---------------
diff --git a/add-interactive.c b/add-interactive.c
index 1ea8eb711a60..42b1bb8c5b64 100644
--- a/add-interactive.c
+++ b/add-interactive.c
@@ -20,6 +20,8 @@
 #include "prompt.h"
 #include "tree.h"
 
+static void choose_prompt_help_context(struct add_i_state *s);
+
 static void init_color(struct repository *r, struct add_i_state *s,
 		       const char *section_and_slot, char *dst,
 		       const char *default_color)
@@ -259,7 +261,8 @@ static void list(struct add_i_state *s, struct string_list *list, int *selected,
 		opts->print_item(i, selected ? selected[i] : 0, list->items + i,
 				 opts->print_item_data);
 
-		if ((opts->columns) && ((i + 1) % (opts->columns))) {
+		if (i < list->nr - 1 &&
+		    (opts->columns) && ((i + 1) % (opts->columns))) {
 			putchar('\t');
 			last_lf = 0;
 		}
@@ -1047,6 +1050,60 @@ static int run_diff(struct add_i_state *s, const struct pathspec *ps,
 	return res;
 }
 
+static int run_context(struct add_i_state *s, const struct pathspec *ps UNUSED,
+		       struct prefix_item_list *files UNUSED,
+		       struct list_and_choose_options *opts UNUSED)
+{
+	struct diff_options diffopts;
+	struct strbuf input = STRBUF_INIT;
+	int res = 0;
+
+	repo_diff_setup(s->r, &diffopts);
+
+	for (;;) {
+		int new_context;
+		char *endp;
+
+		strbuf_reset(&input);
+
+		color_fprintf(stdout, s->header_color, "  %s:", N_("Current"));
+		fprintf(stdout, " %i\n", s->context == -1 ?
+			diffopts.context : s->context);
+
+		color_fprintf(stdout, s->prompt_color, "%s", N_("Change context"));
+		fputs("> ", stdout);
+		fflush(stdout);
+
+		if (git_read_line_interactively(&input) == EOF) {
+			putchar('\n');
+			break;
+		}
+
+		if (!input.len)
+			break;
+
+		if (!strcmp(input.buf, "?")) {
+			choose_prompt_help_context(s);
+			continue;
+		}
+
+		new_context = strtol(input.buf, &endp, 10);
+		if (*endp) {
+			color_fprintf_ln(stderr, s->error_color,
+				_("Context must be a numerical value"));
+			continue;
+		}
+
+		s->context = new_context;
+
+		break;
+	}
+
+	strbuf_release(&input);
+	putchar('\n');
+	return res;
+}
+
 static int run_help(struct add_i_state *s, const struct pathspec *ps UNUSED,
 		    struct prefix_item_list *files UNUSED,
 		    struct list_and_choose_options *opts UNUSED)
@@ -1061,6 +1118,8 @@ static int run_help(struct add_i_state *s, const struct pathspec *ps UNUSED,
 			 _("pick hunks and update selectively"));
 	color_fprintf_ln(stdout, s->help_color, "diff          - %s",
 			 _("view diff between HEAD and index"));
+	color_fprintf_ln(stdout, s->help_color, "context       - %s",
+			 _("change how many context lines diffs are generated with"));
 	color_fprintf_ln(stdout, s->help_color, "add untracked - %s",
 			 _("add contents of untracked files to the staged set of changes"));
 
@@ -1087,6 +1146,16 @@ static void choose_prompt_help(struct add_i_state *s)
 			 _("(empty) finish selecting"));
 }
 
+static void choose_prompt_help_context(struct add_i_state *s)
+{
+	color_fprintf_ln(stdout, s->help_color, "%s",
+			 _("Prompt help:"));
+	color_fprintf_ln(stdout, s->help_color, "<n>        - %s",
+			 _("specify new context lines amount"));
+	color_fprintf_ln(stdout, s->help_color, "           - %s",
+			 _("(empty) finish selecting"));
+}
+
 typedef int (*command_t)(struct add_i_state *s, const struct pathspec *ps,
 			 struct prefix_item_list *files,
 			 struct list_and_choose_options *opts);
@@ -1147,6 +1216,7 @@ int run_add_i(struct repository *r, const struct pathspec *ps,
 		{ "add untracked", run_add_untracked },
 		{ "patch", run_patch },
 		{ "diff", run_diff },
+		{ "context", run_context },
 		{ "quit", NULL },
 		{ "help", run_help },
 	};
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index b8a05d95f3f1..9dcbc07d5876 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -758,16 +758,19 @@ test_expect_success 'colors can be overridden' '
 
 	<RED>*** Commands ***<RESET>
 	  1: <YELLOW>s<RESET>tatus	  2: <YELLOW>u<RESET>pdate	  3: <YELLOW>r<RESET>evert	  4: <YELLOW>a<RESET>dd untracked
-	  5: <YELLOW>p<RESET>atch	  6: <YELLOW>d<RESET>iff	  7: <YELLOW>q<RESET>uit	  8: <YELLOW>h<RESET>elp
+	  5: <YELLOW>p<RESET>atch	  6: <YELLOW>d<RESET>iff	  7: <YELLOW>c<RESET>ontext	  8: <YELLOW>q<RESET>uit
+	  9: <YELLOW>h<RESET>elp
 	<YELLOW>What now<RESET>> <GREEN>status        - show paths with changes<RESET>
 	<GREEN>update        - add working tree state to the staged set of changes<RESET>
 	<GREEN>revert        - revert staged set of changes back to the HEAD version<RESET>
 	<GREEN>patch         - pick hunks and update selectively<RESET>
 	<GREEN>diff          - view diff between HEAD and index<RESET>
+	<GREEN>context       - change how many context lines diffs are generated with<RESET>
 	<GREEN>add untracked - add contents of untracked files to the staged set of changes<RESET>
 	<RED>*** Commands ***<RESET>
 	  1: <YELLOW>s<RESET>tatus	  2: <YELLOW>u<RESET>pdate	  3: <YELLOW>r<RESET>evert	  4: <YELLOW>a<RESET>dd untracked
-	  5: <YELLOW>p<RESET>atch	  6: <YELLOW>d<RESET>iff	  7: <YELLOW>q<RESET>uit	  8: <YELLOW>h<RESET>elp
+	  5: <YELLOW>p<RESET>atch	  6: <YELLOW>d<RESET>iff	  7: <YELLOW>c<RESET>ontext	  8: <YELLOW>q<RESET>uit
+	  9: <YELLOW>h<RESET>elp
 	<YELLOW>What now<RESET>> Bye.
 	EOF
 	test_cmp expect actual &&
@@ -831,7 +834,8 @@ test_expect_success 'brackets appear without color' '
 	|
 	|*** Commands ***
 	|  1: [s]tatus	  2: [u]pdate	  3: [r]evert	  4: [a]dd untracked
-	|  5: [p]atch	  6: [d]iff	  7: [q]uit	  8: [h]elp
+	|  5: [p]atch	  6: [d]iff	  7: [c]ontext	  8: [q]uit
+	|  9: [h]elp
 	|What now> Bye.
 	EOF
 
@@ -1172,16 +1176,19 @@ test_expect_success 'show help from add--helper' '
 
 	<BOLD>*** Commands ***<RESET>
 	  1: <BOLD;BLUE>s<RESET>tatus	  2: <BOLD;BLUE>u<RESET>pdate	  3: <BOLD;BLUE>r<RESET>evert	  4: <BOLD;BLUE>a<RESET>dd untracked
-	  5: <BOLD;BLUE>p<RESET>atch	  6: <BOLD;BLUE>d<RESET>iff	  7: <BOLD;BLUE>q<RESET>uit	  8: <BOLD;BLUE>h<RESET>elp
+	  5: <BOLD;BLUE>p<RESET>atch	  6: <BOLD;BLUE>d<RESET>iff	  7: <BOLD;BLUE>c<RESET>ontext	  8: <BOLD;BLUE>q<RESET>uit
+	  9: <BOLD;BLUE>h<RESET>elp
 	<BOLD;BLUE>What now<RESET>> <BOLD;RED>status        - show paths with changes<RESET>
 	<BOLD;RED>update        - add working tree state to the staged set of changes<RESET>
 	<BOLD;RED>revert        - revert staged set of changes back to the HEAD version<RESET>
 	<BOLD;RED>patch         - pick hunks and update selectively<RESET>
 	<BOLD;RED>diff          - view diff between HEAD and index<RESET>
+	<BOLD;RED>context       - change how many context lines diffs are generated with<RESET>
 	<BOLD;RED>add untracked - add contents of untracked files to the staged set of changes<RESET>
 	<BOLD>*** Commands ***<RESET>
 	  1: <BOLD;BLUE>s<RESET>tatus	  2: <BOLD;BLUE>u<RESET>pdate	  3: <BOLD;BLUE>r<RESET>evert	  4: <BOLD;BLUE>a<RESET>dd untracked
-	  5: <BOLD;BLUE>p<RESET>atch	  6: <BOLD;BLUE>d<RESET>iff	  7: <BOLD;BLUE>q<RESET>uit	  8: <BOLD;BLUE>h<RESET>elp
+	  5: <BOLD;BLUE>p<RESET>atch	  6: <BOLD;BLUE>d<RESET>iff	  7: <BOLD;BLUE>c<RESET>ontext	  8: <BOLD;BLUE>q<RESET>uit
+	  9: <BOLD;BLUE>h<RESET>elp
 	<BOLD;BLUE>What now<RESET>>$SP
 	Bye.
 	EOF
@@ -1230,4 +1237,23 @@ test_expect_success 'hunk splitting works with diff.suppressBlankEmpty' '
 	test_cmp expect actual
 '
 
+test_expect_success 'change context works' '
+	git reset --hard &&
+	cat >template <<-\EOF &&
+	firstline
+	preline
+	TARGET
+	postline
+	lastline
+	EOF
+	sed "/TARGET/d" >x <template &&
+	git update-index --add x &&
+	git commit -m initial &&
+	sed "s/TARGET/ADDED/" >x <template &&
+	test_write_lines p 1 | git add -i >output &&
+	grep firstline output &&
+	test_write_lines c 0 p 1 | git add -i >output &&
+	! grep firstline output
+'
+
 test_done
-- 
gitgitgadget
Previous: Junio C HamanoNext: Eric Sunshine
Message 6 of 77 in “Better support for customising context lines in --patch commands”
  1. 0/3 Better support for customising context lines in --patch commandsLeon Michalak via GitGitGadget, May 5, 2025
  2. 1/3 add-patch: respect diff.context configurationLeon Michalak via GitGitGadget, May 5, 2025
  3. Eric SunshineMay 5, 2025
  4. Phillip WoodMay 6, 2025
  5. Junio C HamanoMay 6, 2025
  6. 3/3 add-interactive: add new "context" subcommandLeon Michalak via GitGitGadget, May 5, 2025
  7. Eric SunshineMay 6, 2025
  8. Leon MichalakMay 6, 2025
  9. Christian CouderMay 6, 2025
  10. Leon MichalakMay 6, 2025
  11. Junio C HamanoMay 6, 2025
  12. Leon MichalakMay 6, 2025
  13. Phillip WoodMay 7, 2025
  14. Junio C HamanoMay 7, 2025
  15. 2/3 add-patch: add diff.context command line overridesLeon Michalak via GitGitGadget, May 5, 2025
  16. Kristoffer HaugsbakkMay 5, 2025
  17. Phillip WoodMay 7, 2025
  18. Junio C HamanoMay 7, 2025
  19. Leon MichalakMay 7, 2025
  20. Junio C HamanoMay 7, 2025
  21. 0/4 Better support for customising context lines in --patch commandsLeon Michalak via GitGitGadget, May 10, 2025
  22. 1/4 test: refactor to use "test_grep"Leon Michalak via GitGitGadget, May 10, 2025
  23. Junio C HamanoMay 12, 2025
  24. Leon MichalakMay 12, 2025
  25. 2/4 test: refactor to use "test_config"Leon Michalak via GitGitGadget, May 10, 2025
  26. 3/4 add-patch: respect diff.context configurationLeon Michalak via GitGitGadget, May 10, 2025
  27. Phillip WoodMay 13, 2025
  28. Junio C HamanoMay 13, 2025
  29. Phillip WoodMay 14, 2025
  30. Junio C HamanoMay 15, 2025
  31. 4/4 add-patch: add diff.context command line overridesLeon Michalak via GitGitGadget, May 10, 2025
  32. Junio C HamanoMay 12, 2025
  33. Leon MichalakMay 12, 2025
  34. Phillip WoodMay 13, 2025
  35. Phillip WoodMay 13, 2025
  36. Leon MichalakMay 13, 2025
  37. phillip.wood123@gmail.comMay 14, 2025
  38. 0/4 Better support for customising context lines in --patch commandsLeon Michalak via GitGitGadget, Jun 28, 2025
  39. 1/4 test: use "test_grep"Leon Michalak via GitGitGadget, Jun 28, 2025
  40. Junio C HamanoJun 30, 2025
  41. 2/4 test: use "test_config"Leon Michalak via GitGitGadget, Jun 28, 2025
  42. Junio C HamanoJun 30, 2025
  43. 4/4 add-patch: add diff.context command line overridesLeon Michalak via GitGitGadget, Jun 28, 2025
  44. Junio C HamanoJun 30, 2025
  45. Phillip WoodJul 1, 2025
  46. Junio C HamanoJul 1, 2025
  47. Phillip WoodJul 2, 2025
  48. Junio C HamanoJul 2, 2025
  49. Phillip WoodJul 1, 2025
  50. 3/4 add-patch: respect diff.context configurationLeon Michalak via GitGitGadget, Jun 28, 2025
  51. Junio C HamanoJun 30, 2025
  52. Phillip WoodJul 1, 2025
  53. Junio C HamanoJun 30, 2025
  54. Junio C HamanoJul 9, 2025
  55. Leon MichalakJul 9, 2025
  56. Junio C HamanoJul 9, 2025
  57. 0/4 Better support for customising context lines in --patch commandsLeon Michalak via GitGitGadget, Jul 19, 2025
  58. 1/4 t: use test_grep in t3701 and t4055Leon Michalak via GitGitGadget, Jul 19, 2025
  59. 2/4 t: use test_config in t4055Leon Michalak via GitGitGadget, Jul 19, 2025
  60. 3/4 add-patch: respect diff.context configurationLeon Michalak via GitGitGadget, Jul 19, 2025
  61. 4/4 add-patch: add diff.context command line overridesLeon Michalak via GitGitGadget, Jul 19, 2025
  62. Phillip WoodJul 22, 2025
  63. Leon MichalakJul 22, 2025
  64. Leon MichalakJul 22, 2025
  65. Phillip WoodJul 23, 2025
  66. Junio C HamanoJul 21, 2025
  67. Phillip WoodJul 22, 2025
  68. Junio C HamanoJul 22, 2025
  69. 0/4 Better support for customising context lines in --patch commandsLeon Michalak via GitGitGadget, Jul 29, 2025
  70. 2/4 t: use test_config in t4055Leon Michalak via GitGitGadget, Jul 29, 2025
  71. 3/4 add-patch: respect diff.context configurationLeon Michalak via GitGitGadget, Jul 29, 2025
  72. 1/4 t: use test_grep in t3701 and t4055Leon Michalak via GitGitGadget, Jul 29, 2025
  73. 4/4 add-patch: add diff.context command line overridesLeon Michalak via GitGitGadget, Jul 29, 2025
  74. Phillip WoodJul 29, 2025
  75. Junio C HamanoJul 29, 2025
  76. Leon MichalakJul 29, 2025
  77. Leon MichalakMay 5, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.