summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Hunter <m@lfurio.us>2026-05-10 00:55:48 -0400
committerMatt Hunter <m@lfurio.us>2026-05-10 04:47:01 -0400
commite20e27ffa8a048068fd8d66b2b6a5bc90d91452b (patch)
tree8d2bdb6d92c1ca207aab200d7bcae0d0be8a2539
parented7d2c87a983c5a7b555d7b8ef50919571195ef6 (diff)
downloadgit-sonar-e20e27ffa8a048068fd8d66b2b6a5bc90d91452b.tar.gz
git-sonar-e20e27ffa8a048068fd8d66b2b6a5bc90d91452b.zip
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 <m@lfurio.us>
Diffstat (limited to '')
-rwxr-xr-xgit-precheck74
1 files changed, 41 insertions, 33 deletions
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