Skip to content

Commit e632c46

Browse files
aspiersgitster
authored andcommitted
hook: add sample template for push-to-checkout
The template 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, to serve as a convenient starting point for modification. It also contains relevant text extracted from the git-config(1) and githooks(5) man pages. Signed-off-by: Adam Spiers <git@adamspiers.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent a5fa49f commit e632c46

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#!/bin/sh
2+
3+
# An example hook script to update a checked-out tree on a git push.
4+
#
5+
# This hook is invoked by git-receive-pack(1) when it reacts to git
6+
# push and updates reference(s) in its repository, and when the push
7+
# tries to update the branch that is currently checked out and the
8+
# receive.denyCurrentBranch configuration variable is set to
9+
# updateInstead.
10+
#
11+
# By default, such a push is refused if the working tree and the index
12+
# of the remote repository has any difference from the currently
13+
# checked out commit; when both the working tree and the index match
14+
# the current commit, they are updated to match the newly pushed tip
15+
# of the branch. This hook is to be used to override the default
16+
# behaviour; however the code below reimplements the default behaviour
17+
# as a starting point for convenient modification.
18+
#
19+
# The hook receives the commit with which the tip of the current
20+
# branch is going to be updated:
21+
commit=$1
22+
23+
# It can exit with a non-zero status to refuse the push (when it does
24+
# so, it must not modify the index or the working tree).
25+
die () {
26+
echo >&2 "$*"
27+
exit 1
28+
}
29+
30+
# Or it can make any necessary changes to the working tree and to the
31+
# index to bring them to the desired state when the tip of the current
32+
# branch is updated to the new commit, and exit with a zero status.
33+
#
34+
# For example, the hook can simply run git read-tree -u -m HEAD "$1"
35+
# in order to emulate git fetch that is run in the reverse direction
36+
# with git push, as the two-tree form of git read-tree -u -m is
37+
# essentially the same as git switch or git checkout that switches
38+
# branches while keeping the local changes in the working tree that do
39+
# not interfere with the difference between the branches.
40+
41+
# The below is a more-or-less exact translation to shell of the C code
42+
# for the default behaviour for git's push-to-checkout hook defined in
43+
# the push_to_deploy() function in builtin/receive-pack.c.
44+
#
45+
# Note that the hook will be executed from the repository directory,
46+
# not from the working tree, so if you want to perform operations on
47+
# the working tree, you will have to adapt your code accordingly, e.g.
48+
# by adding "cd .." or using relative paths.
49+
50+
if ! git update-index -q --ignore-submodules --refresh
51+
then
52+
die "Up-to-date check failed"
53+
fi
54+
55+
if ! git diff-files --quiet --ignore-submodules --
56+
then
57+
die "Working directory has unstaged changes"
58+
fi
59+
60+
# This is a rough translation of:
61+
#
62+
# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX
63+
if git cat-file -e HEAD 2>/dev/null
64+
then
65+
head=HEAD
66+
else
67+
head=$(git hash-object -t tree --stdin </dev/null)
68+
fi
69+
70+
if ! git diff-index --quiet --cached --ignore-submodules $head --
71+
then
72+
die "Working directory has staged changes"
73+
fi
74+
75+
if ! git read-tree -u -m "$commit"
76+
then
77+
die "Could not update working tree to new HEAD"
78+
fi

0 commit comments

Comments
 (0)