#!/bin/sh usage() { echo "git-precheck [--quiet] [--ignore-dirty] [--ignore-untracked]" echo "" echo "If the current working directory is inside a git repository, examine" echo "the repo for any abnormal state and return an exit code indicating" echo "the status. If unclean, print a line of text describing each" echo "condition found." echo "" echo " --quiet" echo " Don't actually print anything." echo "" echo " --ignore-dirty" echo " Don't consider the presence of uncommitted changes to tracked" echo " files as an abnormal state." echo "" echo " --ignore-untracked" echo " Don't consider the presence of untracked files as an abnormal" echo " state." echo "" echo " Exit codes:" echo " 0 If inside a repository and all checks return normal" echo " 1 If untracked files detected" echo " 2 If dirty/modified files detected" echo " 3 If any ongoing git operation is in progress" echo " 4 If not inside a git repository" echo "" echo " Exit any other value on error or if 'precheck' operation is" echo " not completed, such as when viewing this help text." exit 128 } quiet="" opt_dirty="true" opt_untracked="true" while true; do case "$1" in --quiet) quiet="true" ;; --ignore-dirty) opt_dirty="" ;; --ignore-untracked) opt_untracked="" ;; --help) usage ;; -h) usage ;; *) break esac shift done if [ $# -ne 0 ]; then printf 'git-precheck: Unrecognized option given: %s\n' "$1" exit 128 fi CS="\\033[0;31m" CE="\\033[0m" cond="" dirty="" untracked="" # If outside repo, always exit immediately. if ! [ "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = "true" ]; then [ -z "$quiet" ] && printf '%bnot inside a git work tree%b\n' "$CS" "$CE" exit 4 fi # Otherwise, only exit immediately if --quiet was given. # Keep running to report all potential conditions that apply. check() { if [ -e "$(git rev-parse --git-path "$1" 2>/dev/null)" ]; then [ -n "$quiet" ] && exit 3 printf '%b%s in progress%b\n' "$CS" "$2" "$CE" cond="true" fi } check rebase-merge rebase check rebase-apply rebase/am check MERGE_HEAD merge check REVERT_HEAD revert check CHERRY_PICK_HEAD cherry-pick check BISECT_EXPECTED_REV bisect if [ -n "$opt_dirty" ] || [ -n "$opt_untracked" ]; then git_status="$(git status --porcelain 2>/dev/null)" if [ -n "$opt_dirty" ] && printf '%s' "$git_status" | grep -qvE '^\?\? '; then [ -n "$quiet" ] && exit 2 printf '%bmodified files detected%b\n' "$CS" "$CE" dirty="true" fi if [ -n "$opt_untracked" ] && printf '%s' "$git_status" | grep -qE '^\?\? '; then [ -n "$quiet" ] && exit 1 printf '%buntracked files detected%b\n' "$CS" "$CE" untracked="true" fi fi # Still here? Return the highest applicable code based on what has been seen. [ -n "$cond" ] && exit 3 [ -n "$dirty" ] && exit 2 [ -n "$untracked" ] && exit 1 exit 0