# Some fun with git hooks and Grunt.js

Before going further, I’ll start by saying that I’m a Git and Github noob, so if you have a better solution to achieve the same goal, give me a shout, I’ll be happy to hear it..!

A few weeks ago, I implemented a small bookmarklet to apply google-code-prettify anywhere on the Web.
I put the source code on Github and used the (awesome) Automatic Page Generator to quickly create a landing page to host my bookmarklet.

The generated page lives on the same repository, on a branch called gh-pages.
At this point, my concern was the following: How could I include the bookmarklet link on gh-pages branch from the source code living on the master?

In a first try, I could just copy/paste the minified source into an <a href="..."> link in my index.html.
But what happens if I update the source?
I’ll probably have to deal with that kind of work flow:

Rather boring, right? Totally agree! And that’s why I decided to dig a little further to see how I could automate this.

## Automate the whole thing!

### Avoiding copy / paste

Copy/paste a file from a branch to another may be acceptable if you do it only once. From there, it’s probably better to use the following:

### Updating HTML content

As mentioned earlier, I already used grunt.js to lint, concat and minify my source on the master branch.
So I searched for a way to use grunt to update the HTML link. I quickly found grunt-replace, perfect fit for the job.
I ended up with an HTML source file, with a placeholder for the bookmarklet:

And a simple grunt replace task, reading the minified source and generating an up-to-date index.html

### Introducing Git Hooks

Basically, Git Hooks allow you to automatically run custom scripts at any step in your workflow.
Hooks must be defined in the .git/hooks/ folder.
Placeholder files are already created, giving a pretty good idea about what’s possible or not.

You only need to remove the .sample extension to define a hook, then edit the script to create your own awesome automation.

### Bringing the pieces together

In my case, I created a post-commit script. Right after every new commit on the master branch, this piece of code runs and does all the crappy work.

As both master and gh-pages branches are modified, they both need to be pushed on the remote repository.
I use git push --all, which is fine if you don’t have any other updated branch. Otherwise, you’ll need a specific push for each branch.

## Going further

I’d like to find a way to stop the script if the commit doesn’t occur on the master branch, but I’m not sure how to do it…

I’ll probably also add a pre-commit hook to lint/concat/minify the source.
Grunt.js already simplified this to a one liner, but I often forget to call it before committing changes.

(Grunt + Git Hooks) appears to be a nice couple with a huge time-saving potential. I’d like to have an opportunity to try it on a larger project and see how it goes.