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

[PATCH v2 8/9] built-in add -i: re-implement the `diff` command

From
Johannes Schindelin via GitGitGadget <gitgitgadget@gmail.com>
Date
Nov 29, 2019, 21:11 UTC
Message-ID
<e4907112e4b7e053b1436b8bcb8337deb5309463.1575061909.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.171.v2.git.1575061909.gitgitgadget@gmail.com>
From: Johannes Schindelin <johannes.schindelin@gmx.de>

It is not only laziness that we simply spawn `git diff -p --cached` here: this command needs to use the pager, and the pager needs to exit when the diff is done. Currently we do not have any way to make that happen if we run the diff in-process. So let's just spawn.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 add-interactive.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)
diff --git a/add-interactive.c b/add-interactive.c
index cba9688bb5..4d7d44a917 100644
--- a/add-interactive.c
+++ b/add-interactive.c
@@ -931,6 +931,47 @@ static int run_patch(struct add_i_state *s, const struct pathspec *ps,
 	return res;
 }
 
+static int run_diff(struct add_i_state *s, const struct pathspec *ps,
+		    struct prefix_item_list *files,
+		    struct list_and_choose_options *opts)
+{
+	int res = 0;
+	ssize_t count, i;
+
+	struct object_id oid;
+	int is_initial = !resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, &oid,
+					     NULL);
+	if (get_modified_files(s->r, INDEX_ONLY, files, ps, NULL, NULL) < 0)
+		return -1;
+
+	if (!files->items.nr) {
+		putchar('\n');
+		return 0;
+	}
+
+	opts->prompt = N_("Review diff");
+	opts->flags = IMMEDIATE;
+	count = list_and_choose(s, files, opts);
+	opts->flags = 0;
+	if (count >= 0) {
+		struct argv_array args = ARGV_ARRAY_INIT;
+
+		argv_array_pushl(&args, "git", "diff", "-p", "--cached",
+				 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])
+				argv_array_push(&args,
+						files->items.items[i].string);
+		res = run_command_v_opt(args.argv, 0);
+		argv_array_clear(&args);
+	}
+
+	putchar('\n');
+	return res;
+}
+
 static int run_help(struct add_i_state *s, const struct pathspec *unused_ps,
 		    struct prefix_item_list *unused_files,
 		    struct list_and_choose_options *unused_opts)
@@ -1029,6 +1070,7 @@ int run_add_i(struct repository *r, const struct pathspec *ps)
 		{ "revert", run_revert },
 		{ "add untracked", run_add_untracked },
 		{ "patch", run_patch },
+		{ "diff", run_diff },
 		{ "help", run_help },
 	};
 	struct prefix_item_list commands = PREFIX_ITEM_LIST_INIT;
-- 
gitgitgadget
Previous: Johannes Schindelin via GitGitGadgetNext: Johannes Schindelin via GitGitGadget
Message 27 of 29 in “build-in add -i: implement all commands in the main loop”
  1. 0/8 build-in add -i: implement all commands in the main loopJohannes Schindelin via GitGitGadget, Nov 15, 2019
  2. 1/8 built-in add -i: allow filtering the modified files listJohannes Schindelin via GitGitGadget, Nov 15, 2019
  3. Junio C HamanoNov 21, 2019
  4. Johannes SchindelinNov 25, 2019
  5. 3/8 built-in add -i: implement the `update` commandJohannes Schindelin via GitGitGadget, Nov 15, 2019
  6. 5/8 built-in add -i: re-implement `add-untracked` in CJohannes Schindelin via GitGitGadget, Nov 15, 2019
  7. 4/8 built-in add -i: re-implement `revert` in CJohannes Schindelin via GitGitGadget, Nov 15, 2019
  8. 6/8 built-in add -i: implement the `patch` commandJohannes Schindelin via GitGitGadget, Nov 15, 2019
  9. 8/8 built-in add -i: offer the `quit` commandJohannes Schindelin via GitGitGadget, Nov 15, 2019
  10. 7/8 built-in add -i: re-implement the `diff` commandJohannes Schindelin via GitGitGadget, Nov 15, 2019
  11. 2/8 built-in add -i: prepare for multi-selection commandsJohannes Schindelin via GitGitGadget, Nov 15, 2019
  12. Junio C HamanoNov 21, 2019
  13. Johannes SchindelinNov 25, 2019
  14. Junio C HamanoNov 18, 2019
  15. Junio C HamanoNov 18, 2019
  16. Johannes SchindelinNov 18, 2019
  17. Junio C HamanoNov 18, 2019
  18. Johannes SchindelinNov 18, 2019
  19. Junio C HamanoNov 19, 2019
  20. 0/9 built-in add -i: implement all commands in the main loopJohannes Schindelin via GitGitGadget, Nov 29, 2019
  21. 1/9 add-interactive: make sure to release `rev.prune_data`Johannes Schindelin via GitGitGadget, Nov 29, 2019
  22. 2/9 built-in add -i: allow filtering the modified files listJohannes Schindelin via GitGitGadget, Nov 29, 2019
  23. 3/9 built-in add -i: prepare for multi-selection commandsJohannes Schindelin via GitGitGadget, Nov 29, 2019
  24. 4/9 built-in add -i: implement the `update` commandJohannes Schindelin via GitGitGadget, Nov 29, 2019
  25. 5/9 built-in add -i: re-implement `revert` in CJohannes Schindelin via GitGitGadget, Nov 29, 2019
  26. 7/9 built-in add -i: implement the `patch` commandJohannes Schindelin via GitGitGadget, Nov 29, 2019
  27. 8/9 built-in add -i: re-implement the `diff` commandJohannes Schindelin via GitGitGadget, Nov 29, 2019
  28. 9/9 built-in add -i: offer the `quit` commandJohannes Schindelin via GitGitGadget, Nov 29, 2019
  29. 6/9 built-in add -i: re-implement `add-untracked` in CJohannes Schindelin via GitGitGadget, Nov 29, 2019

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.