Git pre-hook: Setup pre-commit hook for Gradle project example
Tags: git, github, gradle, tutorial
Published: 2021-09-16 23:00:32

## Introduction 

There are various Git pre-hooks that are quite helpful for several essential tasks we want to execute before commit or push or rebase etc. Basically, there are various use cases, like running linting before you commit or running unit tests before push or commit.

{% youtube xF4oY-b5m5U %}

> Whenever a Git repository is initialized, Git creates sample hooks inside `.git/hooks` directory in the project directory. E.g. `.git/hooks/pre-commit.sample`

## Getting Started 

Below are steps on how to configure pre-hook for a Gradle project:
### 1. Create a pre-hook script

Let's create `pre-commit` file inside a new `scripts` directory, and we want to run unit tests before code commit.

```SHELL
#!/bin/sh

echo "*****Running unit tests******"

stash_commit="$(git stash create)"
git reset —-hard

./gradlew test

status=$?

if [[ -n "${stash_commit}" ]]
then git stash apply "${stash_commit}"
fi

echo "*****Done with unit tests******"

exit $status
```
Above command stash the working directory changes before running the unit tests, and unstash back. This makes sure, we're running unit tests only in the clean working directory. (as this is been configured for pre-commit, changes must have been staged, make sense?😀)

### 2. Create Gradle Task

Next, create a Gradle task in the `build.gradle` file to install the `pre-commit` script. Why do we need it? because, we want this to run on all developers' machine, not just on our machine, we all love consistency and wants to put the constraints.

```GRADLE

task installLocalGitHook(type: Copy){
from new File(rootProject.rootDir, 'scripts/pre-commit')
into { new File(rootProject.rootDir, '.git/hooks')}
fileMode 0775
}

build.dependsOn installLocalGitHook

```
> Here pre-commit file was created inside project root directory i.e. `scripts`

Above Gradle task will run whenever someone takes the build and assuming that developer who is making changes will run the Gradle build task at least once and I hope I'm right😉.

Once pre-commit script is copied to `.git/hooks/` directory, we're all set. We can verify its content as below:

```SHELL
cat .git/hooks/pre-commit
```

Now, next time whenever someone will run `git commit`, it will first run the `./gradlew test` task.

E.g.
```SHELL
ak@--mac git-pre-commit % git commit -am "update"

-- Output

*****Running unit tests******

BUILD SUCCESSFUL in 1s
4 actionable tasks: 4 up-to-date
[main ed41136] update
 1 file changed, 13 insertions(+), 1 deletion(-)
```

## Final Notes

- The way `./gradlew test` is configured, in the same way, any other tasks can be executed. And of course for other tasks stash and unstash won't be compulsory.
- And similarly other pre-hooks can be configured

## Sample Code
Here is the [GitHub repo](https://github.com/an1meshk/git-pre-commit) with an example.

## My other Blogs:

- [Avoid Spring RestTemplate Default Implementation to Prevent Performance Impact](https://dev.to/akdevcraft/never-use-spring-resttemplate-default-implementation-2ghj)
- Post on how to [setup pre-hook for an NPM project](https://dev.to/an1meshk/git-pre-hook-pre-commit-hook-with-npm-project-44p2)
- [Team Agreement in Software Engineering](https://dev.to/akdevcraft/software-engineering-sample-team-agreement-2275)
- [Containers Vs Virtual Machines, which is better and why?](https://dev.to/akdevcraft/containers-vs-virtual-machines-45m1)

_If you have reached here, then I did a satisfactory effort to keep you reading. Please be kind to leave any comments or ask for any corrections. **Happy Coding!**_