-
Notifications
You must be signed in to change notification settings - Fork 0
/
pre-commit
executable file
·90 lines (75 loc) · 3.22 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
#!/bin/sh
# configure automatically sets up a wrapper at .git/hooks/pre-commit
# which calls this script (if it exists).
set -e
dev/tools/check-overlays.sh
# Can we check and fix formatting?
# NB: we will ignore errors from ocamlformat as it fails when
# encountering OCaml syntax errors
ocamlformat=$(command -v ocamlformat || echo true)
if [ "$ocamlformat" = true ]
then
1>&2 echo "Warning: ocamlformat is not in path. Cannot check formatting."
fi
# Verify that the version of ocamlformat matches the one in .ocamlformat
# The following command will print an error message if that's not the case
# (and will print nothing if the versions match)
if ! echo "let () = ()" | "$ocamlformat" --impl - > /dev/null
then
1>&2 echo "Warning: Cannot check formatting."
ocamlformat=true
fi
1>&2 echo "Auto fixing whitespace and formatting issues..."
# We fix whitespace in the index and in the working tree
# separately to preserve non-added changes.
index=$(mktemp "git-fix-ws-index.XXXXXX")
fixed_index=$(mktemp "git-fix-ws-index-fixed.XXXXXX")
tree=$(mktemp "git-fix-ws-tree.XXXXXX")
1>&2 echo "Patches are saved in '$index', '$fixed_index' and '$tree'."
1>&2 echo "If an error destroys your changes you can recover using them."
1>&2 echo "(The files are cleaned up on success.)"
1>&2 echo #newline
git diff-index -p --cached HEAD > "$index"
git diff-index -p HEAD > "$tree"
# reset work tree and index
# NB: untracked files which were not added are untouched
if [ -s "$index" ]; then git apply --whitespace=nowarn --cached -R "$index"; fi
if [ -s "$tree" ]; then git apply --whitespace=nowarn -R "$tree"; fi
# Fix index
# For end of file newlines we must go through the worktree
if [ -s "$index" ]; then
1>&2 echo "Fixing staged changes..."
git apply --cached --whitespace=fix "$index"
git apply --whitespace=fix "$index" 2>/dev/null # no need to repeat yourself
git diff --cached --name-only -z | xargs -0 dev/tools/check-eof-newline.sh --fix
{ git diff --cached --name-only -z | grep -E '.*\.mli?$' -z | xargs -0 "$ocamlformat" -i || true; } 2> /dev/null
git add -u
1>&2 echo #newline
fi
# reset work tree
git diff-index -p --cached HEAD > "$fixed_index"
# If all changes were bad whitespace changes the patch is empty
# making git fail. Don't fail now: we fix the worktree first.
if [ -s "$fixed_index" ]; then git apply --whitespace=nowarn -R "$fixed_index"; fi
# Fix worktree
if [ -s "$tree" ]; then
1>&2 echo "Fixing unstaged changes..."
git apply --whitespace=fix "$tree"
git diff --name-only -z | xargs -0 dev/tools/check-eof-newline.sh --fix
{ git diff --name-only -z | grep -E '.*\.mli?$' -z | xargs -0 "$ocamlformat" -i || true; } 2> /dev/null
1>&2 echo #newline
fi
if [ -s "$index" ] && ! [ -s "$fixed_index" ]; then
1>&2 echo "Fixing whitespace and formatting issues cancelled all changes."
exit 1
fi
# Check that we did fix whitespace
if ! git diff-index --check --cached HEAD; then
1>&2 echo "Auto-fixing whitespace failed: errors remain."
1>&2 echo "This may fix itself if you try again."
1>&2 echo "(Consider whether the number of errors decreases after each run.)"
exit 1
fi
1>&2 echo "Whitespace and formatting pass complete."
# clean up temporary files
rm "$index" "$tree" "$fixed_index"