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>
			
			
				maint
			
			
		
							parent
							
								
									d2446dfd7f
								
							
						
					
					
						commit
						ee7fb0b1d4
					
				|  | @ -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
								
								
								
								
							
							
						
						
									
										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
								
								
								
								
							
							
						
						
									
										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 && | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Zoltan Klinger
						Zoltan Klinger