How to configure core.hooksPath for BitbucketServer 4.13

We currently enforce a standard set of hooks by running a cron job every 10 minutes that creates a symlink to a central hooks directory in any new repository that does not already have the symlink.  

Starting with Git 2.9, it is now possible to configure core.hooksPath to specify a central hooks directory common to all repos.  This seems a better approach as it is more obvious, and is in effect the moment a new repo is created.

Q1.

To leverage core.hooksPath in Bitbucket Server, I'm guessing that we would set the configuration in the ~/.gitconfig for the user running Bitbucket Server.  Is this correct?

Q2.

Do hooks in a repository .git/hooks directory take precedence over hooks in the core.hooksPath location?  If not, once core.hooksPath is set, how does one override the global hooks for a specific repository? 

2 answers

hi michael!

i'm experiencing the same issue on my workstation using git 2.16.1 and atlassian sdk with bitbucket 5.7.0.

when i'm starting the bitbucket server testing my hook plugin, the hook is not called, I get an error message

    [INFO] 2018-02-06 10:46:26,858 WARN [http-nio-7990-exec-9] admin @1YO4D3Dx646x34x0 127.0.0.1 "POST /scm/project_1/rep_1.git/git-receive-pack HTTP/1.1" c.a.s.i.s.g.p.http.HttpReceivePack PROJECT_1/rep_1[1]: Git hooks have not been called. Please verify that the hooks are configured correctly - see https://confluence.atlassian.com/display/BITBUCKETSERVERKB/Git+hook+scripts+are+not+executing?utm_campaign=in-app-help&utm_medium=in-app-help&utm_source=stash for details

my hookspath is:

core.hookspath=/usr/lib/git-besi/hooks

 

do you have already contacted atlassian for this issue?

0 vote

You should not configure core.hooksPath, nor replace the pre-receive or post-receive hooks in the repository directory; Bitbucket Server relies on these for executing core processes.

Configuring `core.hooksPath` will override the default hooks that Bitbucket Server specifies. As a result, the built-in hooks that verify branch permissions, update pull requests, etc will no longer work

Hooks that use the RepositoryHook API can be enabled on a per-project or per-repository level through the Project Settings or Repository Settings pages. If you have a RepositoryHook that you want to run on all repositories, you can configure your hook to be non-configurable. See the hooks and merge checks guide for more information.

If you have a hook script that you need to run, you can add it to the hooks/pre-receive.d or hooks/post-receive.d directory of the repository that you want the hook to apply to.

Hi Michael!

We have one pre-commit hook globally configured for the whole workstation in a path /usr/lib/..../hooks. There is exactly on hook "pre-commit" in there, no pre-receive, etc.

Now, Bitbucket SDK invokes git in the repository path (e.g. /home/blabla/myhook/target/bitbucket/home/shared/data/repositories/1) and does not use the local hook directory?

It would not be a problem setting the local git repository hookspath to this one before invoking git, wouldn't it?

Thanks for the answer!

If I understand correctly, you're developing a Bitbucket Server plugin on your local machine and have a core.hookspath configured in your ~/.gitconfig. And when you run Bitbucket Server locally (though the SDK), hooks in the Bitbucket repositories are no longer being called?

There are a couple of ways to 'fix' that:

  • remove the core.hooksPath option from your ~/.gitconfig
  • start Bitbucket Server as a different user that does not have this global setting configured
  • add a 'hooksPath = .' setting to the [core] section in BITBUCKET_HOME/shared/config/git/system-config to override the global setting at the Bitbucket level

Hope that helps!

Based on the comments here, it seems to me that a site should be able to use core.hooksPath without disturbing the basic Stash functionality.  But given that it overrides the repository hooks, it seems that some guidelines are required.

  1. all hooks must be implemented in the hooksPath, even ones you do not wish to override or provide logic for.
  2. every hook must delegate to the repository hook to invoke the  Bitbucket built-in hooks.

In this way, the site can implement site-wide hooks in hooksPath and retain the full functionality of the repository level hooks.

This hookpath is configured globally for all users in /etc/gitconfig. Therefore we can't configure or disable this for a certain user.

I think a good way would be,  Bitbucket disables this git setting for it's own environment (BITBUCKET_HOME/shared/config/git/system-config), and nobody will fall into this trap now or later. I assume, the more people will use this feature, the more reports you will get.

By the way: thanks for the hint:  BITBUCKET_HOME/shared/config/git/system-config works for me.

This is not an issue for our Bitbucket Server installation since there is only one user of git on the box, that being the user running Bitbucket.  Setting core.hooksPath in ~/.gitconfig would work well for us if it did not interfere with the execution of the built-in hooks.

Perhaps there is a feature request here.  Allow sites to configure global hooks.  Provide a directory in which to store hooks that will be invoked in addition to the built-in hooks.

 

