cc-discipline 2.12.2 → 2.12.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -43,42 +43,62 @@ if echo "$CMD_NORM" | grep -qE 'hooks[/\\][a-z-]+\.sh'; then
|
|
|
43
43
|
exit 0
|
|
44
44
|
fi
|
|
45
45
|
|
|
46
|
+
# Blank out the CONTENT of message-style arguments before matching. A commit
|
|
47
|
+
# message that merely *describes* a destructive command is data — it can never
|
|
48
|
+
# execute — but the text match could not tell the difference, so writing about
|
|
49
|
+
# these commands blocked the commit:
|
|
50
|
+
# git commit -m "revert the git reset --hard change" -> must pass
|
|
51
|
+
# git commit -m "x" && git reset --hard -> must STILL block
|
|
52
|
+
#
|
|
53
|
+
# Only the argument to -m/--message/-F/--file is blanked, never quotes in
|
|
54
|
+
# general. Stripping all quoted text would open a real hole, because these DO
|
|
55
|
+
# execute what they quote and must keep matching:
|
|
56
|
+
# bash -c "git reset --hard" eval "git clean -fd" sudo git reset --hard
|
|
57
|
+
#
|
|
58
|
+
# Escaped quotes inside a message end the match early, leaving the tail to be
|
|
59
|
+
# scanned — that direction is a false positive (one wasted turn), never a miss.
|
|
60
|
+
SQ="'"
|
|
61
|
+
CMD_SCAN=$(printf '%s' "$CMD_NORM" \
|
|
62
|
+
| sed -E 's/(^|[[:space:]])(-m|--message|-F|--file)[[:space:]]*"[^"]*"/\1\2 ARG/g' \
|
|
63
|
+
| sed -E "s/(^|[[:space:]])(-m|--message|-F|--file)[[:space:]]*${SQ}[^${SQ}]*${SQ}/\1\2 ARG/g" \
|
|
64
|
+
| sed -E 's/(^|[[:space:]])(-m|--message|-F|--file)[[:space:]]+[^[:space:]]+/\1\2 ARG/g')
|
|
65
|
+
|
|
46
66
|
BLOCKED=""
|
|
47
67
|
SUGGESTION=""
|
|
48
68
|
|
|
49
69
|
# git checkout . / git checkout -- <file> (discard working tree changes)
|
|
50
70
|
# But allow: git checkout <branch>, git checkout -b <branch>
|
|
51
|
-
if echo "$
|
|
71
|
+
if echo "$CMD_SCAN" | grep -qE 'git\s+checkout\s+(\.|--\s)'; then
|
|
52
72
|
BLOCKED="git checkout (discards uncommitted changes)"
|
|
53
73
|
SUGGESTION="git stash"
|
|
54
74
|
fi
|
|
55
75
|
|
|
56
76
|
# git restore . / git restore <file> (without --staged)
|
|
57
|
-
if echo "$
|
|
77
|
+
if echo "$CMD_SCAN" | grep -qE 'git\s+restore\s' && ! echo "$CMD_SCAN" | grep -qE 'git\s+restore\s+--staged'; then
|
|
58
78
|
BLOCKED="git restore (discards uncommitted changes)"
|
|
59
79
|
SUGGESTION="git stash"
|
|
60
80
|
fi
|
|
61
81
|
|
|
62
82
|
# git reset --hard
|
|
63
|
-
if echo "$
|
|
83
|
+
if echo "$CMD_SCAN" | grep -qE 'git\s+reset\s+--hard'; then
|
|
64
84
|
BLOCKED="git reset --hard (destroys all uncommitted changes)"
|
|
65
85
|
SUGGESTION="git stash && git reset"
|
|
66
86
|
fi
|
|
67
87
|
|
|
68
88
|
# git clean -f / -fd / -fx
|
|
69
|
-
if echo "$
|
|
89
|
+
if echo "$CMD_SCAN" | grep -qE 'git\s+clean\s+-[a-z]*f'; then
|
|
70
90
|
BLOCKED="git clean -f (permanently deletes untracked files)"
|
|
71
91
|
SUGGESTION="git stash --include-untracked"
|
|
72
92
|
fi
|
|
73
93
|
|
|
74
94
|
# git branch -D (force delete unmerged branch)
|
|
75
|
-
if echo "$
|
|
95
|
+
if echo "$CMD_SCAN" | grep -qE 'git\s+branch\s+-D\s'; then
|
|
76
96
|
BLOCKED="git branch -D (deletes branch even if not merged)"
|
|
77
97
|
SUGGESTION="git branch -d (safe delete, fails if not merged)"
|
|
78
98
|
fi
|
|
79
99
|
|
|
80
100
|
# git push --force / -f (to main/master)
|
|
81
|
-
if echo "$
|
|
101
|
+
if echo "$CMD_SCAN" | grep -qE 'git\s+push\s+.*(-f|--force)' && echo "$CMD_SCAN" | grep -qE '(main|master)'; then
|
|
82
102
|
BLOCKED="git push --force to main/master (rewrites shared history)"
|
|
83
103
|
SUGGESTION="git push --force-with-lease"
|
|
84
104
|
fi
|