Skip to content

Commit 488d346

Browse files
jeblairtechknowlogick
authored andcommitted
Ignore non-standard refs in git push (#6758)
When replicating to gitea from a remote system which makes use of git refs to store extra data (for example, gerrit), pushing a lot of refs to gitea can cause problems due to the extra processing that the pre and post receive hooks perform. But it's still useful for gitea to be able to serve those refs. This change skips unecessary processing of refs other than branches or tags. We don't need to check any ref that isn't a branch for branch protection (protection will never be enabled). So in the pre-receive hook, we wrap that check in a test for whether the ref is a branch. We also don't need to add information to the activity stream about pushes to non-standard refs, so we skip that step in the post-receive hook for refs which are not branches or tags. For some concrete examples, gerrit maintains a ref for every patchset of every change in the form refs/changes/XX/YYYY/Z. Many systems use refs/notes to store additonal data about commits. This change allows these and other schemes to be used without affecting gitea.
1 parent 24a536d commit 488d346

File tree

1 file changed

+43
-34
lines changed

1 file changed

+43
-34
lines changed

cmd/hook.go

Lines changed: 43 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -89,34 +89,37 @@ func runHookPreReceive(c *cli.Context) error {
8989
newCommitID := string(fields[1])
9090
refFullName := string(fields[2])
9191

92-
branchName := strings.TrimPrefix(refFullName, git.BranchPrefix)
93-
protectBranch, err := private.GetProtectedBranchBy(repoID, branchName)
94-
if err != nil {
95-
fail("Internal error", fmt.Sprintf("retrieve protected branches information failed: %v", err))
96-
}
97-
98-
if protectBranch != nil && protectBranch.IsProtected() {
99-
// check and deletion
100-
if newCommitID == git.EmptySHA {
101-
fail(fmt.Sprintf("branch %s is protected from deletion", branchName), "")
92+
// If the ref is a branch, check if it's protected
93+
if strings.HasPrefix(refFullName, git.BranchPrefix) {
94+
branchName := strings.TrimPrefix(refFullName, git.BranchPrefix)
95+
protectBranch, err := private.GetProtectedBranchBy(repoID, branchName)
96+
if err != nil {
97+
fail("Internal error", fmt.Sprintf("retrieve protected branches information failed: %v", err))
10298
}
10399

104-
// detect force push
105-
if git.EmptySHA != oldCommitID {
106-
output, err := git.NewCommand("rev-list", "--max-count=1", oldCommitID, "^"+newCommitID).RunInDir(repoPath)
107-
if err != nil {
108-
fail("Internal error", "Fail to detect force push: %v", err)
109-
} else if len(output) > 0 {
110-
fail(fmt.Sprintf("branch %s is protected from force push", branchName), "")
100+
if protectBranch != nil && protectBranch.IsProtected() {
101+
// check and deletion
102+
if newCommitID == git.EmptySHA {
103+
fail(fmt.Sprintf("branch %s is protected from deletion", branchName), "")
111104
}
112-
}
113105

114-
userID, _ := strconv.ParseInt(userIDStr, 10, 64)
115-
canPush, err := private.CanUserPush(protectBranch.ID, userID)
116-
if err != nil {
117-
fail("Internal error", "Fail to detect user can push: %v", err)
118-
} else if !canPush {
119-
fail(fmt.Sprintf("protected branch %s can not be pushed to", branchName), "")
106+
// detect force push
107+
if git.EmptySHA != oldCommitID {
108+
output, err := git.NewCommand("rev-list", "--max-count=1", oldCommitID, "^"+newCommitID).RunInDir(repoPath)
109+
if err != nil {
110+
fail("Internal error", "Fail to detect force push: %v", err)
111+
} else if len(output) > 0 {
112+
fail(fmt.Sprintf("branch %s is protected from force push", branchName), "")
113+
}
114+
}
115+
116+
userID, _ := strconv.ParseInt(userIDStr, 10, 64)
117+
canPush, err := private.CanUserPush(protectBranch.ID, userID)
118+
if err != nil {
119+
fail("Internal error", "Fail to detect user can push: %v", err)
120+
} else if !canPush {
121+
fail(fmt.Sprintf("protected branch %s can not be pushed to", branchName), "")
122+
}
120123
}
121124
}
122125
}
@@ -169,16 +172,22 @@ func runHookPostReceive(c *cli.Context) error {
169172
newCommitID := string(fields[1])
170173
refFullName := string(fields[2])
171174

172-
if err := private.PushUpdate(models.PushUpdateOptions{
173-
RefFullName: refFullName,
174-
OldCommitID: oldCommitID,
175-
NewCommitID: newCommitID,
176-
PusherID: pusherID,
177-
PusherName: pusherName,
178-
RepoUserName: repoUser,
179-
RepoName: repoName,
180-
}); err != nil {
181-
log.GitLogger.Error("Update: %v", err)
175+
// Only trigger activity updates for changes to branches or
176+
// tags. Updates to other refs (eg, refs/notes, refs/changes,
177+
// or other less-standard refs spaces are ignored since there
178+
// may be a very large number of them).
179+
if strings.HasPrefix(refFullName, git.BranchPrefix) || strings.HasPrefix(refFullName, git.TagPrefix) {
180+
if err := private.PushUpdate(models.PushUpdateOptions{
181+
RefFullName: refFullName,
182+
OldCommitID: oldCommitID,
183+
NewCommitID: newCommitID,
184+
PusherID: pusherID,
185+
PusherName: pusherName,
186+
RepoUserName: repoUser,
187+
RepoName: repoName,
188+
}); err != nil {
189+
log.GitLogger.Error("Update: %v", err)
190+
}
182191
}
183192

184193
if newCommitID != git.EmptySHA && strings.HasPrefix(refFullName, git.BranchPrefix) {

0 commit comments

Comments
 (0)