Skip to content

Commit ee7fb0b

Browse files
zklingergitster
authored andcommitted
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>
1 parent d2446df commit ee7fb0b

File tree

5 files changed

+43
-4
lines changed

5 files changed

+43
-4
lines changed

Documentation/git.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,15 @@ temporary file --- it is removed when 'GIT_EXTERNAL_DIFF' exits.
804804
+
805805
For a path that is unmerged, 'GIT_EXTERNAL_DIFF' is called with 1
806806
parameter, <path>.
807+
+
808+
For each path 'GIT_EXTERNAL_DIFF' is called, two environment variables,
809+
'GIT_DIFF_PATH_COUNTER' and 'GIT_DIFF_PATH_TOTAL' are set.
810+
811+
'GIT_DIFF_PATH_COUNTER'::
812+
A 1-based counter incremented by one for every path.
813+
814+
'GIT_DIFF_PATH_TOTAL'::
815+
The total number of paths.
807816

808817
other
809818
~~~~~

diff.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2899,11 +2899,16 @@ static void run_external_diff(const char *pgm,
28992899
struct diff_filespec *one,
29002900
struct diff_filespec *two,
29012901
const char *xfrm_msg,
2902-
int complete_rewrite)
2902+
int complete_rewrite,
2903+
struct diff_options *o)
29032904
{
29042905
const char *spawn_arg[10];
29052906
int retval;
29062907
const char **arg = &spawn_arg[0];
2908+
struct diff_queue_struct *q = &diff_queued_diff;
2909+
const char *env[3] = { NULL };
2910+
char env_counter[50];
2911+
char env_total[50];
29072912

29082913
if (one && two) {
29092914
struct diff_tempfile *temp_one, *temp_two;
@@ -2928,7 +2933,14 @@ static void run_external_diff(const char *pgm,
29282933
}
29292934
*arg = NULL;
29302935
fflush(NULL);
2931-
retval = run_command_v_opt(spawn_arg, RUN_USING_SHELL);
2936+
2937+
env[0] = env_counter;
2938+
snprintf(env_counter, sizeof(env_counter), "GIT_DIFF_PATH_COUNTER=%d",
2939+
++o->diff_path_counter);
2940+
env[1] = env_total;
2941+
snprintf(env_total, sizeof(env_total), "GIT_DIFF_PATH_TOTAL=%d", q->nr);
2942+
2943+
retval = run_command_v_opt_cd_env(spawn_arg, RUN_USING_SHELL, NULL, env);
29322944
remove_tempfile();
29332945
if (retval) {
29342946
fprintf(stderr, "external diff died, stopping at %s.\n", name);
@@ -3042,7 +3054,7 @@ static void run_diff_cmd(const char *pgm,
30423054

30433055
if (pgm) {
30443056
run_external_diff(pgm, name, other, one, two, xfrm_msg,
3045-
complete_rewrite);
3057+
complete_rewrite, o);
30463058
return;
30473059
}
30483060
if (one && two)
@@ -3317,6 +3329,8 @@ void diff_setup_done(struct diff_options *options)
33173329
options->output_format = DIFF_FORMAT_NO_OUTPUT;
33183330
DIFF_OPT_SET(options, EXIT_WITH_STATUS);
33193331
}
3332+
3333+
options->diff_path_counter = 0;
33203334
}
33213335

33223336
static int opt_arg(const char *arg, int arg_short, const char *arg_long, int *val)

diff.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ struct diff_options {
164164
diff_prefix_fn_t output_prefix;
165165
int output_prefix_length;
166166
void *output_prefix_data;
167+
168+
int diff_path_counter;
167169
};
168170

169171
enum color_diff {

git-difftool--helper.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ launch_merge_tool () {
4040
# the user with the real $MERGED name before launching $merge_tool.
4141
if should_prompt
4242
then
43-
printf "\nViewing: '%s'\n" "$MERGED"
43+
printf "\nViewing (%s/%s): '%s'\n" "$GIT_DIFF_PATH_COUNTER" \
44+
"$GIT_DIFF_PATH_TOTAL" "$MERGED"
4445
if use_ext_cmd
4546
then
4647
printf "Launch '%s' [Y/n]: " \

t/t4020-diff-external.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,19 @@ test_expect_success 'GIT_EXTERNAL_DIFF with more than one changed files' '
193193
GIT_EXTERNAL_DIFF=echo git diff
194194
'
195195

196+
test_expect_success 'GIT_EXTERNAL_DIFF path counter/total' '
197+
write_script external-diff.sh <<-\EOF &&
198+
echo $GIT_DIFF_PATH_COUNTER of $GIT_DIFF_PATH_TOTAL >>counter.txt
199+
EOF
200+
>counter.txt &&
201+
cat >expect <<-\EOF &&
202+
1 of 2
203+
2 of 2
204+
EOF
205+
GIT_EXTERNAL_DIFF=./external-diff.sh git diff &&
206+
test_cmp expect counter.txt
207+
'
208+
196209
test_expect_success 'GIT_EXTERNAL_DIFF generates pretty paths' '
197210
touch file.ext &&
198211
git add file.ext &&

0 commit comments

Comments
 (0)