hooks: detect ref changes at gc --auto time
[girocco/readme.git] / hooks / post-receive
blob846bdc42ea9e370dc6ff942148999a9ae7fa90ea
1 #!/bin/sh
3 # Keep lastactivity and personal mob (if enabled) up-to-date
4 # We use receive.updateserverinfo=true so no need to run update-server-info
5 # Send notification through the taskd socket if it exists and not personal mob push
7 # Beware, we MAY be running in a chroot!
9 set -e
11 # Make sure the current directory is where we expect to be
12 [ "${GIT_DIR+set}" != "set" ] || cd "${GIT_DIR:-.}" || exit 1
13 case "${PWD%/*}" in */worktrees)
14 # Gah!
16 # But it COULD just be a coincidence...
17 [ -s commondir ] && [ -s HEAD ] &&
18 _cmndir= && read -r _cmndir <commondir 2>/dev/null &&
19 [ -n "$_cmndir" ] && [ -d "$_cmndir" ]
20 then
21 # ...it is not, fix it!
22 cd "$_cmndir" || exit 1
24 esac
25 [ "${GIT_DIR+set}" != "set" ] || GIT_DIR="."
27 # Get out of the mob
28 case "$PWD" in *?/mob)
29 cd ..
30 GIROCCO_PERSONAL_MOB=1
31 esac
33 mob=@mob@
34 autogchack=@autogchack@
35 umask 002
36 git config gitweb.lastchange "$(date '+%a, %d %b %Y %T %z')" || :
37 git for-each-ref --sort=-committerdate --format='%(committerdate:iso8601)' \
38 --count=1 refs/heads >info/lastactivity || :
39 ! [ -d htmlcache ] || { >htmlcache/changed; } 2>/dev/null || :
40 rm -f .delaygc .allowgc
41 if [ "$mob" = "mob" ] && [ -d mob ]; then
42 git for-each-ref --format='%(objectname) %(refname)' >packed-refs.mob.$$ || :
43 mv -f packed-refs.mob.$$ packed-refs.mob
44 rm -f packed-refs.mob.$$
47 sockpath=/etc/taskd.socket
48 reporoot=/@jailreporoot@
49 authuser="$LOGNAME"
50 cwd="$(pwd -P)"
51 if [ -x @perlbin@ ]; then
52 # Not in chroot...
53 . @basedir@/shlib.sh
55 sockpath="$cfg_chroot$sockpath"
56 reporoot="$cfg_reporoot"
58 # authuser needs to be set if not running in the chroot.
59 # Currently that can only be the case with https push in
60 # which case REMOTE_USER will contain the user name (possibly prefixed
61 # with "/UID=" and suffixed with "/dnQualifier=...").
62 # Fallback is the mirror_user if REMOTE_USER is not set.
63 authuser="${REMOTE_USER#/UID=}"
64 authuser="${authuser%/dnQualifier=*}"
65 [ -n "$authuser" ] || authuser="%$cfg_mirror_user%"
66 else
67 # In chroot...
68 nc_openbsd() { /bin/nc.openbsd "$@"; }
70 reporoot="$(cd "$reporoot" && pwd -P)"
71 projname="${cwd#$reporoot/}"
74 [ "${autogchack:-0}" != "0" ] &&
75 { [ "$cfg_autogchack" != "mirror" ] || ! [ -e .nofetch ]; } &&
76 [ "$(git config --get --bool girocco.autogchack 2>/dev/null)" != "false" ]
77 then
78 git for-each-ref --format '%(refname) %(objectname)' | LC_ALL=C sort -b -k1,1 >.refs-new.$$
79 mv -f .refs-new.$$ .refs-last
80 rm -f .refs.new.$$
83 if [ -n "$GIROCCO_PERSONAL_MOB" ] || ! [ -S "$sockpath" ]; then
84 # We never run the ref update notification part on a personal mob push
85 # Read the incoming refs, but just ignore them (git doesn't like SIGPIPE)
86 while read -r line; do
88 done
89 else
91 trap ':' PIPE
92 echo "ref-changes $authuser ${projname%.git}" || :
93 while read -r line; do
94 echo "$line" || :
95 done
96 git for-each-ref --format='%(objectname) %(objectname) %(refname)' refs/heads || :
97 echo "done ref-changes $authuser ${projname%.git}" || :
98 ) 2>/dev/null | { nc_openbsd -w 15 -U "$sockpath" || :; } || :
101 exit 0