/
pre-commit
executable file
·100 lines (83 loc) · 2.61 KB
/
pre-commit
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
95
96
97
98
99
100
#!/bin/bash
: ${CXX_FORMAT:=clang-format}
: ${PY_FORMAT:=autopep8}
CXX_EXTS=".c .h .cpp .hpp .cc .hh .cxx .hxx"
PY_EXTS=".py"
command_exists() {
command -v $1 >/dev/null 2>&1
}
match_extension() {
local filename=$(basename $1)
local extension=".${filename##*.}"
local ext
for ext in $2; do [[ "$ext" == "$extension" ]] && return 0; done
return 1
}
get_patch() {
local reformatted=""
local file
patch=""
for file in $files; do
if match_extension $file "$CXX_EXTS"; then
reformatted=`$CXX_FORMAT -style=file $file`
elif match_extension $file "$PY_EXTS"; then
reformatted=`$PY_FORMAT $file`
else
continue
fi
# show colored version to the user
echo "$reformatted" | git --no-pager diff --no-index --color=always $file -
# ... and save non-colored patch for git-apply
file_diff=`echo "$reformatted" | diff -u $file - | \
sed -e "1s|--- |--- a/|" -e "2s|+++ -|+++ b/$file|"`
# diff output does not have a linefeed at the end.
# We need one if there are multiple diff outputs.
if [[ ! -z $file_diff ]]; then
patch+=$file_diff
patch+=$'\n'
fi
done
}
apply_and_commit() {
# The "git add" we use below do not work with non-default index file,
# which is used by "git commit -a" or "git commit <files>"
if [[ $GIT_INDEX_FILE != ".git/index" ]]; then
echo "Error: Non-default index file is being used (GIT_INDEX_FILE is set)." >&2
echo " Are you using 'git commit [--only] -- <files>' to bypass staging?" >&2
exit 1
fi
# Do some files have partial commits? (only some portion of a file is staged)
if [[ ! -z $(git diff -- $files) ]]; then
echo "Error: Partial commits are not supported." >&2
exit 1
fi
(echo "$patch" | git apply -)
git add -- $files
}
if ! command_exists $CXX_FORMAT; then
echo "Error: '$CXX_FORMAT' not found." >&2
echo " Use '--no-verify' to bypass format checker (not recommended)" >&2
exit 1
fi
if ! command_exists $PY_FORMAT; then
echo "Error: '$PY_FORMAT' not found. Try 'pip install $PY_FORMAT'?" >&2
echo " Use '--no-verify' to bypass format checker (not recommended)" >&2
exit 1
fi
# Allows us to read user input below, assigns stdin to keyboard
exec < /dev/tty
files=`git diff-index --cached --name-only HEAD`
get_patch
if [[ ! -z $patch ]]; then
echo "==========================================="
echo "Files in the commit do not comply with the formatting rules. Options:"
echo "y - commit without reformatting (not recommended)"
echo "r - apply the patch and commit"
echo "n - abort"
read -p "Do you want to commit anyway? [y/r/N] " yn
case $yn in
[Yy]* ) exit 0;;
[Rr]* ) apply_and_commit && exit 0;;
* ) exit 1;;
esac
fi