summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rwxr-xr-xgit-precheck94
-rwxr-xr-xgit-sonar31
3 files changed, 120 insertions, 11 deletions
diff --git a/Makefile b/Makefile
index 95538ac..6edd7f4 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-SOURCE=git-sonar
+SOURCE=git-sonar git-precheck
PREFIX?=/usr/local
PWD=$(shell pwd)
@@ -21,7 +21,9 @@ install: $(SOURCE)
mkdir -p $(PREFIX)/bin
install -m 755 $(SOURCE) $(PREFIX)/bin
+# Link each file separately since the full PWD is needed
develop: $(SOURCE)
@echo 'Symlinking in' $(PREFIX)/bin '...'
mkdir -p $(PREFIX)/bin
- ln -sf $(PWD)/$(SOURCE) $(PREFIX)/bin
+ ln -sf $(PWD)/git-sonar $(PREFIX)/bin
+ ln -sf $(PWD)/git-precheck $(PREFIX)/bin
diff --git a/git-precheck b/git-precheck
new file mode 100755
index 0000000..9984bbb
--- /dev/null
+++ b/git-precheck
@@ -0,0 +1,94 @@
+#!/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 the"
+ echo "condition."
+ 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=""
+ignore_dirty=""
+ignore_untracked=""
+
+while true; do
+ case "$1" in
+ --quiet) quiet="true" ;;
+ --ignore-dirty) ignore_dirty="true" ;;
+ --ignore-untracked) ignore_untracked="true" ;;
+ --help) usage ;;
+ -h) usage ;;
+ *) break
+ esac
+ shift
+done
+
+if [ $# -ne 0 ]; then
+ printf 'precheck: Unrecognized option given: %s\n' "$1"
+ 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
+}
+
+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'
+ exit 4
+fi
+
+check MERGE_HEAD Merge
+check REBASE_HEAD Rebase
+check REVERT_HEAD Revert
+check CHERRY_PICK_HEAD Cherry-pick
+check BISECT_EXPECTED_REV Bisect
+
+if [ -e "$(git rev-parse --git-path rebase-apply 2>/dev/null)" ]; then
+ [ -z "$quiet" ] && printf '\e[0;31mrebase-apply (am) found\e[0m\n'
+ exit 3
+fi
+
+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
+ 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
+ fi
+fi
+
+exit 0
diff --git a/git-sonar b/git-sonar
index f957b73..a610d14 100755
--- a/git-sonar
+++ b/git-sonar
@@ -49,18 +49,21 @@ prepare_colors() {
COLOR_CHANGES_CONFLICTED="\x01${GIT_RADAR_COLOR_CHANGES_CONFLICTED:-"\\033[1;33m"}\x02"
COLOR_CHANGES_UNTRACKED="\x01${GIT_RADAR_COLOR_CHANGES_UNTRACKED:-"\\033[1;37m"}\x02"
+ COLOR_CONDITION="\x01${GIT_RADAR_COLOR_CONDITION:-"\\033[1;33m"}\x02"
+
COLOR_STASH="\x01${GIT_RADAR_COLOR_STASH:-"\\033[1;33m"}\x02"
COLOR_BRANCH="\x01${GIT_RADAR_COLOR_BRANCH:-"\\033[0m"}\x02"
MASTER_SYMBOL="${GIT_RADAR_MASTER_SYMBOL:-"\\x01\\033[0m\\x02\\xF0\\x9D\\x98\\xAE\\x01\\033[0m\\x02"}"
- PROMPT_FORMAT="${GIT_RADAR_FORMAT:-" \\x01\\033[1;30m\\x02git:(\\x01\\033[0m\\x02%{remote: }%{branch}%{ :local}\\x01\\033[1;30m\\x02)\\x01\\033[0m\\x02%{ :stash}%{ :changes}"}"
+ PROMPT_FORMAT="${GIT_RADAR_FORMAT:-" \\x01\\033[1;30m\\x02git:(\\x01\\033[0m\\x02%{remote: }%{condition}%{branch}%{ :local}\\x01\\033[1;30m\\x02)\\x01\\033[0m\\x02%{ :stash}%{ :changes}"}"
RESET_COLOR_LOCAL="\x01${GIT_RADAR_COLOR_LOCAL_RESET:-"\\033[0m"}\x02"
RESET_COLOR_REMOTE="\x01${GIT_RADAR_COLOR_REMOTE_RESET:-"\\033[0m"}\x02"
RESET_COLOR_CHANGES="\x01${GIT_RADAR_COLOR_CHANGES_RESET:-"\\033[0m"}\x02"
RESET_COLOR_BRANCH="\x01${GIT_RADAR_COLOR_BRANCH_RESET:-"\\033[0m"}\x02"
RESET_COLOR_STASH="\x01${GIT_RADAR_COLOR_STASH_RESET:-"\\033[0m"}\x02"
+ RESET_COLOR_CONDITION="\x01${GIT_RADAR_COLOR_CONDITION_RESET:-"\\033[0m"}\x02"
}
@@ -90,11 +93,8 @@ dot_git() {
}
is_repo() {
- if [[ -n "$(dot_git)" ]]; then
- return 0
- else
- return 1
- fi
+ git-precheck --quiet
+ [ $? -lt 4 ]
}
record_timestamp() {
@@ -453,8 +453,12 @@ stash_status() {
fi
}
+repo_special_condition() {
+ git-precheck --quiet --ignore-dirty --ignore-untracked \
+ || printf "$COLOR_CONDITION!$RESET_COLOR_CONDITION"
+}
+
render_prompt() {
- output="$PROMPT_FORMAT"
branch_sed=""
remote_sed=""
local_sed=""
@@ -467,7 +471,15 @@ render_prompt() {
sed_pre="%{\(\([^%^{^}]*\)\:\)\{0,1\}"
sed_post="\(\:\([^%^{^}]*\)\)\{0,1\}}"
- if [[ $output =~ ${if_pre}remote${if_post} ]]; then
+ if [[ $PROMPT_FORMAT =~ ${if_pre}condition${if_post} ]]; then
+ condition_result="$(repo_special_condition)"
+ if [[ -n "$condition_result" ]]; then
+ condition_sed="s/${sed_pre}condition${sed_post}/\2${condition_result}\4/"
+ else
+ condition_sed="s/${sed_pre}condition${sed_post}//"
+ fi
+ fi
+ if [[ $PROMPT_FORMAT =~ ${if_pre}remote${if_post} ]]; then
remote_result="$(color_remote_commits)"
if [[ -n "$remote_result" ]]; then
remote_sed="s/${sed_pre}remote${sed_post}/\2${remote_result}\4/"
@@ -508,7 +520,8 @@ render_prompt() {
fi
fi
- printf '%b' "$output" | sed \
+ printf '%b' "$PROMPT_FORMAT" | sed \
+ -e "$condition_sed" \
-e "$remote_sed" \
-e "$branch_sed" \
-e "$changes_sed" \