Managing Git Hooks using Whisky in PHP
Git hooks are scripts that run automatically every time a particular event occurs in a Git repository. They let you customize Git’s internal behavior and trigger customizable actions at key points in the development life cycle.
- What is Whisky?
- Installation
- Defining Git Hooks
- Disabling Git Hooks
- Skipping Git Hooks
- Under the hood
- Conclusion
For instance, if you want to run a linter every time you commit a change, you can use Git hooks to do that. Or if you want to run a test suite before you push your changes to the remote repository, you can use Git hooks to do that as well.
The traditional way of managing Git hooks is to create a file with the name of the hook inside the .git/hooks
directory of your Git repository.
For instance, if you want to run a linter every time you commit a change, you can create a file called pre-commit
inside the .git/hooks
directory and add the following code to it.
#!/bin/sh
echo "Running linter before commit!"
The problem with this approach is that you can’t version control these hooks. So, if you want to share these hooks with your team, you have to manually copy these hooks to each of your team members’ machines. This is where this PHP package called Whisky comes in.
What is Whisky?
Whisky is a framework-agnostic PHP package that lets you manage Git hooks in a version-controlled way. It lets you define Git hooks in a JSON file and then it automatically creates the hooks for you in the .git/hooks
directory of your Git repository.
Installation
You can install the package as a dev dependency in a Composer-based project using the following command.
composer require --dev projektgopher/whisky
./vendor/bin/whisky install
The only prerequisite for this package is that the project should be running on PHP 8.1 or higher.
Defining Git Hooks
Once installed, Whisky will create a whisky.json
file in the root of your project. This file is used to define the Git hooks.
Here’s how it will look like.
{
"disabled": [],
"hooks": {
"pre-commit": [
"./vendor/bin/pint --dirty"
],
"pre-push": [
"composer test"
]
}
}
As you can tell, the configuration is pretty straightforward. All the Git hooks are defined inside the hooks
key. The keys in the hooks
object are the name of the Git hooks and the value is an array of commands that you want to run when the hook is triggered.
In this example, we’re running Laravel Pint before every commit and running the test suite before every push. So, it will fix the code style issues before every commit. Also, it will run the test suite before every push.
Adding or removing any hooks (not individual commands) to your whisky.json file should be followed by
./vendor/bin/whisky update
to ensure that these changes are reflected in your.git/hooks
directory.
Disabling Git Hooks
If for some reason, you want to disable a Git hook, you can do that by adding the name of the hook inside the disabled
key.
{
"disabled": [
"pre-commit"
],
"hooks": {
"pre-commit": [
"./vendor/bin/pint --dirty"
],
"pre-push": [
"composer test"
]
}
}
In this example, we’re disabling the pre-commit
hook. So, it won’t run before every commit.
Skipping Git Hooks
If you want to skip a Git hook for a particular commit, you can do that by adding a --no-verify
flag to the commit command.
git commit -m "My commit message" --no-verify
Or you can use the following command before running a Git command which will skip all the Git hooks once.
./vendor/bin/whisky skip-once
Under the hood
If you check the content of the hook file created by Whisky under the .git/hooks
directory, you’ll see something like this.
# .git/hooks/pre-commit
#!/bin/sh
eval "$(/project-dir/vendor/bin/whisky get-run-cmd pre-commit)"
As you can tell, Whisky creates its own shell script that runs the commands defined in the pre-commit
hook defined in the whisky.json
file.
Conclusion
And that’s essentially the crux of what Whisky does. It’s a pretty handy tool if you want to manage Git hooks in a version-controlled way. You can learn more about this package on its repository.
Like this article?
Buy me a coffee👋 Hi there! I'm Amit. I write articles about all things web development. You can become a sponsor on my blog to help me continue my writing journey and get your brand in front of thousands of eyes.