Reputation: 8128
I would like to customize my Git prompt in such a way that it reminds me or runs checks for me before I push something to a remote repo.
For instance, when I run
git push
Git should ask the user
Did you run unit tests locally?
or something to that effect, so that I don't accidentally push code that is not unit-tested.
Upvotes: 5
Views: 3262
Reputation: 295316
First: This won't work (not in a technical sense, but in a human-habit sense). See Rob Mayoff's idea instead.
However, to demonstrate an implementation, you could put the following in your ~/.bashrc
:
git() {
if [[ $1 = push ]]; then
printf %s "Did you run unit tests locally?"
read response
case $response in
y|Y|yes|YES) command git "$@" ;;
*) echo "Aborting" ;;
esac
else
command git "$@"
fi
}
Better, to implement Rob's idea:
git() {
local -a options=( )
while (( $# )) && [[ $1 = -* ]]; do
case $1 in
-C|-c) options+=( "$1" "$2" ); shift; shift ;;
*) options+=( "$1" ); shift ;;
esac
done
local base_dir=$(git rev-parse --show-toplevel)
case $1 in
commit|merge|rebase)
touch "$base_dir/.untested"
command git "${options[@]}" "$@"
;;
push)
if [[ -e "$base_dir/.untested" ]]; then
echo "Untested commits exist; you must run tests"
else
command git "${options[@]}" "$@"
fi
;;
*) command git "${options[@]}" "$@" ;;
esac
}
unittest() (
cd "$(git rev-parse --show-toplevel)"
make test && rm .untested
)
Upvotes: 0
Reputation: 385540
Set up your pre-push hook to prevent pushing unless the file .testspassed
exists. Example:
cat > .git/hooks/pre-push <<EOF
#!/bin/sh -e
if ! [ -f .testspassed ]; then
echo 1>&2 "push aborted because tests were not run or did not all pass"
exit 1
fi
exit 0
EOF
chmod +x .git/hooks/pre-push
Set up your prepare-commit-msg hook to remove .testspassed
if it exists:
cat > .git/hooks/prepare-commit-msg <<EOF
#!/bin/sh -e
rm -f .testspassed
exit 0
EOF
I'm using prepare-commit-msg
instead of pre-commit
because prepare-commit-msg
runs on merges too. Any time you commit or merge, git will remove the .testspassed
file, preventing you from pushing.
Tell git to ignore the .testspassed
file so it doesn't end up in your repo:
echo .testspassed >> .gitignore
git commit -m 'add .testspassed to .gitignore' .gitignore
Finally, modify your test-run process to create (“touch”) .testspassed
if all your tests pass. How you do this depends on how you run your tests.
Upvotes: 4