Git

Aggressively revert back to a specific commit

git reset --hard `git commit-tree -p HEAD -m "some message" LAST_COMMIT_TO_KEEP^{tree}`

This snippet has gotten me through some rough situations. It ignores everything that git revert and git rebase can choke on. You can revert straight through merge commits, rebased branches, anything.

Unlike git reset, this snippet will preserve the history of your branch, and produce a new commit that performs the revert.

Ignoring all changes to a specific file locally

# To ignore a file
git update-index --assume-unchanged <file>
# To un-ignore the file
git update-index --no-assume-unchanged <file>

I run this command on local config files all the time, when I don’t want to accidentally commit my personal credentials to the repository. Git will act like the file hasn’t been changed no matter how much you edit it.

How is this different from .gitignore?

.gitignore is for files which should never be added to the repo. --assume-unchanged is useful when you DO want to keep copy of the file in your repo, but you don’t want to accidentally commit your own changes.

Prevent committing a value on accident

You can save this as your repo’s .git/hooks/pre-commit file:

#!/bin/sh
DO_NOT_COMMIT=$(git diff --cached -U0 | grep -i 'DO NOT COMMIT')

if [ ! -z "$DO_NOT_COMMIT" ]; then
  echo "Refusing to commit due to 'DO NOT COMMIT'"
  echo "Push anyway with git commit --no-verify"
  exit 1
fi

exit 0

When I’m editing a file and I’ve done something I don’t want to accidentally commit, I’ll add the text “DO NOT COMMIT” to prevent accidents:

function saveUser() {
    validateUser();
    deleteEverything(); // DO NOT COMMIT
    db.save(user);
}

The error message you get looks like this:

$ git commit -am "Save the user"

Refusing to commit due to 'DO NOT COMMIT'
Push anyway with git commit --no-verify