hooks: work around worktree wierdness
[girocco.git] / toolbox / update-all-hooks.sh
blob30a37617faf500dbcbe19930b23288972fcbd532
1 #!/bin/sh
3 # Update all out-of-date hooks in all current projects and install missing ones
5 # If one or more project names are given, just update those instead
7 set -e
9 . @basedir@/shlib.sh
11 force=
12 dryrun=
13 [ "$1" != "--force" ] && [ "$1" != "-f" ] || { force=1; shift; }
14 [ "$1" != "--dry-run" ] && [ "$1" != "-n" ] || { dryrun=1; shift; }
15 case "$1" in -*) echo "Invalid options: $1" >&2; exit 1;; esac
17 if is_root; then
18 printf '%s\n' "$(basename "$0"): refusing to run as root -- bad things would happen"
19 exit 1
22 umask 002
24 relocate=\
25 '# Make sure the current directory is where we expect to be
26 [ "${GIT_DIR+set}" != "set" ] || cd "${GIT_DIR:-.}" || exit 1
27 case "${PWD%/*}" in */worktrees)
28 # Gah!
30 # But it COULD just be a coincidence...
31 [ -s commondir ] && [ -s HEAD ] &&
32 _cmndir= && read -r _cmndir <commondir 2>/dev/null &&
33 [ -n "$_cmndir" ] && [ -d "$_cmndir" ]
34 then
35 # ...it is not, fix it!
36 cd "$_cmndir" || exit 1
38 esac
39 [ "${GIT_DIR+set}" != "set" ] || GIT_DIR="."'
41 write_mob_hook() {
42 echo '#!'@shbin@
43 printf '%s\n' "$relocate"
44 echo "cd .. && GIT_DIR=. GIROCCO_PERSONAL_MOB=1 exec hooks/$1"
47 base="${cfg_reporoot%/}"
48 hookbin="$cfg_basedir/hooks"
49 cmd='cut -d : -f 1 <"$cfg_chroot/etc/group" | grep -v ^_repo'
50 [ $# -eq 0 ] || cmd='printf "%s\n" "$@"'
51 eval "$cmd" |
53 while read -r proj; do
54 proj="${proj#$base/}"
55 proj="${proj%.git}"
56 projdir="$base/$proj.git"
57 [ -d "$projdir" ] || { echo "$proj: does not exist -- skipping"; continue; }
58 ! [ -e "$projdir/.nohooks" ] || { echo "$proj: .nohooks found -- skipping"; continue; }
59 updates=
60 for hook in pre-receive post-receive update; do
61 if [ -f "$projdir/hooks/$hook" ]; then
62 if ! cmp -s "$hookbin/$hook" "$projdir/hooks/$hook"; then
63 [ -n "$dryrun" ] || cat "$hookbin/$hook" >"$projdir/hooks/$hook"
64 updates="$updates $hook"
66 elif ! [ -e "$projdir/hooks/$hook" ]; then
67 [ -n "$dryrun" ] || [ -d "$projdir/hooks" ] || mkdir "$projdir/hooks"
68 [ -n "$dryrun" ] || cat "$hookbin/$hook" >"$projdir/hooks/$hook"
69 [ -n "$dryrun" ] || chmod 0775 "$projdir/hooks/$hook"
70 updates="$updates +$hook"
72 done
73 if [ -d "$projdir/mob/hooks" ]; then
74 for hook in pre-receive post-receive; do
75 if [ -f "$projdir/mob/hooks/$hook" ]; then
76 if ! write_mob_hook "$hook" | cmp -s - "$projdir/mob/hooks/$hook"; then
77 [ -n "$dryrun" ] || write_mob_hook "$hook" >"$projdir/mob/hooks/$hook"
78 updates="$updates mob/$hook"
80 elif ! [ -e "$projdir/mob/hooks/$hook" ]; then
81 [ -n "$dryrun" ] || write_mob_hook "$hook" >"$projdir/mob/hooks/$hook"
82 [ -n "$dryrun" ] || chmod 0775 "$projdir/mob/hooks/$hook"
83 updates="$updates +mob/$hook"
85 done
86 if ! [ -x "$projdir/mob/hooks/update" ]; then
87 [ -n "$dryrun" ] || ln -sfn ../../hooks/update "$projdir/mob/hooks/update"
88 updates="$updates +mob/update"
91 for hook in post-update; do
92 if [ -e "$projdir/hooks/$hook" ]; then
93 [ -n "$dryrun" ] || rm -f "$projdir/hooks/$hook"
94 updates="$updates -$hook"
96 done
97 if [ -d "$projdir/mob/hooks" ]; then
98 for hook in post-update; do
99 if [ -e "$projdir/mob/hooks/$hook" ]; then
100 [ -n "$dryrun" ] || rm -f "$projdir/mob/hooks/$hook"
101 updates="$updates -mob/$hook"
103 done
105 added=
106 while read -r fixfilex; do
107 case "$fixfilex" in ""|*.sample) :;; *)
108 #[ -n "$added" ] || { added=1; updates="$updates a+rx"; }
109 #[ -n "$dryrun" ] || chmod a+rx "$projdir/$fixfilex"
111 esac
112 done <<-EOT
113 $(cd "$projdir"
114 # find -P is not POSIX (it is the default though) but we absolutely
115 # do NOT want either -H or -L here because if either the directory or
116 # the hook itself is a symbolic link we have no business changing it!
117 ! [ -d hooks ] || find hooks -xdev -type f ! -perm -a+rx -print
118 ! [ -d mob/hooks ] || find mob/hooks -xdev -type f ! -perm -a+rx -print)
120 [ -z "$updates" ] || echo "$proj:$updates" ${dryrun:+(dryrun)}
121 done