summaryrefslogtreecommitdiffstats
blob: 75c9705a95975fea060439f11ba28f12fea62dcb (plain)
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#!/bin/sh

# https://bugs.eclipse.org/362363 : Better policy ... provide hooks to allow a committer to delete <userid>/branchname branches
# Latest version is at http://git.eclipse.org/c/e4/org.eclipse.e4.releng.git/tree/org.eclipse.e4.builder/scripts/pre-receive

#
#	For each ref, validate the commit.
#
validate_ref()
{
	# --- Arguments
	oldrev=$(git rev-parse $1)
	newrev=$(git rev-parse $2)
	refname="$3"

	allownonffpush=$( git config --bool hooks.allownonffpush )
	allowdeletebranch=$( git config --bool hooks.allowdeletebranch )
	allowdeletetag=$( git config --bool hooks.allowdeletetag )
	allowcreatenottopicbranch=$( git config --bool hooks.allowcreatenottopicbranch )
	# oldrev could be 0s which means creating refname
	# newrev could be 0s which means deleting refname

	case "$refname" in
		refs/heads/*)
			branch=$(expr "$refname" : "refs/heads/\(.*\)")
			topicbranch=$(expr "$branch" : "\(.*/.*\)")
			topicuser=$(expr "$branch" : "\([^/]*\)/.*")
			if [ 0 -ne $(expr "$newrev" : "0*$") ]; then # deleting
				# only topic branches can be deleted
				if [ "$allowdeletebranch" != "true" -a -z "$topicbranch" ]; then
					fail=1
					echo >&2 "*** Deleting the branch $branch is not permitted. ***"
					return
				fi
				if [  "$allowdeletebranch" != "true" -a "$USER" != "$topicuser" ]; then
					fail=1
					echo >&2 "*** Deleting the branch $branch is not permitted by $USER. ***"
					return
				fi
				return # Don't need to validate old revision
			else #updating
				if [ 0 -ne $(expr "$oldrev" : "0*$") ]; then # pushing a new branch
					if [ "$allowcreatenottopicbranch" != "true" -a -z "$topicbranch" ]; then
						fail=1
						echo >&2 "*** creation of branch $branch is not permitted. Use <committerId>/<branchname> for topic branches, or ask your project lead or PMC to temporarily set hooks.allowcreatenottopicbranch to true. ***"
					fi
					return # it's not a FF merge
				fi
				if [ $oldrev != $(git merge-base $oldrev $newrev) ]; then # non fast-forward
					# only topic branches can be non fast-forwarded
					if [ "$allownonffpush" != "true" -a -z "$topicbranch" ]; then
						fail=1
						echo >&2 "*** Non fast-forward of branch $branch is not permitted. Use <committerId>/<branchname> for topic branches, or ask your project lead or PMC to temporarily set hooks.allownonffpush to true. ***"
						return
					fi
					if [  "$allownonffpush" != "true" -a "$USER" != "$topicuser" ]; then
						fail=1
						echo >&2 "*** Non fast-forward of branch $branch is not permitted by $USER. ***"
						return
					fi
				fi
			fi
			;;
		refs/tags/*)
		    tag=$(expr "$refname" : "refs/tags/\(.*\)")
			topictag=$(expr "$tag" : "\(.*/.*\)")
			topicuser=$(expr "$tag" : "\(.*\)/.*")
			if [ 0 -ne $(expr "$newrev" : "0*$") ]; then # deleting
				# only topic tags can be deleted
				if [ "$allowdeletetag" != "true" -a -z "$topictag" ]; then
					fail=1
					echo >&2 "*** Deleting the tag $tag is not permitted. ***"
					return
				fi
				if [  "$allowdeletetag" != "true" -a "$USER" != "$topicuser" ]; then
					fail=1
					echo >&2 "*** Deleting the tag $tag is not permitted by $USER. ***"
					return
				fi
				return
			fi
			;;
		*)
			fail=1
			echo >&2 "*** pre-receive hook does not understand ref $refname in this repository. ***"
			echo >&2 "*** Contact the repository administrator. ***"
			;;
	esac
}

fail=""

# Allow dual mode: run from the command line just like the update hook, or
# if no arguments are given then run as a hook script
if [ -n "$1" -a -n "$2" -a -n "$3" ]; then
	# Output to the terminal in command line mode - if someone wanted to
	# resend an email; they could redirect the output to sendmail
	# themselves
	PAGER= validate_ref $2 $3 $1
else
	while read oldrev newrev refname
	do
		validate_ref $oldrev $newrev $refname
	done
fi

if [ -n "$fail" ]; then
	exit $fail
fi