summaryrefslogtreecommitdiffstats
path: root/git-precheck
blob: 9984bbb4e46276f150e3caf5dfdd12dcff96ffa1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
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