blob: e7595378e3218522327efb38c6b0f4fbf0e310ce (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#!/bin/sh

# Updates the age-file cgit reads for the idle column. The path below is the
# default age-file, so a cgitrc that changes the setting needs the same change
# here. A file the pusher cannot write stays as it was, and nothing here
# complains or exits nonzero, so the pusher is not shown an error over a stale
# idle column.
#
# To install the hook, copy or link it to hooks/post-receive in each
# repository. Git runs one post-receive per repository, so fold this together
# with the other hooks here to have more than one.

set -eu

# The pushing user's umask decides the mode of a freshly written agefile, so
# force one that leaves the file readable by the web server. A repository
# shared with a group, which git keeps group writable, keeps the directory
# that way too, or the next member to push could not replace the file.
case "$(git config --get core.sharedRepository | tr '[:upper:]' '[:lower:]')" in
""|umask|0|false|no|off)
	umask 022
	;;
*)
	umask 002
	;;
esac

agefile="$(git rev-parse --git-dir)"/info/web/last-modified

# Committer dates rather than author dates, so a push of rebased or imported
# history still counts as recent activity. Branch tips only, since an annotated
# tag carries no committer date of its own and would sort in as an empty line.
date="$(git for-each-ref --sort=-committerdate --count=1 \
	--format='%(committerdate:iso8601)' refs/heads/)"

# A repository with no branches keeps whatever cgit already had, rather than
# being handed an empty file.
test -n "$date" || exit 0

mkdir -p "$(dirname "$agefile")" 2>/dev/null || exit 0

# Write through a temporary file so a reader never sees a half written date.
tmpfile="$agefile.$$"
trap 'rm -f "$tmpfile"' EXIT
{ printf '%s\n' "$date" >"$tmpfile"; } 2>/dev/null || exit 0
mv "$tmpfile" "$agefile" 2>/dev/null || :