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
Remove extra ‘gits’ on the command line
I exclusively use Git via the command line, so I spend a lot of time typing commands. Sometimes I absentmindedly forget where I am and type something like git git commit
or git git checkout my-branch
I have this in my .bashrc / .zshrc file to remove the extra ‘gits’:
function git() {
if [[ $1 == "git" ]]; then
command git "${@:2}"
fi
if [[ $1 == "checkout" && $2 == "git" ]]; then
command git "${@:3}"
else
command git "$@"
fi
}
It includes a special case to convert git checkout git checkout my-branch
to git checkout my-branch
, another frequent inattentive mistake of mine when copying branch names from a Pull Request.