41
votes

Not sure if this is possible in git (I haven't found it but I may be using the wrong vocabulary in my searches), but it be would useful to be able to modify and enable hooks as the defaults for all new repositories (at the time of creation I mean) so these don't have to be customized each time a new repository is created. It seems the easy way to do this is write a wrapper that sets my hooks and chmods them when I create a new repository, but if there's a way built into git I would rather use that instead of having unnecessary wrapper scripts however little lying around.


Clarification copied up from a comment to a now-deleted answer:

My question is whether the default behavior for ALL new repositories can be changed, so they don't need to be customized in the same way each time for each new repository. The easy answer is write a wrapper for creating and customizing the repos (it generates the hook scripts and chmods them), but it seems like this default behavior should also be customizable without having to do that.

4
Don't forget that answers can be deleted - it is often better to clarify your question than to add comments to answers.Jonathan Leffler
With git 2.9 (June 2016), you will have a new config to define a central place for hooks for all repos: core.hooksPath. See my answer belowVonC

4 Answers

39
votes

From the git-init man page (also works with git-clone if you are cloning an existing repo instead of creating a new one from scratch):

       --template=<template_directory>
           Provide the directory from which templates will be used. The
           default template directory is /usr/share/git-core/templates.

           When specified, <template_directory> is used as the source of the
           template files rather than the default. The template files include
           some directory structure, some suggested "exclude patterns", and
           copies of non-executing "hook" files. The suggested patterns and
           hook files are all modifiable and extensible.

You can modify the system-wide template directory (which defaults to /usr/share/git-core/templates, but may be in a different location on your machine), you can supply --template=<template_directory> on the command line when you create or clone the repo, or you can configure the default template directory in your config file:

[init]
     templatedir = /path/to/templates
35
votes

With git 2.9, you have a new option made for centralizing hooks: core.hooksPath

See commit 867ad08, commit de0824e, commit bf7d977, commit 49fa52f (04 May 2016) by Ævar Arnfjörð Bjarmason (avar).
(Merged by Junio C Hamano -- gitster -- in commit 6675f50, 17 May 2016)

The git config documentation now includes:

core.hooksPath

By default Git will look for your hooks in the '$GIT_DIR/hooks' directory.
Set this to different path, e.g. '/etc/git/hooks', and Git will try to find your hooks in that directory, e.g. '/etc/git/hooks/pre-receive' instead of in '$GIT_DIR/hooks/pre-receive'.

The path can be either absolute or relative. A relative path is taken as relative to the directory where the hooks are run

This configuration variable is useful in cases where you'd like to centrally configure your Git hooks instead of configuring them on a per-repository basis, or as a more flexible and centralized alternative to having an init.templateDir where you've changed default hooks.

The author of this pathc (Ævar Arnfjörð Bjarmason avar) adds in his commit:

I plan on using this on a centralized Git server where users can create arbitrary repositories under /gitroot, but I'd like to manage all the hooks that should be run centrally via a unified dispatch mechanism.


Git 2.10 uses that new setting in git rev-parse --git-path hooks/<hook>

See commit 9445b49 (16 Aug 2016) by Johannes Schindelin (dscho).
(Merged by Junio C Hamano -- gitster -- in commit d05d0e9, 19 Aug 2016)

rev-parse: respect core.hooksPath in --git-path

The idea of the --git-path option is not only to avoid having to prefix paths with the output of --git-dir all the time, but also to respect overrides for specific common paths inside the .git directory
(e.g. git rev-parse --git-path objects will report the value of the environment variable GIT_OBJECT_DIRECTORY, if set).

When introducing the core.hooksPath setting, we forgot to adjust git_path() accordingly. This patch fixes that.

4
votes

With git 1.6.5.3 (and some earlier versions), you get sample hooks delivered in your .git/hooks directory:

$ ls .git/hooks
applypatch-msg.sample     post-update.sample        prepare-commit-msg.sample
commit-msg.sample         pre-applypatch.sample     update.sample
post-commit.sample        pre-commit.sample
post-receive.sample       pre-rebase.sample
$ 

They are all executable on my system. To make use of one of the hooks, either copy or rename the file removing the '.sample' suffix. Edit it as appropriate to suit your requirements.


Addressing the question in a comment - to change the default sample hooks installed, you need to find the directory where git is installed. On my machine, that is $HOME/git - so the binary is in $HOME/git/bin/git. Then the directory containing the sample hooks is:

$HOME/git/share/git-core/templates/hooks

If you edit those templates (be careful), then that is what will be copied to new git repositories. They'll still be samples, but they'll be your samples.

I've not experimented with creating a non-sample file in the directory; it might or might not be copied. Be wary of changing the defaults, though - when you next upgrade, you'll have to redo the changes.

0
votes

For MacPorts dorectory will be /opt/local/share/git-core/templates/

To share hooks or templates with team members I usually create subdirectory in project like $PROJECT_DIR/lib/git/hooks then create Rake task or shell script to copy cp $PROJECT_DIR/git/hooks/* $PROJECT_DIR/.git/hooks. Symbolic links doesn't work.