There is an ongoing outage on the primary CPAN mirror. It is possible to work around the issue by using MetaCPAN as a mirror.

NAME

run-git-hooks - Secure Git Server with more granular hooks capabilities than default git.

SYNOPSIS

Standard Method:
With SHELL=/bin/bash, use the following format in ~/.ssh/authorized_keys:
command="~/git-server/gitserver KEY=user1" ssh-ed25519 AAAA_OAX+blah_pub__ user1@workstation

 -- OR --

Advanced Method:
Set SHELL=/path/to/git-server (in /etc/passwd) and
Set "PermitUserEnvironment yes" (in /etc/ssh/sshd_config)
Then use the following format in ~/.ssh/authorized_keys:
environment="KEY=user1" ssh-ed25519 AAAA_OAX+blah_pub__ user1@workstation

ENV

You can set as many %ENV variables as you want within the authorized_keys configuration.

KEY

KEY has a special meaning to define a word for the associated user and will be used for ACL rules.

INSTALL

This can be used with any existing git repositories or as a drop-in replacement for git-shell or you can create a fresh repo on the git host:

git init --bare project

Then add whatever hooks you want:

vi project/hooks/pre-read
chmod 755 project/hooks/pre-read

Each hook can read the ENV settings defined in authorized_keys.

HOOKS

All the normal git hooks will continue to work, plus the following:

hooks/pre-read

Executed before any repository read operation, such as "git clone" or "git pull" or "git fetch" or "git ls-remote". The Environment variable GIT_PRE_EXIT_STATUS will be set to the exit status of this pre-read. If this exit status is exactly zero, then the git read operation will be executed. Otherwise, the git read operation will be aborted.

hooks/post-read

If the Environment variable GIT_PRE_EXIT_STATUS is defined, then post-read will know that the pre-read ran, and its exit status will be available in this variable. If it does not exist, then pre-read never ran. If the Environment variable GIT_EXIT_STATUS is defined, then post-read will know that the git operation ran, and its exit status will be this variable. If it does not exist, then the git operation never ran.

This post-read hook will always be executed regardless of the exit statuses of pre-read or the git operation. The post-read hook is meant primarily for notification and cannot affect the outcome of the git operation.

hooks/pre-write

Executed before any repository modification attempt, such as "git push". Unlike the hooks/update hook, this hooks/pre-write will always be triggered for write operations, even if there are no actual changes that need to be made. The Environment variable GIT_PRE_EXIT_STATUS will be set to the exit status of this pre-write. If this exit status is exactly zero, then the git write operation will be executed. Otherwise, the git write operation will be aborted.

hooks/post-write

If the Environment variable GIT_PRE_EXIT_STATUS is defined, then post-write will know that the pre-write ran, and its exit status will be available in this variable. If it does not exist, then pre-write never ran. If the Environment variable GIT_EXIT_STATUS is defined, then post-write will know that the git operation ran, and its exit status will be this variable. If it does not exist, then the git operation never ran.

This post-write hook will always be executed regardless of the exit statuses of pre-write or the git operation. The post-write hook is meant primarily for notification and cannot affect the outcome of the git operation.

hooks/git-shell

If this exists, then it will be executed instead of the real git-shell program.

SEE ALSO

Similar functionality to the following:

gitlab-shell, gitolite, git-shell

AUTHOR

Rob Brown <bbb@cpan.org>

COPYRIGHT AND LICENSE

Copyright 2015-2025 by Rob Brown <bbb@cpan.org>

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.