Wednesday, September 7, 2016

Git Hooks: Unwanted Code Lines

When working with source control, there are often files that you don't want to commit. This could be for cleanliness sake, for things such as IDE file that get placed into a directory. It could be security related files like keystores or password files. Luckily there's a very simple solution in the form of the .gitignore file. Simply add the file name pattern to it and voila it doesn't appear. However, what if you want to prevent certain lines of a file from being committed?

A simple case may be where you are initially coding something that requires passwords in the code itself. Maybe you're starting an interface that goes out to some remote system, but you don't have in system in place to managed the passwords in a smart way yet. First you want to get the interface built, and then augment it with smarter practices. Additionally, you want the ability to commit your progress along the way, but at the same time you to make sure that these credentials don't make their way into the repo since that could. In your file you have some line that looks like this:

private final String userName = "someusername";

So how do you prevent this? Git Hooks , but more specifically we are going to use the pre-commit hook. Git Hooks can be pretty powerful, but unfortunately on the client side they have to more or less be populated manually, and it's on a per-repo basis. Nonetheless they can still be useful.

After customizing a script that I forked on Github I copied the pre-commit script into my .git/hooks folder and away it goes. Now all I need to do in the future is add the NOCOMMIT keyword to my files and it will prevent them from getting committed.

private final String userName = "someusername"; // NOCOMMIT

Now if the keyword is found a message similar to this will appear:

Checking modified file: path/to/violating/File.java [NOCOMMIT]
NOCOMMIT found in file: path/to/violating/File.java 

These errors were found in try-to-commit files: 
private final String userName = "someusername"; // NOCOMMIT

Can't commit, fix errors first.

This is far from a flawless implementation, but for 90% of the time, it reduces the headaches associated with needing to rollback commits, rebase and all that fun to be rid these tainted commits. I figured if it works for me, then it can work for most people.

Happy Committing!

No comments: