When --prompt option is set, git-difftool displays a prompt for each modified file to be viewed in an external diff program. At that point it could be useful to display a counter and the total number of files in the diff queue. Below is the current difftool prompt for the first of 5 modified files: Viewing: 'diff.c' Launch 'vimdiff' [Y/n]: Consider the modified prompt: Viewing (1/5): 'diff.c' Launch 'vimdiff' [Y/n]: The current GIT_EXTERNAL_DIFF mechanism does not tell the number of paths in the diff queue nor the current counter. To make this "counter/total" info available for GIT_EXTERNAL_DIFF programs without breaking existing ones: (1) Modify run_external_diff() function in diff.c to set one environment variable for a counter and one for the total number of files in the diff queue. The size of the diff queue is already available in the diff_queue_struct. For the counter define a new variable in the diff_options struct and reset it to zero in diff_setup_done() function. Pre-increment the counter inside the run_external_diff() function. (2) Modify git-difftool--helper.sh script to display the counter and the diff queue count values in the difftool prompt. (3) Update git.txt documentation (4) Update t4020-diff-external.sh test script Signed-off-by: Zoltan Klinger <zoltan.klinger@xxxxxxxxx> --- Reworked patch to use run_command_v_opt_cd_env() function when invoking the external diff program. Modified test script to use write_script helper function. Documentation/git.txt | 9 +++++++++ diff.c | 20 +++++++++++++++++--- diff.h | 2 ++ git-difftool--helper.sh | 3 ++- t/t4020-diff-external.sh | 14 ++++++++++++++ 5 files changed, 44 insertions(+), 4 deletions(-) diff --git a/Documentation/git.txt b/Documentation/git.txt index 4448ce2..10939ac 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -806,6 +806,15 @@ temporary file --- it is removed when 'GIT_EXTERNAL_DIFF' exits. + For a path that is unmerged, 'GIT_EXTERNAL_DIFF' is called with 1 parameter, <path>. ++ +For each path 'GIT_EXTERNAL_DIFF' is called, two environment variables, +'GIT_DIFF_PATH_COUNTER' and 'GIT_DIFF_PATH_TOTAL' are set. + +'GIT_DIFF_PATH_COUNTER':: + A 1-based counter incremented by one for every path. + +'GIT_DIFF_PATH_TOTAL':: + The total number of paths. other ~~~~~ diff --git a/diff.c b/diff.c index e34bf97..a7d5a47 100644 --- a/diff.c +++ b/diff.c @@ -2899,11 +2899,16 @@ static void run_external_diff(const char *pgm, struct diff_filespec *one, struct diff_filespec *two, const char *xfrm_msg, - int complete_rewrite) + int complete_rewrite, + struct diff_options *o) { const char *spawn_arg[10]; int retval; const char **arg = &spawn_arg[0]; + struct diff_queue_struct *q = &diff_queued_diff; + const char *env[3] = { NULL }; + char env_counter[50]; + char env_total[50]; if (one && two) { struct diff_tempfile *temp_one, *temp_two; @@ -2928,7 +2933,14 @@ static void run_external_diff(const char *pgm, } *arg = NULL; fflush(NULL); - retval = run_command_v_opt(spawn_arg, RUN_USING_SHELL); + + env[0] = env_counter; + snprintf(env_counter, sizeof(env_counter), "GIT_DIFF_PATH_COUNTER=%d", + ++o->diff_path_counter); + env[1] = env_total; + snprintf(env_total, sizeof(env_total), "GIT_DIFF_PATH_TOTAL=%d", q->nr); + + retval = run_command_v_opt_cd_env(spawn_arg, RUN_USING_SHELL, NULL, env); remove_tempfile(); if (retval) { fprintf(stderr, "external diff died, stopping at %s.\n", name); @@ -3042,7 +3054,7 @@ static void run_diff_cmd(const char *pgm, if (pgm) { run_external_diff(pgm, name, other, one, two, xfrm_msg, - complete_rewrite); + complete_rewrite, o); return; } if (one && two) @@ -3317,6 +3329,8 @@ void diff_setup_done(struct diff_options *options) options->output_format = DIFF_FORMAT_NO_OUTPUT; DIFF_OPT_SET(options, EXIT_WITH_STATUS); } + + options->diff_path_counter = 0; } static int opt_arg(const char *arg, int arg_short, const char *arg_long, int *val) diff --git a/diff.h b/diff.h index e342325..42bd34c 100644 --- a/diff.h +++ b/diff.h @@ -164,6 +164,8 @@ struct diff_options { diff_prefix_fn_t output_prefix; int output_prefix_length; void *output_prefix_data; + + int diff_path_counter; }; enum color_diff { diff --git a/git-difftool--helper.sh b/git-difftool--helper.sh index b00ed95..7ef36b9 100755 --- a/git-difftool--helper.sh +++ b/git-difftool--helper.sh @@ -40,7 +40,8 @@ launch_merge_tool () { # the user with the real $MERGED name before launching $merge_tool. if should_prompt then - printf "\nViewing: '%s'\n" "$MERGED" + printf "\nViewing (%s/%s): '%s'\n" "$GIT_DIFF_PATH_COUNTER" \ + "$GIT_DIFF_PATH_TOTAL" "$MERGED" if use_ext_cmd then printf "Launch '%s' [Y/n]: " \ diff --git a/t/t4020-diff-external.sh b/t/t4020-diff-external.sh index 8a30979..1855d31 100755 --- a/t/t4020-diff-external.sh +++ b/t/t4020-diff-external.sh @@ -193,6 +193,20 @@ test_expect_success 'GIT_EXTERNAL_DIFF with more than one changed files' ' GIT_EXTERNAL_DIFF=echo git diff ' +write_script external-diff.sh <<\EOF +echo $GIT_DIFF_PATH_COUNTER of $GIT_DIFF_PATH_TOTAL >>counter.txt +EOF + +test_expect_success 'GIT_EXTERNAL_DIFF path counter/total' ' + GIT_EXTERNAL_DIFF=./external-diff.sh git diff && + echo "1 of 2" >expect && + head -n 1 counter.txt >actual && + test_cmp expect actual && + echo "2 of 2" >expect && + tail -n 1 counter.txt >actual && + test_cmp expect actual +' + test_expect_success 'GIT_EXTERNAL_DIFF generates pretty paths' ' touch file.ext && git add file.ext && -- 1.8.4.4 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html