Protect Git Refs

A git reference is a pointer to a particular commit. In the case of branches it is a pointer to the head of a line of work. For a tag, it’s a pointer to a particular commit that remains fixed. The purpose of this hook is to block changes to refs based on arbitrary conditions.

So, this does nothing other than reject the commit with the supplied message, if the provided condition evaluates to true. So, as a blank condition evaluates to true, unless you provide a condition this will reject everything (so not very useful).

The error message will only be used if one is not provided in the condition. If you want a dynamic error message based on the changes a user has pushed then you should use diagnosable conditions.

Click the Expand examples link to show examples…​ you will probably need to modify them to suit.

For example to prevent deletion of tags that begin with REL, you would start with the existing example for blocking all tag deletion, and end up with:

import com.atlassian.bitbucket.repository.RefChangeType refChanges.any { it.ref.id.startsWith("refs/tags/REL") && it.type == RefChangeType.DELETE }

To reject changes to certain subdirectories from users not in a particular authorized group, we need to combine two of the example conditions. Firstly, checking the group of the pusher, and secondly, checking if the user is in a group.

This leads us to the following condition script:

import com.atlassian.sal.api.component.ComponentLocator import com.atlassian.bitbucket.auth.AuthenticationContext import com.atlassian.bitbucket.user.UserService def userService = ComponentLocator.getComponent(UserService) def authContext = ComponentLocator.getComponent(AuthenticationContext) if (pathsMatchExcludingDeletes('glob:path/to/sensitive/code/**')) { // return true if the user is NOT in the desired group, thus blocking the push return !userService.isUserInGroup(authContext.getCurrentUser(), "authorised-devs") } return false

The intention of the examples is that you use them as starting points for more complex instructions, by and and or ing them together for instance.

When restricting pushes by file name, use pathsMatchExcludingDeletes rather than pathsMatch, as this will allow users to delete undesirable files that were in the repository before you started using this hook.

Exclude Files Tracked by Git LFS

You can exclude files tracked by Git LFS from any hook condition by using the following:

pathsMatcher .excludingLfsFiles() .matches("glob:**.jar")

Line 2: Tell pathsMatcher to exclude files tracked by Git LFS

Line 3: See if any files in the push (not already by Git LFS) with the jar file extension are present

This is particularly useful if you want a condition to block binary files, but exclude the ones already tracked by Git LFS. You could then add an error message informing the developer that they need to move these files to Git LFS if they want to push them.

You can find further configuration options for pathsMatcher here.

On this page