git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH] difftool: always honor "command not found" exit code
  2016-08-13 10:36 ` John Keeping
@ 2016-08-13 11:30   ` John Keeping
  2016-08-13 22:59     ` David Aguilar
  2016-08-14  3:21     ` Junio C Hamano
  0 siblings, 2 replies; 8+ messages in thread
From: John Keeping @ 2016-08-13 11:30 UTC (permalink / raw)
  To: Tom Tanner (BLOOMBERG/ LONDON), David Aguilar; +Cc: git

At the moment difftool's "trust exit code" logic always suppresses the
exit status of the diff utility we invoke.  This is useful because we
don't want to exit just because diff returned "1" because the files
differ, but it's confusing if the shell returns an error because the
selected diff utility is not found.

POSIX specifies 127 as the exit status for "command not found" and 126
for "command found but is not executable" [1] and at least bash and dash
follow this specification, while diff utilities generally use "1" for
the exit status we want to ignore.

Handle 126 and 127 as special values, assuming that they always mean
that the command could not be executed.

[1] http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_08_02

Signed-off-by: John Keeping <john@keeping.me.uk>
---
On Sat, Aug 13, 2016 at 11:36:39AM +0100, John Keeping wrote:
> It would be nice if there was a way to differentiate between complete
> failure and just the diff tool exiting with a non-zero return status
> because the files differ, but I'm not sure whether we can do that
> reliably.  POSIX uses 127 and 126 as errors that mean the command didn't
> run [1] so it may be sensible to to treat those as special values.

Something like this perhaps?  I think this is probably safe, but it's
always possible that some diff utility does use 126 or 127 as a "normal"
exit status.  I'm not sure what we can do about that other than add a
"really, really don't trust the exit status" option!

 git-difftool--helper.sh | 18 ++++++++++++++----
 t/t7800-difftool.sh     |  6 ++++++
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/git-difftool--helper.sh b/git-difftool--helper.sh
index 84d6cc0..68877d4 100755
--- a/git-difftool--helper.sh
+++ b/git-difftool--helper.sh
@@ -86,11 +86,21 @@ else
 	do
 		launch_merge_tool "$1" "$2" "$5"
 		status=$?
-		if test "$status" != 0 &&
-			test "$GIT_DIFFTOOL_TRUST_EXIT_CODE" = true
-		then
+		case "$status" in
+		0)
+			: OK
+			;;
+		126|127)
+			# Command not found or not executable
 			exit $status
-		fi
+			;;
+		*)
+			if test "$GIT_DIFFTOOL_TRUST_EXIT_CODE" = true
+			then
+				exit $status
+			fi
+			;;
+		esac
 		shift 7
 	done
 fi
diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh
index 2974900..70a2de4 100755
--- a/t/t7800-difftool.sh
+++ b/t/t7800-difftool.sh
@@ -124,6 +124,12 @@ test_expect_success PERL 'difftool stops on error with --trust-exit-code' '
 	test_cmp expect actual
 '
 
+test_expect_success PERL 'difftool honors exit status if command not found' '
+	test_config difftool.nonexistent.cmd i-dont-exist &&
+	test_config difftool.trustExitCode false &&
+	test_must_fail git difftool -y -t nonexistent branch
+'
+
 test_expect_success PERL 'difftool honors --gui' '
 	difftool_test_setup &&
 	test_config merge.tool bogus-tool &&
