Youre Doing it Wrong: Commit Hooks! or Commit Hooks: the Subtle HammerBen McGrawSr. Software Engineer, IMVU Inc.firstname.lastname@example.org@bengrue
What are commit hooks?A way to run automated actions before your local changes getcommitted to your code repository.
What are commit hooks?A way to run automated actions before your local changes getcommitted to your code repository.A way to make the computer check all those annoying littlerepetitive tasks before your code goes on your permanentrecord.
Computers are good at repetition.(People are bad at repetition...and good about forgetting little things!)Make the computer do the repetitive,boring stuff so you can focus on theinteresting code.
How do I make them?In SVN:as the SVN user, go to /PATH_TO_REPO/hooks/ and make anexecutable script file in your favorite shell scripting language.In GIT:Basically the same... but theres a lot more options/specifichooks available (see link at the end).
How do I make them?The basic principle is the same in both:1. The script receives text about the files youre attempting tocommit.2. You inspect those files for rules you make yourself.3. If you want the commit to not get through to the repository,return an error code (and print out an error message toSTDERR).4. Otherwise, your commit continues on to the repository.
Best Practices1. Subdivide each individual check into its own function.2. Give each individual check its own passphrase to skip it.
Enforce Coding Conventions- Prevent Code that doesnt allow Linting (Static Analysis!)- Enforcing Company/Project-specific coding style guidelines - For example, IMVU has commit hooks to prevent: - tabs from being committed - leading-underscored (lazy private) functions from being used outside of a module. - using a modules name in a function (e.g., customer::get() is good, customer::get_customer() is bad.)- Passphrase to skip is per type ("Skip whitespace check.","Skip module check.", etc... )
Running tests as part of your workflow- One of the simplest way to integrate test-running into a codingworkflow- If you want acceptance tests, and you dont prevent commitsupon failure, youre Doing It Wrong (but thats a seperate talk).- Running tests-pre commit doesnt scale to a large team / largenumber of tests
Continuous Deployment?- If youre doing a Continuous Deployment System, commithooks are a simple but critical element of your system... If your build system is red, you must prevent commits.- Passphrase to commit through this: "Fixing buildbot"
Locking Down Sensitive Areas- Some areas of your architechture are incredibly sensitive (e.g., low-level database/memcache libraries, paymentprocessing, )- Try to use this sparingly (make a blanklist of files, not awhitelist) since it breaks workflow and halts engineer velocity tohave to verify everything on every file.- Passphrase to commit through this: "Reviewed by XXX" where XXX is the name of an engineer.
Enforcing Social Policies- You can enforce a Code Freeze during weekends andholidays to prevent committing to the main code line whentheres minimal staff around. - Lowers stress for ops during off-hours - Engineers can commit to branches during the weekend towork unimpeded
Enforcing Social Policies- We found this useful at IMVU for years, but refinement of ourentire Continuous Deployment system has recently made usreconsider preventing weekend commits, so we changed policy!- Passphrase to commit on weekends is a password that is listed onthe internal wiki for the weekend commit policy. The passphrase ischanged every time we change the policy.- The rejection error message itself contains the link to the wikipage with the current policy and the passphrase.
The Shibboleth of Saving FaceProblem:Sometimes you are proving something to yourself in yoursandbox (noodling through a problem) and you dont want thiscode going out.Sometimes you forget and commit that code.Solution:A commit hook checking for the phrase "DO NOT COMMIT".Now when you noodle, you start it with that phrase in acomment and your ass is covered.Override: "Ignore Do Not Commit"
Passive EducationNot strictly "coding conventions" in the traditional sense, butgood habits based on context.For example:$_REQUEST bad in PHP, $_GET/$_POST are good......so forbid access of $_REQUEST and link to a webpage thatexplains why, and provide a short blurb of how to correct theissue.For these types of rules, no specific "skip this" message
Further reading (yay homework)- http://wordaligned.org/articles/a-subversion-pre-commit-hook General how-to for SVN pre-commit hooks- http://book.git-scm.com/5_git_hooks.html General how-to for all sorts of GIT commit hooks- http://eng.wealthfront.com/2011/03/corrective-action-with-gits-pre-commit.html Corrective Actions with GIT commit hooks- http://engineering.imvu.com/ We do cool things, and talk about workflow/build systems a lot