Skip to content

Commit ebc77a5

Browse files
committed
Skip push update when tag to blob/tree
Because git ref may reference to blob/tree, but push update logic will treate the object as a commit. Therefore, an error occurred when parsing the commit object, resulting in the loss of the webhook notification of this ref and other refs. So we ignore the wrong type error here to let other common refs can do webhook normally. Hope to fix #23213. Signed-off-by: ZheNing Hu <[email protected]>
1 parent ea1d097 commit ebc77a5

File tree

4 files changed

+76
-14
lines changed

4 files changed

+76
-14
lines changed

modules/git/error.go

+16
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,22 @@ func (err ErrNotExist) Unwrap() error {
4646
return util.ErrNotExist
4747
}
4848

49+
// ErrWrongType git object with wrong type
50+
type ErrWrongType struct {
51+
ID string
52+
Type string
53+
}
54+
55+
// IsErrWrongType if some error is ErrWrongType
56+
func IsErrWrongType(err error) bool {
57+
_, ok := err.(ErrWrongType)
58+
return ok
59+
}
60+
61+
func (err ErrWrongType) Error() string {
62+
return fmt.Sprintf("git object type is invalid [id: %s, type: %s]", err.ID, err.Type)
63+
}
64+
4965
// ErrBadLink entry.FollowLink error
5066
type ErrBadLink struct {
5167
Name string

modules/git/repo_commit_gogit.go

+47-14
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ package git
99
import (
1010
"strings"
1111

12+
"code.gitea.io/gitea/modules/log"
13+
1214
"github.com/go-git/go-git/v5/plumbing"
1315
"github.com/go-git/go-git/v5/plumbing/object"
1416
)
@@ -66,26 +68,57 @@ func (repo *Repository) IsCommitExist(name string) bool {
6668
return err == nil
6769
}
6870

69-
func (repo *Repository) getCommit(id SHA1) (*Commit, error) {
70-
var tagObject *object.Tag
71-
72-
gogitCommit, err := repo.gogitRepo.CommitObject(id)
73-
if err == plumbing.ErrObjectNotFound {
74-
tagObject, err = repo.gogitRepo.TagObject(id)
75-
if err == plumbing.ErrObjectNotFound {
76-
return nil, ErrNotExist{
77-
ID: id.String(),
78-
}
79-
}
80-
if err == nil {
81-
gogitCommit, err = repo.gogitRepo.CommitObject(tagObject.Target)
71+
func (repo *Repository) getGoGitTagDeepestObject(tag *object.Tag) (object.Object, error) {
72+
obj, err := tag.Object()
73+
if err != nil {
74+
return nil, err
75+
}
76+
if subTag, ok := obj.(*object.Tag); ok {
77+
obj, err = repo.getGoGitTagDeepestObject(subTag)
78+
if err != nil {
79+
return nil, err
8280
}
83-
// if we get a plumbing.ErrObjectNotFound here then the repository is broken and it should be 500
8481
}
82+
return obj, nil
83+
}
84+
85+
func (repo *Repository) getCommit(id SHA1) (*Commit, error) {
86+
var gogitCommit *object.Commit
87+
88+
obj, err := repo.gogitRepo.Object(plumbing.AnyObject, id)
8589
if err != nil {
8690
return nil, err
8791
}
8892

93+
switch o := obj.(type) {
94+
case *object.Commit:
95+
gogitCommit = o
96+
case *object.Tag:
97+
var ok bool
98+
99+
obj, err := repo.getGoGitTagDeepestObject(o)
100+
if err != nil {
101+
return nil, err
102+
}
103+
if gogitCommit, ok = obj.(*object.Commit); !ok {
104+
return nil, ErrWrongType{
105+
ID: obj.ID().String(),
106+
Type: obj.Type().String(),
107+
}
108+
}
109+
110+
case *object.Blob, *object.Tree:
111+
return nil, ErrWrongType{
112+
ID: id.String(),
113+
Type: o.Type().String(),
114+
}
115+
default:
116+
log.Debug("Unknown typ: %s", o.Type())
117+
return nil, ErrNotExist{
118+
ID: id.String(),
119+
}
120+
}
121+
89122
commit := convertCommit(gogitCommit)
90123
commit.repo = repo
91124

modules/git/repo_commit_nogogit.go

+9
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,15 @@ func (repo *Repository) getCommitFromBatchReader(rd *bufio.Reader, id SHA1) (*Co
119119
}
120120

121121
return commit, nil
122+
case "blob", "tree":
123+
_, err = rd.Discard(int(size) + 1)
124+
if err != nil {
125+
return nil, err
126+
}
127+
return nil, ErrWrongType{
128+
ID: id.String(),
129+
Type: typ,
130+
}
122131
default:
123132
log.Debug("Unknown typ: %s", typ)
124133
_, err = rd.Discard(int(size) + 1)

services/repository/push.go

+4
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
135135
} else { // is new tag
136136
newCommit, err := gitRepo.GetCommit(opts.NewCommitID)
137137
if err != nil {
138+
if git.IsErrWrongType(err) {
139+
log.Info("ignore special ref push update: %v", err)
140+
continue
141+
}
138142
return fmt.Errorf("gitRepo.GetCommit(%s) in %s/%s[%d]: %w", opts.NewCommitID, repo.OwnerName, repo.Name, repo.ID, err)
139143
}
140144

0 commit comments

Comments
 (0)