Bundler has a cool facility with Gemfile s that allow you to specify some fine-grained options for a given gem beyond specifying a version. Things like :path , :branch , :git , and :tag . All of those things are neat for development, but horrible for production. I wanted a way to reject pushes to a repo if the Gemfile was changed to include any one of those options, and a git pre-receive hook was just the tonic.
The script above monitors pushes to the “master” and “stable” branches (our development and production lines, respectively). It checks to see if the Gemfile was listed in the new commit file list, then parses the blob of the Gemfile for any of the offending options. Each offending line is then output back to the pushing developer with instructions on how to fix his/her Gemfile and how to amend the commit. Here’s what the output looks like:
It’s also worth noting that since this is a pre-receive hook, when returning an exit status of anything but 0, git will reject merging the commits. This is good because we don’t want “bad code” in our repo. You could also use this to do other checking measures, such as running a CI build or syntax checks.
To use the above hook, simply copy the script above into the ./hooks/pre-receive file in your origin repo. Be sure to chmod +x ./hooks/pre-receive otherwise git won’t be able to invoke the script when a new push occurs. We have ~15 repos that I manage at work that I want to use the hook on, so I just kept the file out on the git user’s home directory and symlinked it back to each repos hooks directory. Same results, just easier to manage if I need to make a quick change to the hook.