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

Re: [PATCH 2/3] mergetool: dissect strings with shell variable magic instead of `expr`

From
Junio C Hamano <gitster@pobox.com>
Date
Jun 10, 2019, 17:17 UTC
Message-ID
<xmqqblz5nyve.fsf@gitster-ct.c.googlers.com>
In-Reply-To
<2a33ca20af41d68a5bb4e2cf1e5ae32fddf2796c.1560152205.git.j6t@kdbg.org>
Johannes Sixt <j6t@kdbg.org> writes:
> git-mergetool spawns an enormous amount of processes. For this reason,
> the test script, t7610, is exceptionally slow, in particular, on
> Windows. Most of the processes are invocations of git, but there are
> also some that can be replaced with shell builtins. Do so with `expr`.

I see these as improvements independent of whatever test may or may not be slow ;-) s/^.*/but there are/There are/. Thanks for working on it.

>  checkout_staged_file () {
> -	tmpfile=$(expr \
> -		"$(git checkout-index --temp --stage="$1" "$2" 2>/dev/null)" \
> -		: '\([^	]*\)	')

So this wants to grab leading non-HT substring that comes before an HT; we are trying to grab the name of the temorary picked by the checkout-index command, the output is ".merge_file_XXXXXX" followed by HT followed by the original filename "$2".

> +	tmpfile="$(git checkout-index --temp --stage="$1" "$2" 2>/dev/null)" &&
> +	tmpfile=${tmpfile%%'	'*}

And this obviously is an equivalent, at least in the successful case. The ".merge_file_XXXXXX" temporary filename never has HT in it, and we are stripping everything after the first HT.

And this rewrite makes the error behaviour much better. In the original, the exit code checked in the next "if test $? -eq 0" is that of "expr" (i.e. does the pattern match?); with this version, we are looking at the exit status of the checkout-index command.

Good.
Show 13 quoted lines
> @@ -255,13 +254,16 @@ merge_file () {
>  		return 1
>  	fi
>  
> -	if BASE=$(expr "$MERGED" : '\(.*\)\.[^/]*$')
> -	then
> -		ext=$(expr "$MERGED" : '.*\(\.[^/]*\)$')
> -	else
> +	# extract file extension from the last path component
> +	case "${MERGED##*/}" in
> +	*.*)
> +		ext=.${MERGED##*.}
> +		BASE=${MERGED%"$ext"}

This rewrite can potentially change the behaviour, when $ext has glob metacharacters. Wouldn't BASE=${MERGED%.*} be more faithful conversion?

Show 12 quoted lines
> +		;;
> +	*)
>  		BASE=$MERGED
>  		ext=
> -	fi
> +	esac
> @@ -406,7 +408,7 @@ main () {
>  		-t|--tool*)
>  			case "$#,$1" in
>  			*,*=*)
> -				merge_tool=$(expr "z$1" : 'z-[^=]*=\(.*\)')
> +				merge_tool=${1#*=}

OK, we strip leading substring before the first '=' out of "$1" and the case/esac ensures that there is such an equal '=' sign in "$1", so the rewrite is correct.

Looks good.  Thanks.
Previous: Johannes SixtNext: Johannes Sixt
Message 9 of 18 in “Reduce number of processes spawned by git-mergetool”
  1. 0/3 Reduce number of processes spawned by git-mergetoolJohannes Sixt, Jun 10, 2019
  2. 1/3 t7610-mergetool: do not place pipelines headed by `yes` in subshellsJohannes Sixt, Jun 10, 2019
  3. SZEDER GáborJun 10, 2019
  4. Junio C HamanoJun 10, 2019
  5. SZEDER GáborJun 10, 2019
  6. Johannes SchindelinJun 10, 2019
  7. SZEDER GáborJun 10, 2019
  8. 2/3 mergetool: dissect strings with shell variable magic instead of `expr`Johannes Sixt, Jun 10, 2019
  9. Junio C HamanoJun 10, 2019
  10. Johannes SixtJun 10, 2019
  11. 3/3 mergetool: use shell variable magic instead of `awk`Johannes Sixt, Jun 10, 2019
  12. Junio C HamanoJun 10, 2019
  13. Johannes SixtJun 10, 2019
  14. 0/4 Reduce number of processes spawned by git-mergetoolJohannes Sixt, Jun 12, 2019
  15. 3/4 mergetool: dissect strings with shell variable magic instead of `expr`Johannes Sixt, Jun 12, 2019
  16. 4/4 mergetool: use shell variable magic instead of `awk`Johannes Sixt, Jun 12, 2019
  17. 1/4 t7610-mergetool: do not place pipelines headed by `yes` in subshellsJohannes Sixt, Jun 12, 2019
  18. 2/4 t7610-mergetool: use test_cmp instead of test $(cat file) = $txtJohannes Sixt, Jun 12, 2019

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.