Skip to content

Instantly share code, notes, and snippets.

@mmueller
Last active July 6, 2022 18:12
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mmueller/7286919 to your computer and use it in GitHub Desktop.
Save mmueller/7286919 to your computer and use it in GitHub Desktop.
This is a bash script that wraps git and lets you implement pre- or post-command hooks that apply to git globally (not per-repository). Out of the box, this script has a post_clone and post_init hook that do the same thing: prompt you to verify that the author information (user.name and user.email) are correct for the given repository -- prevent…
#!/bin/bash
#
# This script wraps git, so install it somewhere such as ~/bin where
# it will be found by your shell before the actual git executable.
set -e
# Extract the command from a git command line
function get_command {
while [[ "$1" =~ ^- ]]; do
shift
done
echo $1
}
function pre_command {
command="`get_command "$@"`"
# Pre-command hooks could go here
}
function post_command {
command="`get_command "$@"`"
# Post-command hooks
case $command in
clone) post_clone "$@" ;;
init) post_init "$@" ;;
esac
}
function post_clone {
# Skip past irrelevant parameters
while [[ "$1" =~ ^- ]] || [ "$1" = "clone" ]; do
param="$1"
shift
if [ "$param" = "--" ]; then
break
fi
done
# We only need to know the target directory
repo="$1"
dir="$2"
if [ "$dir" = "" ]; then
# Directory not passed, derive dir name from repository URI
dir="$repo"
dir="${dir##*/}"
dir="${dir%.git}"
fi
configure_author "$dir"
}
function post_init {
last="${@: -1}"
if [ "$#" -le 2 ] || [[ "$last" =~ ^- ]]; then
dir="."
else
dir="$last"
fi
configure_author "$dir"
}
# Rationale: It's not hard to run git config user.email, etc., but I often
# forget to do it and accidentally commit to a repository with the wrong
# author email set. This will ensure that after a clone or init, I'm prompted
# to verify the author configuration.
function configure_author {
dir="$1"
pushd "$dir" >/dev/null
echo "--"
echo "Configuring author for this repository..."
echo -n "Author name: [`"$GIT" config user.name`] "
read name
if [ -n "$name" ]; then
"$GIT" config user.name "$name"
echo " [$dir] git config user.name \"$name\""
fi
echo -n "Email address: [`"$GIT" config user.email`] "
read email
if [ -n "$email" ]; then
"$GIT" config user.email "$email"
echo " [$dir] git config user.email \"$email\""
fi
popd >/dev/null
}
# Assuming this script is called 'git', find the next available 'git' command
# via 'which'. Override this if you want to hard-code a different path.
GIT="`which -a git | awk 'NR==2 {print}'`"
if [ "$GIT" = "" ]; then
echo "git executable not found"
exit 1
fi
# General: Do not run hooks for --help
if [ "${@: -1}" == "--help" ]; then
"$GIT" "$@"
else
pre_command "$@"
"$GIT" "$@"
post_command "$@"
fi
@benjaminfuchs
Copy link

Hi Mike,
thanks for that script!
I created my own based on your basic idea, maybe you can benefit from my work too:
https://github.com/benjaminfuchs/git-wrapper
Greeting,
Benjamin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment