Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

git-gui - re-enable use of hook scripts #100

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

gitster
Copy link
Contributor

@gitster gitster commented Sep 17, 2023

Earlier, commit aae9560 introduced search in $PATH to find executables before running them, avoiding an issue where on Windows a same named file in the current directory can be executed in preference to anything in a directory in $PATH. This search is intended to find an absolute path for a bare executable ( e.g, a function "foo") by finding the first instance of "foo" in a directory given in $PATH, and this search works correctly. The search is explicitly avoided for an executable named with an absolute path (e.g., /bin/sh), and that works as well.

Unfortunately, the search is also applied to commands named with a relative path. A hook script (or executable) $HOOK is usually located relative to the project directory as .git/hooks/$HOOK. The search for this will generally fail as that relative path will (probably) not exist on any directory in $PATH. This means that git hooks in general now fail to run. Considerable mayhem could occur should a directory on $PATH be git controlled. If such a directory includes .git/hooks/$HOOK, that repository's $HOOK will be substituted for the one in the current project, with unknown consequences.

This lookup failure also occurs in worktrees linked to a remote .git directory using git-new-workdir. However, a worktree using a .git file pointing to a separate git directory apparently avoids this: in that case the hook command is resolved to an absolute path before being passed down to the code introduced in aae9560.

Fix this by replacing the test for an "absolute" pathname to a check for a command name having more than one pathname component. This limits the search and absolute pathname resolution to bare commands. The new test uses tcl's "file split" command. Experiments on Linux and Windows, using tclsh, show that command names with relative and absolute paths always give at least two components, while a bare command gives only one.

  Linux:   puts [file split {foo}]       ==>  foo
  Linux:   puts [file split {/foo}]      ==>  / foo
  Linux:   puts [file split {.git/foo}]  ==> .git foo
  Windows: puts [file split {foo}]       ==>  foo
  Windows: puts [file split {c:\foo}]    ==>  c:/ foo
  Windows: puts [file split {.git\foo}]  ==> .git foo

The above results show the new test limits search and replacement to bare commands on both Linux and Windows.

Earlier, commit aae9560 introduced search in $PATH to find executables
before running them, avoiding an issue where on Windows a same named
file in the current directory can be executed in preference to anything
in a directory in $PATH. This search is intended to find an absolute
path for a bare executable ( e.g, a function "foo") by finding the first
instance of "foo" in a directory given in $PATH, and this search works
correctly.  The search is explicitly avoided for an executable named
with an absolute path (e.g., /bin/sh), and that works as well.

Unfortunately, the search is also applied to commands named with a
relative path. A hook script (or executable) $HOOK is usually located
relative to the project directory as .git/hooks/$HOOK. The search for
this will generally fail as that relative path will (probably) not exist
on any directory in $PATH. This means that git hooks in general now fail
to run. Considerable mayhem could occur should a directory on $PATH be
git controlled. If such a directory includes .git/hooks/$HOOK, that
repository's $HOOK will be substituted for the one in the current
project, with unknown consequences.

This lookup failure also occurs in worktrees linked to a remote .git
directory using git-new-workdir. However, a worktree using a .git file
pointing to a separate git directory apparently avoids this: in that
case the hook command is resolved to an absolute path before being
passed down to the code introduced in aae9560.

Fix this by replacing the test for an "absolute" pathname to a check for
a command name having more than one pathname component. This limits the
search and absolute pathname resolution to bare commands. The new test
uses tcl's "file split" command. Experiments on Linux and Windows, using
tclsh, show that command names with relative and absolute paths always
give at least two components, while a bare command gives only one.

	  Linux:   puts [file split {foo}]       ==>  foo
	  Linux:   puts [file split {/foo}]      ==>  / foo
	  Linux:   puts [file split {.git/foo}]  ==> .git foo
	  Windows: puts [file split {foo}]       ==>  foo
	  Windows: puts [file split {c:\foo}]    ==>  c:/ foo
	  Windows: puts [file split {.git\foo}]  ==> .git foo

The above results show the new test limits search and replacement
to bare commands on both Linux and Windows.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
@gitster
Copy link
Contributor Author

gitster commented Sep 17, 2023

I am planning to merge this directly to my tree (via -Xsubtree=git-gui/ option), and thought that it would make it easier to maintain your tree up to date by simply fast-forwarding to it (the commit is built directly on top of your 'master').

Thanks.

git-gui currently runs some hooks directly using its own code written
before 2010, long predating git v2.9 that added the core.hooksPath
configuration to override the assumed location at $GIT_DIR/hooks.  Thus,
git-gui looks for and runs hooks including prepare-commit-msg,
commit-msg, pre-commit, post-commit, and post-checkout from
$GIT_DIR/hooks, regardless of configuration. Commands (e.g., git-merge)
that git-gui invokes directly do honor core.hooksPath, meaning the
overall behaviour is inconsistent.

Furthermore, since v2.36 git exposes its hook execution machinery via
`git-hook run`, eliminating the need for others to maintain code
duplicating that functionality.  Using git-hook will both fix git-gui's
current issues on hook configuration and (presumably) reduce the
maintenance burden going forward. So, teach git-gui to use git-hook.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
@prati0100
Copy link
Owner

Hi @gitster

I fetched your tree just now and I see that you have not yet merged it. My master branch has moved since you opened this PR. If it works for you, I can apply the patch and send you a pull request today. I am looking at it now.

@gitster
Copy link
Contributor Author

gitster commented Sep 20, 2023

My copy already has these in 'next', but they are identical so it is not a huge deal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants