We all sometimes write a code that we don’t want to commit to our codebase at the end. For example you test a tricky bug, that’s hard to catch, and hardcode some parameters. Or you develop a feature and create a stub class at the beginning, and then plan to return to it after some time. But you have to always keep a note about this code in memory, and occasionally you may forget about it and commit the temporary code to your repository.
Our brain can hold only limited amount of objects in short-term memory, so I like to delegate some tasks to my computer and reduce the amount of work my brain does during programming. I found one small trick, that lets me deal with this issue. I use it every day couple of times and find it extremely useful, so let me share that trick with you.
The idea is simple, whenever you write a code, that you know you don’t want to be in your codebase you just write a comment with a codeword NOCOMMIT (it can be any word you want actually). For example, let’s say we want to check a behavior with the premium user in our application. So we write some hardcode to test an issue and then plan to remove that line of code after the check.
val isUserPremium = true //userRepo.isPremium() NOCOMMIT
Then, if you forget to remove this code, you will receive an error trying to create a commit.
~/demoapp: git commit -a -m 'testapp/src/main/java/com/demoapp/DemoClass.kt:1:
val isUserPremium = true //userRepo.isPremium() NOCOMMIT ERROR: @COMMITFAIL or @NOCOMMIT found. Exiting to save you from yourself.
Seeing this error you can instantly search for the code you marked as not commitable and fix it.
Now let’s see how can we add this behavior to our projects.
The magic that happens behind the scenes uses git hooks to execute some scripts before each commit. (You can execute it on other steps as well, but I won’t stop on it). Every project on git has a .git/hooks folder in root where you can add your own git hooks.
To use this script, create a new file called
pre-commit and add the following lines to it:
FORBIDDEN=’(@?NOCOMMIT|@?COMMITFAIL)'if ( git diff --cached --name-only | grep -E $FILES_PATTERN | xargs grep -E --with-filename -n $FORBIDDEN ); then
echo "ERROR: @COMMITFAIL or @NOCOMMIT found. Exiting to save you from yourself."
The logic is simple: the script searches for the keywords ( NOCOMMIT or COMMITFAIL here) in the git diff and if it finds any keyword then the commit is aborted. It will also work if you put this word in any file like .xml or .gradle, not only Java/Kotlin classes.
After creating the file make it executable.
chmod +x pre-commit
Now just put it into the
.git/hooks. And that's all you need to make it work. You can test it yourself.
Adding the hook to every local repository
I work with this hook on every repository I have. And I don’t want to add it manually every time I clone a new repo, so why not to delegate this work to git? If you use Git v2.9 and above you can write following in console (assuming you have your hooks in githooks folder):
git config core.hooksPath githooks
Now for every new git repo the above hook will be placed automatically into the .git/hooks folder. You can also add it to any repository you already have using
git init command.
Live template to make it safer
We can’t be sure we won’t make a mistake writing the keyword, so it’s a good idea to create a live template that will help you with it.
- Go to Live Templates setting in Android Studio (CTRL + SHIFT + A -> Live Templates)
- Choose any group you like and press + -> Live Template to create a new template
- Select abbreviation (I chose ncm), any description you want and put your keyword in Template text (I put NOCOMMIT)
- Define applicable contexts (the place where you template will work). Here we should choose Java -> Comment, Kotlin -> Comment
- Make sure it’s checked in the menu above.
- Apply -> OK
It should work now.
Extend it as you want
You can also expand the idea as you wish, the power beyond git hooks is really enormous.
For example there’s an interesting article about passing all tests before the code can be pushed to the repository. Take a look here
Also there’s quite similar idea to prevent code to be released. It also uses comment //STOPSHIFT. Take a look here for implementation
Thanks for reading. I’d be happy if you can share your own git hooks ideas that make your daily development easier in the comment section below.
Originally published at https://andrey-kazarovets.com on September 10, 2019.