Configure Git
Git can be configured to improve a developer's workflow. I use git from the command line, so I rely on aliases and hooks.
Aliases
Git aliases allow one to decrease the amount of typing and the need to memorize exact commands.They are defined in .gitconfig
file, under the alias
section.
[alias]
c=commit
lg="git log -1"
In the example above, the aliases c
and lg
allow one to run git c
and git log
instead of git commit
or git log -1
.
The alias section in my .gitconfig
is as follows
[alias]
a=add
b=branch
c=commit
p=push
s=status
# Add a patch
ap="!git add ${@} -p; git status"
# Simple Checkout
co="!git checkout ${@}; git status"
# Display last commit (HEAD)
lst="!git log -1 | cat"
# Search for a branch
sr="!git branch -a | grep $2"
# Discard changes
unco="!git checkout -- ${@}; git status"
# Unstage changes
unst="!git reset HEAD -- ${@}; git status"
The !
tells to git to run the command as if in a terminal.
Hooks
Git hooks allow one to tap into the the git lifecycle events.This gives one the ability to automate routine tasks. I use the following hooks
- pre-commit
- commit-msg
- pre-push
Pre-commit
This hook is run before any of the commit related git lifecycle events are fired. I use it to do the linting and type checking.
#!/bin/sh
set -e
changed_files="$(git diff --staged --name-only *.{ts,tsx})"
## Linter on changed files
echo "Running ESLint on changed files"
echo $changed_files | xargs npx eslint
## Typechecker on changed files
echo "Running typechecker on changed files"
echo $changed_files | xargs npx tsc --noEmit
Commit-msg
This hook is run after a commit message has been written and before the commit has been applied.I use it to ensure that the commit message header is prefixed with the issue/ticket id.
#!/bin/sh
set -e
# Read first line from EDIT_COMMITMSG file
read -r msg<$1
# Get current branch name
branch=$(git symbolic-ref --short -q HEAD)
# If branch name is properly named, then extract XXX-1234 prefix.
# It will used to prefix the commit message.
if [[ $branch =~ ^[a-zA-Z]{3}-[0-9]+ ]]; then
prefix="${BASH_REMATCH[0]}"
else
echo "Branch name is not prefixed with XXX-1234."
exit 1
fi
if [[ $msg =~ ^[a-zA-Z]{3}-[0-9]+ ]]; then
echo "The commit message properly formatted."
else
msg="$prefix $msg"
# Replace the commit message header with the prefixed one
gsed -i "1s/.*/$msg/" $1
echo "Prefixed the commit message with $prefix"
fi
Pre-push
This hook is run before one pushes to a remote branch. I use it to run tests, this is specially helpful when pushing to an open PR.
#!/bin/bash
npm test -- --all --watchAll=false --silent