Skip to content

Commit 5235122

Browse files
committed
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 <[email protected]>
1 parent c599406 commit 5235122

File tree

1 file changed

+47
-1
lines changed

1 file changed

+47
-1
lines changed

add-interactive.c

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,51 @@ static int run_patch(struct add_i_state *s, const struct pathspec *ps,
845845
return res;
846846
}
847847

848+
static int run_diff(struct add_i_state *s, const struct pathspec *ps,
849+
struct file_list *files,
850+
struct list_and_choose_options *opts)
851+
{
852+
struct prefix_item **items = (struct prefix_item **)files->file;
853+
int res = 0, *selected = NULL;
854+
ssize_t count, i;
855+
856+
struct object_id oid;
857+
int is_initial = !resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, &oid,
858+
NULL);
859+
reset_file_list(files);
860+
if (get_modified_files(s->r, INDEX_ONLY, NULL, NULL, files, ps) < 0)
861+
return -1;
862+
863+
if (!files->nr) {
864+
putchar('\n');
865+
return 0;
866+
}
867+
868+
opts->prompt = N_("Review diff");
869+
CALLOC_ARRAY(selected, files->nr);
870+
871+
opts->flags = IMMEDIATE;
872+
count = list_and_choose(items, selected, files->nr, s, opts);
873+
opts->flags = 0;
874+
if (count >= 0) {
875+
struct argv_array args = ARGV_ARRAY_INIT;
876+
877+
argv_array_pushl(&args, "git", "diff", "-p", "--cached",
878+
oid_to_hex(!is_initial ? &oid :
879+
s->r->hash_algo->empty_tree),
880+
"--", NULL);
881+
for (i = 0; i < files->nr; i++)
882+
if (selected[i])
883+
argv_array_push(&args, items[i]->name);
884+
res = run_command_v_opt(args.argv, 0);
885+
argv_array_clear(&args);
886+
}
887+
888+
putchar('\n');
889+
free(selected);
890+
return res;
891+
}
892+
848893
static int run_help(struct add_i_state *s, const struct pathspec *ps,
849894
struct file_list *files,
850895
struct list_and_choose_options *opts)
@@ -939,10 +984,11 @@ int run_add_i(struct repository *r, const struct pathspec *ps)
939984
revert = { { "revert" }, run_revert },
940985
add_untracked = { { "add untracked" }, run_add_untracked },
941986
patch = { { "patch" }, run_patch },
987+
diff = { { "diff" }, run_diff },
942988
help = { { "help" }, run_help };
943989
struct command_item *commands[] = {
944990
&status, &update, &revert, &add_untracked,
945-
&patch, &help
991+
&patch, &diff, &help
946992
};
947993

948994
struct print_file_item_data print_file_item_data = {

0 commit comments

Comments
 (0)