BITBUCKET_HOME/shared/hooks/before-built-in/*

BITBUCKET_HOME/shared/hooks/after-built-in/*

 

Or something similar.  The point is that some of us have git hooks that we would like to reuse in Bitbucket, and applied to all repos without having to rewrite them using the API.

Just for info: To prevent falling into this situation somewhere in future (where I have forgot this for sure :-) ), I updated our official Bitbucket test server from git 2.6 to git 2.15 to configure the system correctly and test it before I will apply this on our live system.

1) BITBUCKET_HOME/shared/config/git/system-config is overwritten each time the server reboots - so this is no solution.

2) /home/atlbitbucket/.gitconfig does not override core.hookspath from /etc/gitconfig. This is strange.

atlbitbucket@...$ cat ~/.gitconfig
[core]
hooksPath = .

 $ git config --list | grep hooks
core.hookspath=/usr/lib/git-besi/hooks
core.hookspath=.

$ git config --list --system | grep hooks
core.hookspath=/usr/lib/git-besi/hooks

$ git config --list --global | grep hooks
core.hookspath=.

I tested each possible constellation, but only one worked: when I commented out the core.hooksPath in /etc/gitconfig (server reboots didn't lead to a success, too)

So this was the only possible solution for me - maybe I missed something.

 

@michael_girouxwhat I meant before was: Does Bitbucket really need to honor this setting? Shouldn't be the server configured this way to completely ignore core.hooksPath (system-config) - because it makes no sense that Bitbucket's hooks are disabled by this setting this way?

I've raised BSERV-10609 for this. 

The issue suggests that the correction is to ignore hooksPath.  This pretty much ignores the intent of the feature.

As I suggested above, there is a need to define a hook (or set of hooks) that will apply to all repositories.  That is exactly the objective of hooksPath.  In our Bitbucket server is managing 2600 repositories.  New repos are created regularly.  We implement the update hook to enforce standards on commit messages, committer names, branch naming conventions, ...   This works because:

1. Bitbucket creates repositories that do NOT include the update hook

2. the update hook is executed after the build-in hooks so it does not override normal Bitbucket hook processing

We have a cron job that creates a symlink to the standard update hook.  We could eliminate the cron job if we could leverage core.hooksPath.

Hi @Michael Giroux,

Apologies if the intent of BSERV-10609 wasn't clear. It was meant to address this concern:

Shouldn't be the server configured this way to completely ignore core.hooksPath (system-config) - because it makes no sense that Bitbucket's hooks are disabled by this setting this way?

core.hooksPath instructs git to evaluate hook scripts in the configured location and completely ignore the hooks in the default location. Any system-wide or user-level hook configuration would have the unintended side-effect of disabling Bitbucket's built-in hooks.

Your case is a bit different in that you want use the mechanism to enforce policies globally (much like BSERV-3597 requests). The core.hookspath mechanism is tricky to use correctly for this and would easily lead to misconfiguration.

To enforce policies on all repositories, you have a number of alternative options, which may or may not meet your needs:

  • the Java hooks API does support instance-wide hooks, but this requires your hooks to be implemented in Java (or called from a Java hook)
  • Add a custom script to BITBUCKET_HOME/shared/config/git/templates/hooks/pre-recieve.d. The templates directory is used as a blueprint for creating new repositories, so any additional hooks you install there will be automatically copied to newly created repositories. I'd suggest adding a script that simply calls a script in some central location; that way you only have to maintain that central script.

Hope this helps!

I do not see BITBUCKET_HOME/shared/config/templates/hooks/pre-recieve.d.  I believe you are referencing BITBUCKET_HOME/shared/config/git/templates/hooks/pre-recieve.d.

This is very helpful.  As our hook(s) are intended to work with git whether Bitbucket is present or not, we implement as bash scripts.  The pointer to the templates directory is very helpful.  Is there documentation that describes this?  It appears that file names need to include a sequence number to indicate order of processing.  What is STASH_HOOK_CALLBACK?  Do we need to worry about that?

One thing I discovered in my own experiments with hoosPath is that it completely overrides the default location such that if we have only one hook (update) none of the hooks in the default are run.  Hence, our path needs to delegate to the default location for all hooks we do not implement.  This might be the configuration error issue you refer to.  Also, if we intend to override a default hook our hook in the hooksPath must invoke the default hook, either before or after our own logic.  Essentially, the directory pointed to by hooksPath MUST include every possible hook, and MUST delegate to the default hooks to maintain Bitbucket hook behavior. 

I do not see BITBUCKET_HOME/shared/config/templates/hooks/pre-recieve.d.  I believe you are referencing BITBUCKET_HOME/shared/config/git/templates/hooks/pre-recieve.d.

Ah yes, thanks. I've updated my original reply

The pointer to the templates directory is very helpful.  Is there documentation that describes this?  It appears that file names need to include a sequence number to indicate order of processing.  What is STASH_HOOK_CALLBACK?  Do we need to worry about that?

Here's a knowledge base article  that describes the various ways to set up hooks. All hooks in the pre-receive.d and post-receive.d directories will be invoked in alphabetical order. The sequence numbers are there to make the order clear. Your custom hooks should be called after Bitbucket's hooks.

STASH_HOOK_CALLBACK is the script that Bitbucket uses call back to the Java application is order to invoke the Java based hooks. It's not something that your custom scripts need to worry about.

Essentially, the directory pointed to by hooksPath MUST include every possible hook, and MUST delegate to the default hooks to maintain Bitbucket hook behavior. 

That is correct. But it's really easy to get wrong and not notice straightaway that the built-in hooks are not being invoked. When BSERV-10609 is fixed, Bitbucket will override any core.hooksPath setting that is configured to ensure that the built-in hooks are always called. This means that the core.hooksPath mechanism can no longer be used to manage 'central The templates approach should give you an alternative way of achieving the same thing.

thank you for raising issue BSERV-10609.

Suggest an answer

Log in or Sign up to answer
How to earn badges on the Atlassian Community

How to earn badges on the Atlassian Community

Badges are a great way to show off community activity, whether you’re a newbie or a Champion.

Learn more
Community showcase
Posted Jun 12, 2018 in Bitbucket

Do you use any Atlassian products for your personal projects?

After spinning my wheels trying to get organized enough to write a book for National Novel Writing Month (NaNoWriMo) I took my affinity for Atlassian products from my work life and decided to tr...

188 views 20 8
Join discussion

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you