-
Notifications
You must be signed in to change notification settings - Fork 11
/
git-safe-push-to-checkout
executable file
·71 lines (57 loc) · 2.05 KB
/
git-safe-push-to-checkout
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
#!/bin/bash
# Smarter push-to-checkout hook for when receive.denyCurrentBranch is
# set to updateInstead. It's near-identical to git's default
# behaviour when no push-to-checkout hook is provided; however it
# additionally bails if we have emacs lockfiles indicating edits in
# progress for files which would be changed by the push-to-checkout.
#
# This means that push-to-checkout works more safely and doesn't rewrite
# files which are currently being edited in emacs with unsaved changes.
commit="$1"
#echo "push-to-checkout $commit"
die () {
echo >&2 "$*"
exit 1
}
if ! git cat-file -t HEAD >&/dev/null; then
die "No history yet"
fi
# The below is a more-or-less exact translation to shell of the C code for
# the default behaviour for git's push-to-checkout hook defined in the
# push_to_deploy() function in builtin/receive-pack.c
#
# However it additionally bails if we have emacs lockfiles indicating
# edits in progress for files which would be changed by the push-to-checkout.
if ! git update-index -q --ignore-submodules --refresh; then
die "Up-to-date check failed"
fi
if ! git diff-files --quiet --ignore-submodules --; then
die "Working directory has unstaged changes"
fi
# This is a rough translation of:
#
# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX
if git cat-file -t HEAD >&/dev/null; then
head=HEAD
else
head=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
if ! git diff-index --quiet --cached --ignore-submodules $head --; then
die "Working directory has staged changes"
fi
if [[ "`pwd`" == */.git ]]; then
# Not a bare repo; check for emacs lockfiles
#git diff-tree HEAD $commit --
cd ..
while read srcmode dstmode src dst status src dst; do
if [ -L ".#$src" ]; then
die "emacs lockfile present for $src; can't update"
fi
if [ -n "$dst" -a -L ".#$dst" ]; then
die "emacs lockfile present for $dst; can't update"
fi
done < <(git diff-tree HEAD $commit --)
fi
if ! git read-tree -u -m $commit; then
die "Could not update working tree to new HEAD"
fi