-- 
2.9.2.639.g855ae9f


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] difftool: always honor "command not found" exit code
  2016-08-13 11:30   ` [PATCH] difftool: always honor "command not found" exit code John Keeping
@ 2016-08-13 22:59     ` David Aguilar
  2016-08-14  3:21     ` Junio C Hamano
  1 sibling, 0 replies; 8+ messages in thread
From: David Aguilar @ 2016-08-13 22:59 UTC (permalink / raw)
  To: John Keeping; +Cc: Tom Tanner (BLOOMBERG/ LONDON), git

On Sat, Aug 13, 2016 at 12:30:28PM +0100, John Keeping wrote:
> At the moment difftool's "trust exit code" logic always suppresses the
> exit status of the diff utility we invoke.  This is useful because we
> don't want to exit just because diff returned "1" because the files
> differ, but it's confusing if the shell returns an error because the
> selected diff utility is not found.
> 
> POSIX specifies 127 as the exit status for "command not found" and 126
> for "command found but is not executable" [1] and at least bash and dash
> follow this specification, while diff utilities generally use "1" for
> the exit status we want to ignore.
> 
> Handle 126 and 127 as special values, assuming that they always mean
> that the command could not be executed.
> 
> [1] http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_08_02
> 
> Signed-off-by: John Keeping <john@keeping.me.uk>

Looks good to me, thanks.

Acked-by: David Aguilar <davvid@gmail.com>

> ---
> On Sat, Aug 13, 2016 at 11:36:39AM +0100, John Keeping wrote:
> > It would be nice if there was a way to differentiate between complete
> > failure and just the diff tool exiting with a non-zero return status
> > because the files differ, but I'm not sure whether we can do that
> > reliably.  POSIX uses 127 and 126 as errors that mean the command didn't
> > run [1] so it may be sensible to to treat those as special values.
> 
> Something like this perhaps?  I think this is probably safe, but it's
> always possible that some diff utility does use 126 or 127 as a "normal"
> exit status.  I'm not sure what we can do about that oaaaather than add a
> "really, really don't trust the exit status" option!


We can always add a mechanism for tool-specific error codes
later if we ever end up needing it, but this seems sufficient.

cheers,
-- 
David

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] difftool: always honor "command not found" exit code
  2016-08-13 11:30   ` [PATCH] difftool: always honor "command not found" exit code John Keeping
  2016-08-13 22:59     ` David Aguilar
@ 2016-08-14  3:21     ` Junio C Hamano
  1 sibling, 0 replies; 8+ messages in thread
From: Junio C Hamano @ 2016-08-14  3:21 UTC (permalink / raw)
  To: John Keeping; +Cc: Tom Tanner (BLOOMBERG/ LONDON), David Aguilar, git

John Keeping <john@keeping.me.uk> writes:

> At the moment difftool's "trust exit code" logic always suppresses the
> exit status of the diff utility we invoke.  This is useful because we
> don't want to exit just because diff returned "1" because the files
> differ, but it's confusing if the shell returns an error because the
> selected diff utility is not found.
>
> POSIX specifies 127 as the exit status for "command not found" and 126
> for "command found but is not executable" [1] and at least bash and dash
> follow this specification, while diff utilities generally use "1" for
> the exit status we want to ignore.
>
> Handle 126 and 127 as special values, assuming that they always mean
> that the command could not be executed.

