git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] git-difftool-helper.sh: learn a new way skip to save point

From
Junio C Hamano <gitster@pobox.com>
Date
Feb 7, 2021, 19:04 UTC
Message-ID
<xmqq8s7z8zsg.fsf@gitster.c.googlers.com>
In-Reply-To
<pull.870.git.1612711153591.gitgitgadget@gmail.com>

Sorry, but a not-yet-written reply went out by accident; please discard it.

> `git difftool` only allow us to select file to view In turn.
Funny capitalization "In"?
> If there is a commit with many files and we exit in search,
> We will have to traverse list again to get the file diff which
> we want to see.Therefore,here is a new method:every time before

It makes it hard to lack SP after punctuation like '.', ',', and ':'.

Show 6 quoted lines
> we view the file diff,the current coordinates will be stored in
> `GIT_DIR/difftool_skip_to`,this file will be deleted after
> successful traversing.But if an unexpected exit occurred midway,
> git will view the coordinates in the save point,ask user if they
> want continue from the last saved point.This will improve the
> user experience.

I think the idea sounds good. Admittedly I do not use difftool myself, so I do not even know if and how the current end user experience is so bad to require a patch like this (e.g. I do not know how "unexpected exit" is "unexpected"---isn't it the end user initiated action to "quit", or does the tool crash or something?).

So I won't be the best qualified person to judge if the solution presented is the best one for the problem.

    $ git shortlog --no-merges git-diff-helper.sh
might be a good way to find whom to ask for review and help.

Having said that, I do have one opinion on the "skip-to" filename. I do not think it is wise to call it after the purpose you want to use it for (i.e. "I want to use it to skip to the recorded position"). Instead, if the file records "the last visited position", it is better to name it after that (e.g. "difftool-last-position". If it records "the next file to be visited", then "difftool-next-file" may be a good name).

The reason is because your first design may be to visit the file the user was visiting before the "crash" happened, but you may later want to revise the design to allow the user to say "start at one file before the file I was visiting" etc. The location recorded in the file may still be used to decide where the code skips to when restarting, but no longer exactly where the code "skips to". If you name it after what it is, not what it is (currently) used for, the design would become clearer.

Show 19 quoted lines
> diff --git a/git-difftool--helper.sh b/git-difftool--helper.sh
> index 46af3e60b718..56ec1d38a7a1 100755
> --- a/git-difftool--helper.sh
> +++ b/git-difftool--helper.sh
> @@ -6,6 +6,7 @@
>  # Copyright (c) 2009, 2010 David Aguilar
>  
>  TOOL_MODE=diff
> +GIT_DIFFTOOL_SKIP_TO_FILE="$GIT_DIR/difftool-skip-to"
>  . git-mergetool--lib
>  
>  # difftool.prompt controls the default prompt/no-prompt behavior
> @@ -40,6 +41,31 @@ launch_merge_tool () {
>  	# the user with the real $MERGED name before launching $merge_tool.
>  	if should_prompt
>  	then
> +		if test -f "$GIT_DIFFTOOL_SKIP_TO_FILE"
> +		then
> +			SAVE_POINT_NUM=$(cat "$GIT_DIFFTOOL_SKIP_TO_FILE")
You can avoid the TOCTTOU race by
		if SAVE_POINT=$(cat 2>/dev/null "$GIT_DIFFTOOL_SKIP_TO_FILE")
		then
but that wouldn't probably matter in this application.
> +			if test $SAVE_POINT_NUM -le $GIT_DIFF_PATH_TOTAL &&
> +				test $SAVE_POINT_NUM -gt $GIT_DIFF_PATH_COUNTER

Think what happens if the file is corrupt and SAVE_POINT_NUM has (1) an empty string, (2) garbage that has $IFS whitespace, (3) non number, in it. At least, quoting the variable inside double-quotes, i.e. "$SAVE_POINT_NUM", would help an error condition reported correctly at the runtime.

> +			then
> +				# choice skip or not skip when check first file.
A bit funny language.  Isn't the code clear enough without this comment?
> +				if test $GIT_DIFF_PATH_COUNTER -eq "1"

No need to quote the constant "1"; quoting the variable side may be a good practice, even though I think in this codepath we know GIT_DIFF_PATH_COUNTER is a well-formatted number.

> +				then
> +					printf "do you want to skip to last time difftool save point($SAVE_POINT_NUM) [Y/n]?"

"Skip" is probably an implementation detail that the user does not have to know. "Do you want to start from the last file you were viewing?", perhaps?

Show 12 quoted lines
> +					read skip_ans || return
> +					if test "$skip_ans" = y
> +					then
> +						return
> +					fi
> +				else
> +					return
> +				fi
> +			fi
> +		fi
> +		# write the current coordinates to .git/difftool-skip-to
> +		if test !$SAVE_POINT_NUM || $SAVE_POINT_NUM -ne $GIT_DIFF_PATH_COUNTER

Have this code been tested? I think "test" is missing after the "||", and I am not quite sure what you are trying to check with "test !$SAVE_POINT_NUM", either. The "test" utility, when given a non-operator string (like "!23" this one is checking when the last visited path was the 23rd one), returns true if the string is not an empty string, and by definition a string made by appending anything after "!" would not be empty, so the entire "|| $SAVE_POINT_NUM ..." have been skipped in your test, I think.

Is writing the current position to the file unconditionally good enough? After all, we are about to go interactive with the user, so the body of this "if" statement won't be performance critical in any sense, no? Or is there something more subtle going on and correctness of the code depends on this condition? I cannot quite tell.

> +		then
> +			echo $GIT_DIFF_PATH_COUNTER > $GIT_DIFFTOOL_SKIP_TO_FILE
		echo "$GIT_DIFF_PATH_COUNTER" >"$GIT_DIFFTOOL_SKIP_TO_FILE"
cf. Documentation/CodingGuidelines
 - Redirection operators should be written with space before, but no
   space after them.  In other words, write 'echo test >"$file"'
   instead of 'echo test> $file' or 'echo test > $file'.  Note that
   even though it is not required by POSIX to double-quote the
   redirection target in a variable (as shown above), our code does so
   because some versions of bash issue a warning without the quotes.
	(incorrect)
	cat hello > world < universe
	echo hello >$world
	(correct)
	cat hello >world <universe
	echo hello >"$world"
Show 15 quoted lines
> +		fi
>  		printf "\nViewing (%s/%s): '%s'\n" "$GIT_DIFF_PATH_COUNTER" \
>  			"$GIT_DIFF_PATH_TOTAL" "$MERGED"
>  		if use_ext_cmd
> @@ -102,4 +128,10 @@ else
>  	done
>  fi
>  
> +if test -f $GIT_DIFFTOOL_SKIP_TO_FILE &&
> +	test $GIT_DIFF_PATH_COUNTER -eq $GIT_DIFF_PATH_TOTAL
> +then
> +	rm $GIT_DIFFTOOL_SKIP_TO_FILE
> +
> +fi
>  exit 0
Wouldn't it be simpler to clear when we have reached at the end, i.e.
	if test "$GIT_DIFF_PATH_COUNTER" -eq "$GIT_DIFF_PATH_TOTAL"
	then
		rm -f "$GIT_DIFFTOOL_SKIP_TO_FILE"
	fi
Thanks.
Previous: Junio C HamanoNext: 胡哲宁
Message 3 of 37 in “git-difftool-helper.sh: learn a new way skip to save point”
  1. git-difftool-helper.sh: learn a new way skip to save point阿德烈 via GitGitGadget, Feb 7, 2021
  2. Junio C HamanoFeb 7, 2021
  3. Junio C HamanoFeb 7, 2021
  4. 胡哲宁Feb 8, 2021
  5. git-difftool-helper.sh: learn a new way go back to last save pointZheNing Hu via GitGitGadget, Feb 8, 2021
  6. Junio C HamanoFeb 8, 2021
  7. David AguilarFeb 8, 2021
  8. Junio C HamanoFeb 8, 2021
  9. 胡哲宁Feb 9, 2021
  10. 胡哲宁Feb 9, 2021
  11. difftool.c: learn a new way start from specified fileZheNing Hu via GitGitGadget, Feb 9, 2021
  12. Junio C HamanoFeb 9, 2021
  13. 胡哲宁Feb 10, 2021
  14. Junio C HamanoFeb 10, 2021
  15. Junio C HamanoFeb 10, 2021
  16. ZheNing HuFeb 14, 2021
  17. difftool.c: learn a new way start at specified fileZheNing Hu via GitGitGadget, Feb 14, 2021
  18. Junio C HamanoFeb 16, 2021
  19. 0/2 difftool.c: learn a new way start at specified fileZheNing Hu via GitGitGadget, Feb 16, 2021
  20. 1/2 diff: --{rotate,skip}-to=<path>Junio C Hamano via GitGitGadget, Feb 16, 2021
  21. 2/2 difftool.c: learn a new way start at specified fileZheNing Hu via GitGitGadget, Feb 16, 2021
  22. Junio C HamanoFeb 17, 2021
  23. ZheNing HuFeb 17, 2021
  24. Junio C HamanoFeb 16, 2021
  25. ZheNing HuFeb 17, 2021
  26. Denton LiuFeb 17, 2021
  27. ZheNing HuFeb 17, 2021
  28. Junio C HamanoFeb 17, 2021
  29. ZheNing HuFeb 18, 2021
  30. ZheNing HuFeb 18, 2021
  31. Junio C HamanoFeb 18, 2021
  32. ZheNing HuFeb 19, 2021
  33. Johannes SchindelinFeb 25, 2021
  34. Junio C HamanoFeb 25, 2021
  35. difftool.c: learn a new way start at specified fileZheNing Hu via GitGitGadget, Feb 19, 2021
  36. ZheNing HuFeb 22, 2021
  37. Junio C HamanoFeb 22, 2021

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.