aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Schindelin <johannes.schindelin@gmx.de>2019-11-29 21:11:48 +0000
committerJunio C Hamano <gitster@pobox.com>2019-12-01 07:30:54 -0800
commitd7633578b5ecf0d75e2793b01aa2e9afe645c186 (patch)
treede58122ab36802aaefec05c73dacf984dd75f49e
parent8746e07277cb548185a33efa0037c313a06001f8 (diff)
downloadgit-d7633578b5ecf0d75e2793b01aa2e9afe645c186.tar.gz
built-in add -i: re-implement the `diff` command
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> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--add-interactive.c42
1 files changed, 42 insertions, 0 deletions
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;