From e20e27ffa8a048068fd8d66b2b6a5bc90d91452b Mon Sep 17 00:00:00 2001 From: Matt Hunter Date: Sun, 10 May 2026 00:55:48 -0400 Subject: precheck: Switch to file-based detection and report all conditions Detect all ongoing git conditions by checking for the existence of some file or directory within the .git folder. This eliminates the previous git rev-parse --verify commands, which should be a slight boost to performance. Furthermore, the implementation of rebase detection is no longer a special case. Also, restructure the script such that all applicable conditions are reported when run, not just the first we detect. The script exit code reflects the highest value of the active conditions. Though, as an optimization, still exit on the first found when --quiet is in effect. The script is cleaned up as well. In some cases style is changed to better match the current state of git-sonar. git-status is now only called once and cached for both dirty and untracked detection. Signed-off-by: Matt Hunter --- git-precheck | 74 +++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 41 insertions(+), 33 deletions(-) (limited to 'git-precheck') diff --git a/git-precheck b/git-precheck index 2547563..0602ecd 100755 --- a/git-precheck +++ b/git-precheck @@ -5,8 +5,8 @@ usage() { 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 the" - echo "condition." + echo "the status. If unclean, print a line of text describing each" + echo "condition found." echo "" echo " --quiet" echo " Don't actually print anything." @@ -32,14 +32,14 @@ usage() { } quiet="" -ignore_dirty="" -ignore_untracked="" +opt_dirty="true" +opt_untracked="true" while true; do case "$1" in --quiet) quiet="true" ;; - --ignore-dirty) ignore_dirty="true" ;; - --ignore-untracked) ignore_untracked="true" ;; + --ignore-dirty) opt_dirty="" ;; + --ignore-untracked) opt_untracked="" ;; --help) usage ;; -h) usage ;; *) break @@ -52,47 +52,55 @@ if [ $# -ne 0 ]; then exit 128 fi -check() { - if git rev-parse --verify "$1" >/dev/null 2>&1; then - [ -z "$quiet" ] && printf '\e[0;31m%s in progress\e[0m\n' "$2" - exit 3 - 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 '\e[0;31mNot inside a git work tree\e[0m\n' + [ -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 [ -e "$(git rev-parse --git-path rebase-merge 2>/dev/null)" ]; then - [ -z "$quiet" ] && printf '\e[0;31mrebase in progress\e[0m\n' - exit 3 -fi - -if [ -e "$(git rev-parse --git-path rebase-apply 2>/dev/null)" ]; then - [ -z "$quiet" ] && printf '\e[0;31mrebase/am in progress\e[0m\n' - exit 3 -fi +if [ -n "$opt_dirty" ] || [ -n "$opt_untracked" ]; then + git_status="$(git status --porcelain 2>/dev/null)" -if [ -z "$ignore_dirty" ]; then - if git status --porcelain 2>/dev/null \ - | grep --quiet --invert-match '^??'; then - [ -z "$quiet" ] && printf '\e[0;31mModified files detected\e[0m\n' - exit 2 + 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 -fi -if [ -z "$ignore_untracked" ]; then - if git status --porcelain 2>/dev/null \ - | grep --quiet '^??'; then - [ -z "$quiet" ] && printf '\e[0;31mUntracked files detected\e[0m\n' - exit 1 + 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 -- cgit v1.2.3