difftool: display the number of files in the diff queue in the prompt

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 by doing the following:

 - Keep track of the number of paths shown so far in diff_options;

 - Export two new environment variables from run_external_diff() to
   show the total number of paths (from diff_queue_struct) and the
   current value of the counter (from diff_options); and

 - Update git-difftool--helper to use these two environment variables.

Signed-off-by: Zoltan Klinger <zoltan.klinger@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Zoltan Klinger 2013-12-06 10:38:46 +11:00 коммит произвёл Junio C Hamano
Родитель d2446dfd7f
Коммит ee7fb0b1d4
5 изменённых файлов: 43 добавлений и 4 удалений

Просмотреть файл

@ -804,6 +804,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
~~~~~

20
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)

2
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 {

Просмотреть файл

@ -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]: " \

Просмотреть файл

@ -193,6 +193,19 @@ test_expect_success 'GIT_EXTERNAL_DIFF with more than one changed files' '
GIT_EXTERNAL_DIFF=echo git diff
'
test_expect_success 'GIT_EXTERNAL_DIFF path counter/total' '
write_script external-diff.sh <<-\EOF &&
echo $GIT_DIFF_PATH_COUNTER of $GIT_DIFF_PATH_TOTAL >>counter.txt
EOF
>counter.txt &&
cat >expect <<-\EOF &&
1 of 2
2 of 2
EOF
GIT_EXTERNAL_DIFF=./external-diff.sh git diff &&
test_cmp expect counter.txt
'
test_expect_success 'GIT_EXTERNAL_DIFF generates pretty paths' '
touch file.ext &&
git add file.ext &&