clone/update: mark project changed on failure
[girocco.git] / jobd / maintain-auto-gc-hack.sh
blob62858a30a3a234cd76584c82f9fa4be5897fe05a
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 # maintain_auto_gc_hack function must be called
11 if [ -z "$_shlib_done" ]; then
12 . @basedir@/shlib.sh
14 set -e
16 if [ $# -ne 1 ]; then
17 echo "Usage: maintain-auto-gc-hack.sh projname" >&2
18 exit 1
21 proj="${1%.git}"
22 shift
23 cd "$cfg_reporoot/$proj.git"
26 make_empty_git_pack() {
27 if ! [ -f "objects/pack/$1.idx" ] || ! [ -f "objects/pack/$1.pack" ]; then
28 rm -f "objects/pack/$1.idx" "objects/pack/$1.pack" || :
29 git pack-objects -q $opts --stdout </dev/null |
30 git index-pack --stdin "objects/pack/$1.pack" >/dev/null || :
32 ! [ -e "objects/pack/$1.keep" ] || rm -f "objects/pack/$1.keep" || :
35 # In order to get pre-auto-gc to run we maintain the following:
36 # 1) gc.auto=1
37 # 2) gc.autopacklimit=1
38 # 3) pre-auto-gc-1.pack (and .idx)
39 # 4) pre-auto-gc-2.pack (and .idx)
40 # In addition the following happens:
41 # 5) post-receive and update.sh keep .refs-last updated
43 # The current state pre-auto-gc hack is determined by the following:
45 # $Girocco::Config::autogchack | repository's girocco.autogchack config | state
46 # ---------------------------- | -------------------------------------- | -----
47 # mirror and .nofetch exists | don't care | off
48 # false | don't care | off
49 # true (or mirror w/o .nofetch)| true or unset | on
50 # true (or mirror w/o .nofetch)| false | off
52 # When $Girocco::Config::autogchack is the special value "mirror" it behaves
53 # as "false" when the .nofetch file exists and "true" when it does not.
55 # After determining what state we should be in, we make suitable adjustments
56 # if things are not set up properly including creating a .refs-last file
58 # Note that if the auto gc hack is disabled and nothing needs to be changed
59 # then only two read-only "git config" commands get run which makes this
60 # very low overhead considering it normally only runs at gc.sh time.
61 maintain_auto_gc_hack() {
62 _hackon=
64 [ "${cfg_autogchack:-0}" != "0" ] &&
65 { [ "$cfg_autogchack" != "mirror" ] || ! [ -e .nofetch ]; } &&
66 [ "$(git config --get --bool girocco.autogchack 2>/dev/null)" != "false" ]
67 then
68 _hackon=1
70 if [ -z "$_hackon" ]; then
71 # Make the hack be off, but still allow pre-auto-gc to run if there are
72 # enough loose objects or packs in order to ensure that .needsgc gets set
73 rm -f .refs-last
74 rm -f objects/pack/pre-auto-gc-?.idx objects/pack/pre-auto-gc-?.pack || :
75 [ "$(git config -f config --get gc.auto)" = "3000" ] || git config gc.auto 3000 || :
76 [ "$(git config -f config --get gc.autopacklimit)" = "25" ] || git config gc.autopacklimit 25 || :
77 else
78 # Make the hack be on
79 # This one may need a bit more work
80 # Do the .refs-last file first to make sure it's available
81 # before changing the settings that will cause pre-auto-gc to activate
82 if ! [ -e .refs-last ]; then
83 git for-each-ref --format '%(refname) %(objectname)' |
84 LC_ALL=C sort -b -k1,1 >.refs-new.$$ &&
85 mv -f .refs-new.$$ .refs-last || :
87 # Make sure at least two pack files exist; they MUST NOT
88 # have any associated .keep files for this to work!
89 make_empty_git_pack "pre-auto-gc-1" || :
90 make_empty_git_pack "pre-auto-gc-2" || :
91 # Finally activate auto gc
92 [ "$(git config -f config --get gc.autopacklimit)" = "1" ] || git config gc.autopacklimit 1 || :
93 [ "$(git config -f config --get gc.auto)" = "1" ] || git config gc.auto 1 || :
97 [ -n "$_shlib_done" ] || maintain_auto_gc_hack