Sounds like a reasonable thing to do.  Will queue; thanks.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] difftool: always honor "command not found" exit code
@ 2016-08-15 10:38 Tom Tanner (BLOOMBERG/ LONDON)
  2016-08-15 20:21 ` Junio C Hamano
  0 siblings, 1 reply; 8+ messages in thread
From: Tom Tanner (BLOOMBERG/ LONDON) @ 2016-08-15 10:38 UTC (permalink / raw)
  To: gitster, john; +Cc: davvid, git

Would it be possible to also treat signals (128 and above) as 'special' values as well (as I've seen some merge tools self destruct like that from time to time)

----- Original Message -----
From: gitster@pobox.com
To: john@keeping.me.uk
Cc: Tom Tanner (BLOOMBERG/ LONDON), davvid@gmail.com, git@vger.kernel.org
At: 08/14/16 04:21:18

John Keeping <john@keeping.me.uk> writes:

> At the moment difftool's "trust exit code" logic always suppresses the
> exit status of the diff utility we invoke.  This is useful because we
> don't want to exit just because diff returned "1" because the files
> differ, but it's confusing if the shell returns an error because the
> selected diff utility is not found.
>
> POSIX specifies 127 as the exit status for "command not found" and 126
> for "command found but is not executable" [1] and at least bash and dash
> follow this specification, while diff utilities generally use "1" for
> the exit status we want to ignore.
>
> Handle 126 and 127 as special values, assuming that they always mean
> that the command could not be executed.

Sounds like a reasonable thing to do.  Will queue; thanks.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] difftool: always honor "command not found" exit code
  2016-08-15 10:38 [PATCH] difftool: always honor "command not found" exit code Tom Tanner (BLOOMBERG/ LONDON)
@ 2016-08-15 20:21 ` Junio C Hamano
  2016-08-15 21:35   ` John Keeping
  0 siblings, 1 reply; 8+ messages in thread
From: Junio C Hamano @ 2016-08-15 20:21 UTC (permalink / raw)
  To: Tom Tanner (BLOOMBERG/ LONDON); +Cc: john, davvid, git

"Tom Tanner (BLOOMBERG/ LONDON)" <ttanner2@bloomberg.net> writes:

> From: gitster@pobox.com
> To: john@keeping.me.uk
> Cc: Tom Tanner (BLOOMBERG/ LONDON), davvid@gmail.com, git@vger.kernel.org
> At: 08/14/16 04:21:18
>
> John Keeping <john@keeping.me.uk> writes:
> ...
>> POSIX specifies 127 as the exit status for "command not found" and 126
>> for "command found but is not executable" [1] and at least bash and dash
>> follow this specification, while diff utilities generally use "1" for
>> the exit status we want to ignore.
>>
>> Handle 126 and 127 as special values, assuming that they always mean
>> that the command could not be executed.
>
> Sounds like a reasonable thing to do.  Will queue; thanks.

> Would it be possible to also treat signals (128 and above) as
> 'special' values as well (as I've seen some merge tools self
> destruct like that from time to time)

Certainly, it feels safer to notice an unusual exit status code and
error out to force the user to take notice, but that reasoning
assumes that "128 and above" are noteworthy exceptions.

I do not have a strong opinion on that part.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] difftool: always honor "command not found" exit code
  2016-08-15 20:21 ` Junio C Hamano
@ 2016-08-15 21:35   ` John Keeping
  2016-08-15 21:54     ` [PATCH v2] difftool: always honor fatal error exit codes John Keeping
  0 siblings, 1 reply; 8+ messages in thread
From: John Keeping @ 2016-08-15 21:35 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Tom Tanner (BLOOMBERG/ LONDON), davvid, git

On Mon, Aug 15, 2016 at 01:21:22PM -0700, Junio C Hamano wrote:
> "Tom Tanner (BLOOMBERG/ LONDON)" <ttanner2@bloomberg.net> writes:
> 
> > From: gitster@pobox.com
> > To: john@keeping.me.uk
> > Cc: Tom Tanner (BLOOMBERG/ LONDON), davvid@gmail.com, git@vger.kernel.org
> > At: 08/14/16 04:21:18
> >
> > John Keeping <john@keeping.me.uk> writes:
> > ...
> >> POSIX specifies 127 as the exit status for "command not found" and 126
> >> for "command found but is not executable" [1] and at least bash and dash
> >> follow this specification, while diff utilities generally use "1" for
> >> the exit status we want to ignore.
> >>
> >> Handle 126 and 127 as special values, assuming that they always mean
> >> that the command could not be executed.
> >
> > Sounds like a reasonable thing to do.  Will queue; thanks.
> 
> > Would it be possible to also treat signals (128 and above) as
> > 'special' values as well (as I've seen some merge tools self
> > destruct like that from time to time)
> 
> Certainly, it feels safer to notice an unusual exit status code and
> error out to force the user to take notice, but that reasoning
> assumes that "128 and above" are noteworthy exceptions.

Reading further in POSIX:

	The exit status of a command that terminated because it received
	a signal shall be reported as greater than 128.

I think if we accept the argument above about diff utilities generally
using low numbers for the status values we're ignoring intentionally,
then we can just treat any value above 125 as a fatal error.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2] difftool: always honor fatal error exit codes
  2016-08-15 21:35   ` John Keeping
@ 2016-08-15 21:54     ` John Keeping
  2016-08-15 22:26       ` Junio C Hamano
  0 siblings, 1 reply; 8+ messages in thread
From: John Keeping @ 2016-08-15 21:54 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Tom Tanner (BLOOMBERG/ LONDON), davvid, git

At the moment difftool's "trust exit code" logic always suppresses the
exit status of the diff utility we invoke.  This is useful because we
don't want to exit just because diff returned "1" because the files
differ, but it's confusing if the shell returns an error because the
selected diff utility is not found.

POSIX specifies 127 as the exit status for "command not found", 126 for
"command found but is not executable" and values greater than 128 if the
command terminated because it received a signal [1] and at least bash
and dash follow this specification, while diff utilities generally use
"1" for the exit status we want to ignore.

Handle any value of 126 or greater as a special value indicating that
some form of fatal error occurred.

[1] http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_08_02

Signed-off-by: John Keeping <john@keeping.me.uk>
---
On Mon, Aug 15, 2016 at 10:35:26PM +0100, John Keeping wrote:
> On Mon, Aug 15, 2016 at 01:21:22PM -0700, Junio C Hamano wrote:
> > "Tom Tanner (BLOOMBERG/ LONDON)" <ttanner2@bloomberg.net> writes:
> > 
> > > From: gitster@pobox.com
> > > To: john@keeping.me.uk
> > > Cc: Tom Tanner (BLOOMBERG/ LONDON), davvid@gmail.com, git@vger.kernel.org
> > > At: 08/14/16 04:21:18
> > >
> > > John Keeping <john@keeping.me.uk> writes:
> > > ...
> > >> POSIX specifies 127 as the exit status for "command not found" and 126
> > >> for "command found but is not executable" [1] and at least bash and dash
> > >> follow this specification, while diff utilities generally use "1" for
> > >> the exit status we want to ignore.
> > >>
> > >> Handle 126 and 127 as special values, assuming that they always mean
> > >> that the command could not be executed.
> > >
> > > Sounds like a reasonable thing to do.  Will queue; thanks.
> > 
> > > Would it be possible to also treat signals (128 and above) as
> > > 'special' values as well (as I've seen some merge tools self
> > > destruct like that from time to time)
> > 
> > Certainly, it feels safer to notice an unusual exit status code and
> > error out to force the user to take notice, but that reasoning
> > assumes that "128 and above" are noteworthy exceptions.
> 
> Reading further in POSIX:
> 
> 	The exit status of a command that terminated because it received
> 	a signal shall be reported as greater than 128.
> 
> I think if we accept the argument above about diff utilities generally
> using low numbers for the status values we're ignoring intentionally,
> then we can just treat any value above 125 as a fatal error.

Here's what that looks like.

 git-difftool--helper.sh | 7 +++++++
 t/t7800-difftool.sh     | 6 ++++++
 2 files changed, 13 insertions(+)

diff --git a/git-difftool--helper.sh b/git-difftool--helper.sh
index 84d6cc0..7bfb673 100755
--- a/git-difftool--helper.sh
+++ b/git-difftool--helper.sh
@@ -86,6 +86,13 @@ else
 	do
 		launch_merge_tool "$1" "$2" "$5"
 		status=$?
+		if test $status -ge 126
+		then
+			# Command not found (127), not executable (126) or
+			# exited via a signal (>= 128).
+			exit $status
+		fi
+
 		if test "$status" != 0 &&
 			test "$GIT_DIFFTOOL_TRUST_EXIT_CODE" = true
 		then
diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh
index 2974900..70a2de4 100755
--- a/t/t7800-difftool.sh
+++ b/t/t7800-difftool.sh
@@ -124,6 +124,12 @@ test_expect_success PERL 'difftool stops on error with --trust-exit-code' '
 	test_cmp expect actual
 '
 
+test_expect_success PERL 'difftool honors exit status if command not found' '
+	test_config difftool.nonexistent.cmd i-dont-exist &&
+	test_config difftool.trustExitCode false &&
+	test_must_fail git difftool -y -t nonexistent branch
+'
+
 test_expect_success PERL 'difftool honors --gui' '
 	difftool_test_setup &&
 	test_config merge.tool bogus-tool &&
-- 
2.9.3.728.g30b24b4


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2] difftool: always honor fatal error exit codes
  2016-08-15 21:54     ` [PATCH v2] difftool: always honor fatal error exit codes John Keeping
