Merge branch 'master' into rorcz
[girocco.git] / jobd / generate-auto-gc-update.sh
blobb6685c3ba694c79bc70dd1ec6476b8ab57075677
1 #!/bin/sh
3 # This script is designed to be run either directly giving it a project
4 # name or by being sourced from one of the other scripts.
6 # When sourced from another script the current directory must be set
7 # to the top-level --git-dir of the project to operate on and the
8 # _shlib_done variable must be set to 1 and then after sourcing the
9 # generate_auto_gc_update function must be called
11 # If GIROCCO_SUPPRESS_AUTO_GC_UPDATE is set to a non-zero value then this
12 # script will always exit immediately with success without doing anything
14 if [ -z "$_shlib_done" ]; then
15 [ "${GIROCCO_SUPPRESS_AUTO_GC_UPDATE:-0}" = "0" ] || exit 0
17 . @basedir@/shlib.sh
19 set -e
21 if [ $# -ne 1 ]; then
22 echo "Usage: generate-auto-gc-update.sh projname" >&2
23 exit 1
26 proj="${1%.git}"
27 shift
28 cd "$cfg_reporoot/$proj.git"
29 unset GIROCCO_SUPPRESS_AUTO_GC_UPDATE
32 # See the table from maintain-auto-gc-hack.sh
33 # We test the same conditions here
34 generate_auto_gc_update() {
35 [ "${GIROCCO_SUPPRESS_AUTO_GC_UPDATE:-0}" = "0" ] || return 0
36 _hackon=
38 [ "${cfg_autogchack:-0}" != "0" ] &&
39 { [ "$cfg_autogchack" != "mirror" ] || ! [ -e .nofetch ]; } &&
40 [ "$(git config --get --bool girocco.autogchack 2>/dev/null)" != "false" ]
41 then
42 _hackon=1
44 [ -n "$_hackon" ] || return 0
45 # It's not our responsibility to create the initial .refs-last file
46 # But we do need one, so make sure it exists
47 [ -f .refs-last ] || >>.refs-last
48 # This works like a combination of update.sh and pre-receive and post-receive
49 git for-each-ref --format '%(refname) %(objectname)' | LC_ALL=C sort -b -k1,1 >.refs-new.$$
50 refschanged=
51 cmp -s .refs-last .refs-new.$$ || refschanged=1
52 sockpath="$cfg_chroot/etc/taskd.socket"
53 if [ -n "$refschanged" ]; then
54 config_set lastreceive "$(date '+%a, %d %b %Y %T %z')"
55 # See comments in hooks/pre-receive about this
56 lognamets="$(TZ=UTC strftime '%Y%m%d_%H%M%S%N')"
57 lognamets="${lognamets%???}"
58 loghhmmss="${lognamets##*_}"
59 loghhmmss="${loghhmmss%??????}"
60 logname="reflogs/$lognamets.$$"
61 lognametmp="reflogs/tmp_$lognamets.$$"
62 v_get_proj_from_dir proj && proj="${proj%.git}"
64 echo "ref-changes %@local% $proj"
65 LC_ALL=C join .refs-last .refs-new.$$ |
66 LC_ALL=C sed -e '/^[^ ][^ ]* \([^ ][^ ]*\) \1$/d' |
67 while read ref old new; do
68 echo "$loghhmmss $old $new $ref" >&3
69 echo "$old $new $ref"
70 done
71 LC_ALL=C join -v 1 .refs-last .refs-new.$$ |
72 while read ref old; do
73 echo "$loghhmmss $old 0000000000000000000000000000000000000000 $ref" >&3
74 echo "$old 0000000000000000000000000000000000000000 $ref"
75 done
76 LC_ALL=C join -v 2 .refs-last .refs-new.$$ |
77 while read ref new; do
78 echo "$loghhmmss 0000000000000000000000000000000000000000 $new $ref" >&3
79 echo "0000000000000000000000000000000000000000 $new $ref"
80 done
81 LC_ALL=C join .refs-last .refs-new.$$ |
82 LC_ALL=C sed -ne '/^refs\/heads\/[^ ][^ ]* \([^ ][^ ]*\) \1$/p' |
83 while read ref old new; do
84 echo "$old $new $ref"
85 done
86 echo "done ref-changes %@local% $proj"
87 } >.refs-temp.$$ 3>>"$lognametmp"
88 mv "$lognametmp" "$logname"
89 if [ -S "$sockpath" ]; then
90 trap ':' PIPE
91 nc_openbsd -w 15 -U "$sockpath" <.refs-temp.$$ || :
92 trap - PIPE
94 mv -f .refs-new.$$ .refs-last
95 config_set lastchange "$(date '+%a, %d %b %Y %T %z')"
96 git for-each-ref --sort=-committerdate --format='%(committerdate:iso8601)' \
97 --count=1 refs/heads >info/lastactivity
98 ! [ -d htmlcache ] || { >htmlcache/changed; } 2>/dev/null || :
99 check_and_set_needsgc
100 rm -f .delaygc .allowgc
102 rm -f .refs-new.$$ .refs-temp.$$
105 [ -n "$_shlib_done" ] || generate_auto_gc_update