hooks: use _global/hooks directly or indirectly
commitfd1aff907f596aaea7686d05f9f809bd04e764ee
authorKyle J. McKay <mackyle@gmail.com>
Sat, 23 Dec 2017 01:40:41 +0000 (22 17:40 -0800)
committerKyle J. McKay <mackyle@gmail.com>
Sat, 23 Dec 2017 01:40:41 +0000 (22 17:40 -0800)
tree2890fa56b03718a793583dde310e59d0e25dd90d
parentc5f7bc7161a765f9ff869b7d64a57dab002411c0
hooks: use _global/hooks directly or indirectly

Starting with Git 2.9.0, if the config item core.hooksPath has been
set then the repository's own hooks directory is completely ignored
unless that new config item happens to point there.

The implementation of this config item is an abomination.

There's simply no way to restore the original behavior once it's
been set in any of the possible config areas (system, global, XDG,
repository, environment or command line).

It does support relative paths and one might mistakenly believe
that setting "core.hooksPath = hooks" in the repository's config
file would restore the default behavior.  One would be horribly
mistaken in that belief.

The location that a relative core.hooksPath path is relative to
varies depending on the situation (pushing into a linked working
tree is most especially fun with regard to that).

What would an empty path do, you say?  That's the worst of all.
"core.hooksPath=" is the same as "core.hooksPath=/".  Bad bad bad!

The only way to alleviate the horrible pain of the core.hooksPath
implementation abomination is to always set core.hooksPath in the
repository's config file to an absolute path.

Fortunately we have just recently started installing all of Girocco's
hooks to a well-known absolute path that's accessible both in and
out of the sshd chroot at the same absolute path.  :)

Additionally, the exact same hook scripts are used for both the real
repository and the personal mob push "pseudo" repository.  :)
(This matters because the "pseudo" repository's config file is just
a symbolic link to the real repository's config file.)

One final issue remains and that is compatibility with pre-2.9.0
versions of Git.  This requires hooks to remain in the repository's
hooks directory in order for them to be run.

Solve all these issues by setting core.hooksPath to point to the
new "$Girocco::Config::reporoot/_global/hooks" directory and
additionally install symbolic links in each repository's hooks
subdirectory for each hook that link to the same-named hook in the
_global/hooks directory.

The core.hooksPath config value is set in the repository's config
file thereby overriding any system, global or XDG setting for such.
It's set to an absolute path thereby mitigating the core.hooksPath
implementation abomination.

Furthermore, earlier versions of Git will still run the hooks in
the _global/hooks directory even though they do not understand the
core.hooksPath config item courtesy of the symbolic links that are
installed into each repository's hooks subdirectory.

As a result of these changes, the update-all-hooks script becomes
mostly superfluous other than to make sure the symlinks are in
place for older Git versions to follow.

Obviously update-all-projects must be run at least once after this
change to actually switch all the projects over to using _global/hooks.

The other nice advantage of this approach is that the hook scripts
are always immediately up-to-date for all projects after running
"make install".

Signed-off-by: Kyle J. McKay <mackyle@gmail.com>
Girocco/Project.pm
toolbox/update-all-config.pl
toolbox/update-all-hooks.sh