@ 2016-08-15 22:26       ` Junio C Hamano
  0 siblings, 0 replies; 8+ messages in thread
From: Junio C Hamano @ 2016-08-15 22:26 UTC (permalink / raw)
  To: John Keeping; +Cc: Tom Tanner (BLOOMBERG/ LONDON), davvid, git

John Keeping <john@keeping.me.uk> writes:

> Here's what that looks like.

Sounds good.  It feels a bit funny to see that new mentions of
$status are unquoted (which is totally valid because we know it has
$? that cannot be anything other than a short decimal integer),
while the one in the post-context quotes it, but that's not a huge
issue.

Will queue.  Thanks.

>  git-difftool--helper.sh | 7 +++++++
>  t/t7800-difftool.sh     | 6 ++++++
>  2 files changed, 13 insertions(+)
>
> diff --git a/git-difftool--helper.sh b/git-difftool--helper.sh
> index 84d6cc0..7bfb673 100755
> --- a/git-difftool--helper.sh
> +++ b/git-difftool--helper.sh
> @@ -86,6 +86,13 @@ else
>  	do
>  		launch_merge_tool "$1" "$2" "$5"
>  		status=$?
> +		if test $status -ge 126
> +		then
> +			# Command not found (127), not executable (126) or
> +			# exited via a signal (>= 128).
> +			exit $status
> +		fi
> +
>  		if test "$status" != 0 &&
>  			test "$GIT_DIFFTOOL_TRUST_EXIT_CODE" = true
>  		then
> diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh
> index 2974900..70a2de4 100755
> --- a/t/t7800-difftool.sh
> +++ b/t/t7800-difftool.sh
> @@ -124,6 +124,12 @@ test_expect_success PERL 'difftool stops on error with --trust-exit-code' '
>  	test_cmp expect actual
>  '
>  
> +test_expect_success PERL 'difftool honors exit status if command not found' '
> +	test_config difftool.nonexistent.cmd i-dont-exist &&
> +	test_config difftool.trustExitCode false &&
> +	test_must_fail git difftool -y -t nonexistent branch
> +'
> +
>  test_expect_success PERL 'difftool honors --gui' '
>  	difftool_test_setup &&
>  	test_config merge.tool bogus-tool &&

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2016-08-15 22:26 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-15 10:38 [PATCH] difftool: always honor "command not found" exit code Tom Tanner (BLOOMBERG/ LONDON)
2016-08-15 20:21 ` Junio C Hamano
2016-08-15 21:35   ` John Keeping
2016-08-15 21:54     ` [PATCH v2] difftool: always honor fatal error exit codes John Keeping
2016-08-15 22:26       ` Junio C Hamano
  -- strict thread matches above, loose matches on Subject: below --
2016-08-12  7:13 git difftool and git mergetool aren't returning errors when the tool has issues Tom Tanner (BLOOMBERG/ LONDON)
2016-08-13 10:36 ` John Keeping
2016-08-13 11:30   ` [PATCH] difftool: always honor "command not found" exit code John Keeping
2016-08-13 22:59     ` David Aguilar
2016-08-14  3:21     ` Junio C Hamano

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).