diff mbox series

[v2,7/7] var(win32): do report the GIT_SHELL_PATH that is actually used

Message ID 8bfd23cfa00c351ffdcc25bd29f3b84089544a56.1720739496.git.gitgitgadget@gmail.com (mailing list archive)
State Superseded
Headers show
Series var(win32): do report the GIT_SHELL_PATH that is actually used | expand

Commit Message

Johannes Schindelin July 11, 2024, 11:11 p.m. UTC
From: Johannes Schindelin <johannes.schindelin@gmx.de>

On Windows, Unix-like paths like `/bin/sh` make very little sense. In
the best case, they simply don't work, in the worst case they are
misinterpreted as absolute paths that are relative to the drive
associated with the current directory.

To that end, Git does not actually use the path `/bin/sh` that is
recorded e.g. when `run_command()` is called with a Unix shell
command-line. Instead, as of 776297548e (Do not use SHELL_PATH from
build system in prepare_shell_cmd on Windows, 2012-04-17), it
re-interprets `/bin/sh` as "look up `sh` on the `PATH` and use the
result instead".

This is the logic users expect to be followed when running `git var
GIT_SHELL_PATH`.

However, when 1e65721227 (var: add support for listing the shell,
2023-06-27) introduced support for `git var GIT_SHELL_PATH`, Windows was
not special-cased as above, which is why it outputs `/bin/sh` even
though that disagrees with what Git actually uses.

Let's fix this by using the exact same logic as `prepare_shell_cmd()`,
adjusting the Windows-specific `git var GIT_SHELL_PATH` test case to
verify that it actually finds a working executable.

Reported-by: Phillip Wood <phillip.wood123@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 builtin/var.c      | 3 ++-
 t/t0007-git-var.sh | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

Comments

Junio C Hamano July 12, 2024, 3:35 p.m. UTC | #1
"Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
writes:

> From: Johannes Schindelin <johannes.schindelin@gmx.de>
>
> On Windows, Unix-like paths like `/bin/sh` make very little sense. In
> the best case, they simply don't work, in the worst case they are
> misinterpreted as absolute paths that are relative to the drive
> associated with the current directory.
> To that end, ...

This does not quite explain why a hardcoded full path does not make
sense, though.  If you do not want "relative to the current drive",
you can even hardcode the path including the drive letter and now it
no longer falls into that "worst case" because there is no way to
misinterpret it as such.  I think the real reason is that the port's
"relocatable" nature does not mix well with the "let's make sure we
know what we use exactly by deciding the paths to various tools at
compile time" mentality.  So if I were rerolling this I would say

	Git ported to Windows expect to be installed at user-chosen
	places, which means hardcoded paths to tools decided at
	compile time are bad fit.

or something.

But it does not matter if the stated reason is to use the "find 'sh'
that is on PATH" approach was taken tells the whole story or not.
The important thing is that we do ...

> Git does not actually use the path `/bin/sh` that is
> recorded e.g. when `run_command()` is called with a Unix shell
> command-line. Instead, as of 776297548e (Do not use SHELL_PATH from
> build system in prepare_shell_cmd on Windows, 2012-04-17), it
> re-interprets `/bin/sh` as "look up `sh` on the `PATH` and use the
> result instead".

... this.  And with the design constraints that it has to be
installable anywhere and cannot rely on compile-time determined
hardcoded paths, the above design decision is a very valid one.

> This is the logic users expect to be followed when running `git var
> GIT_SHELL_PATH`.

And matching `git var GIT_SHELL_PATH` to what the code path does
make sense.

> diff --git a/builtin/var.c b/builtin/var.c
> index 5dc384810c0..e30ff45be1c 100644
> --- a/builtin/var.c
> +++ b/builtin/var.c
> @@ -12,6 +12,7 @@
>  #include "refs.h"
>  #include "path.h"
>  #include "strbuf.h"
> +#include "run-command.h"
>  
>  static const char var_usage[] = "git var (-l | <variable>)";
>  
> @@ -51,7 +52,7 @@ static char *default_branch(int ident_flag UNUSED)
>  
>  static char *shell_path(int ident_flag UNUSED)
>  {
> -	return xstrdup(SHELL_PATH);
> +	return git_shell_path();
>  }

Simple and clear.  Nicely concluded.

Thanks.  Will queue.
diff mbox series

Patch

diff --git a/builtin/var.c b/builtin/var.c
index 5dc384810c0..e30ff45be1c 100644
--- a/builtin/var.c
+++ b/builtin/var.c
@@ -12,6 +12,7 @@ 
 #include "refs.h"
 #include "path.h"
 #include "strbuf.h"
+#include "run-command.h"
 
 static const char var_usage[] = "git var (-l | <variable>)";
 
@@ -51,7 +52,7 @@  static char *default_branch(int ident_flag UNUSED)
 
 static char *shell_path(int ident_flag UNUSED)
 {
-	return xstrdup(SHELL_PATH);
+	return git_shell_path();
 }
 
 static char *git_attr_val_system(int ident_flag UNUSED)
diff --git a/t/t0007-git-var.sh b/t/t0007-git-var.sh
index ff4fd9348cc..9fc58823873 100755
--- a/t/t0007-git-var.sh
+++ b/t/t0007-git-var.sh
@@ -157,7 +157,7 @@  test_expect_success POSIXPERM 'GIT_SHELL_PATH points to a valid executable' '
 test_expect_success MINGW 'GIT_SHELL_PATH points to a suitable shell' '
 	shellpath=$(git var GIT_SHELL_PATH) &&
 	case "$shellpath" in
-	*sh) ;;
+	[A-Z]:/*/sh.exe) test -f "$shellpath";;
 	*) return 1;;
 	esac
 '