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.