86 lines
1.8 KiB
Bash
Executable file
86 lines
1.8 KiB
Bash
Executable file
#!/bin/bash
|
|
#
|
|
# This script runs a given command over a range of Git revisions. Note that it
|
|
# will check past revisions out! Exercise caution if there are important
|
|
# untracked files in your working tree.
|
|
#
|
|
# This came from Gary Bernhardt's dotfiles:
|
|
# https://github.com/garybernhardt/dotfiles
|
|
#
|
|
# Example usage:
|
|
# $ run-command-on-git-revisions origin/master master 'python runtests.py'
|
|
|
|
set -e
|
|
|
|
if [[ $1 == -v ]]; then
|
|
verbose=1
|
|
shift
|
|
fi
|
|
|
|
start_ref=$1
|
|
end_ref=$2
|
|
test_command=$3
|
|
|
|
main() {
|
|
abort_if_dirty_repo
|
|
enforce_usage
|
|
run_tests
|
|
}
|
|
|
|
abort_if_dirty_repo() {
|
|
set +e
|
|
git diff-index --quiet --cached HEAD
|
|
if [[ $? -ne 0 ]]; then
|
|
echo "You have staged but not committed changes that would be lost! Aborting."
|
|
exit 1
|
|
fi
|
|
git diff-files --quiet
|
|
if [[ $? -ne 0 ]]; then
|
|
echo "You have unstaged changes that would be lost! Aborting."
|
|
exit 1
|
|
fi
|
|
untracked=$(git ls-files --exclude-standard --others)
|
|
if [ -n "$untracked" ]; then
|
|
echo "You have untracked files that could be overwritten! Aborting."
|
|
exit 1
|
|
fi
|
|
set -e
|
|
}
|
|
|
|
enforce_usage() {
|
|
if [ -z "$test_command" ]; then
|
|
usage
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
usage() {
|
|
echo "usage: `basename $0` start_ref end_ref test_command"
|
|
}
|
|
|
|
run_tests() {
|
|
revs=`log_command git rev-list --reverse ${start_ref}..${end_ref}`
|
|
|
|
for rev in $revs; do
|
|
debug "Checking out: $(git log --oneline -1 $rev)"
|
|
log_command git checkout --quiet $rev
|
|
git log -n1
|
|
log_command $test_command
|
|
log_command git reset --hard --quiet
|
|
done
|
|
log_command git checkout --quiet $end_ref
|
|
debug "OK for all revisions!"
|
|
}
|
|
|
|
log_command() {
|
|
debug "=> $*"
|
|
eval "$@"
|
|
}
|
|
|
|
debug() {
|
|
if [ $verbose ]; then
|
|
echo $* >&2
|
|
fi
|
|
}
|
|
|
|
main
|