Skip to content

Commit

Permalink
Tagger can be empty, as can Commit and Author - tolerate this (go-git…
Browse files Browse the repository at this point in the history
…ea#15835)

Backport go-gitea#15835

Unfortunately some old repositories can have tags with empty Tagger, Commit
or Author. Go-Git variants will always have empty values for these whereas
the native git variant leaves them at nil. The simplest solution is just to
always have these set to empty Signatures.

v156 migration also makes the incorrect assumption that these cannot be empty.
Therefore add some handling to this and add logging and adjust broken
logging elsewhere in this migration.

Signed-off-by: Andrew Thornton <[email protected]>
  • Loading branch information
zeripath committed May 12, 2021
1 parent 3ae1d7a commit 361d638
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 8 deletions.
32 changes: 25 additions & 7 deletions models/migrations/v156.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func fixPublisherIDforTagReleases(x *xorm.Engine) error {
repo = new(Repository)
has, err := sess.ID(release.RepoID).Get(repo)
if err != nil {
log.Error("Error whilst loading repository[%d] for release[%d] with tag name %s", release.RepoID, release.ID, release.TagName)
log.Error("Error whilst loading repository[%d] for release[%d] with tag name %s. Error: %v", release.RepoID, release.ID, release.TagName, err)
return err
} else if !has {
log.Warn("Release[%d] is orphaned and refers to non-existing repository %d", release.ID, release.RepoID)
Expand All @@ -105,32 +105,50 @@ func fixPublisherIDforTagReleases(x *xorm.Engine) error {
}

if _, err := sess.ID(release.RepoID).Get(repo); err != nil {
log.Error("Error whilst loading repository[%d] for release[%d] with tag name %s", release.RepoID, release.ID, release.TagName)
log.Error("Error whilst loading repository[%d] for release[%d] with tag name %s. Error: %v", release.RepoID, release.ID, release.TagName, err)
return err
}
}
gitRepo, err = git.OpenRepository(repoPath(repo.OwnerName, repo.Name))
if err != nil {
log.Error("Error whilst opening git repo for %-v", repo)
log.Error("Error whilst opening git repo for [%d]%s/%s. Error: %v", repo.ID, repo.OwnerName, repo.Name, err)
return err
}
}

commit, err := gitRepo.GetTagCommit(release.TagName)
if err != nil {
if git.IsErrNotExist(err) {
log.Warn("Unable to find commit %s for Tag: %s in %-v. Cannot update publisher ID.", err.(git.ErrNotExist).ID, release.TagName, repo)
log.Warn("Unable to find commit %s for Tag: %s in [%d]%s/%s. Cannot update publisher ID.", err.(git.ErrNotExist).ID, release.TagName, repo.ID, repo.OwnerName, repo.Name)
continue
}
log.Error("Error whilst getting commit for Tag: %s in %-v.", release.TagName, repo)
log.Error("Error whilst getting commit for Tag: %s in [%d]%s/%s. Error: %v", release.TagName, repo.ID, repo.OwnerName, repo.Name, err)
return fmt.Errorf("GetTagCommit: %v", err)
}

if commit.Author.Email == "" {
log.Warn("Tag: %s in Repo[%d]%s/%s does not have a tagger.", release.TagName, repo.ID, repo.OwnerName, repo.Name)
commit, err = gitRepo.GetCommit(commit.ID.String())
if err != nil {
if git.IsErrNotExist(err) {
log.Warn("Unable to find commit %s for Tag: %s in [%d]%s/%s. Cannot update publisher ID.", err.(git.ErrNotExist).ID, release.TagName, repo.ID, repo.OwnerName, repo.Name)
continue
}
log.Error("Error whilst getting commit for Tag: %s in [%d]%s/%s. Error: %v", release.TagName, repo.ID, repo.OwnerName, repo.Name, err)
return fmt.Errorf("GetCommit: %v", err)
}
}

if commit.Author.Email == "" {
log.Warn("Tag: %s in Repo[%d]%s/%s does not have a Tagger and its underlying commit does not have an Author either!", release.TagName, repo.ID, repo.OwnerName, repo.Name)
continue
}

if user == nil || !strings.EqualFold(user.Email, commit.Author.Email) {
user = new(User)
_, err = sess.Where("email=?", commit.Author.Email).Get(user)
if err != nil {
log.Error("Error whilst getting commit author by email: %s for Tag: %s in %-v.", commit.Author.Email, release.TagName, repo)
log.Error("Error whilst getting commit author by email: %s for Tag: %s in [%d]%s/%s. Error: %v", commit.Author.Email, release.TagName, repo.ID, repo.OwnerName, repo.Name, err)
return err
}

Expand All @@ -143,7 +161,7 @@ func fixPublisherIDforTagReleases(x *xorm.Engine) error {

release.PublisherID = user.ID
if _, err := sess.ID(release.ID).Cols("publisher_id").Update(release); err != nil {
log.Error("Error whilst updating publisher[%d] for release[%d] with tag name %s", release.PublisherID, release.ID, release.TagName)
log.Error("Error whilst updating publisher[%d] for release[%d] with tag name %s. Error: %v", release.PublisherID, release.ID, release.TagName, err)
return err
}
}
Expand Down
4 changes: 3 additions & 1 deletion modules/git/commit_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ import (
// If used as part of a cat-file --batch stream you need to limit the reader to the correct size
func CommitFromReader(gitRepo *Repository, sha SHA1, reader io.Reader) (*Commit, error) {
commit := &Commit{
ID: sha,
ID: sha,
Author: &Signature{},
Committer: &Signature{},
}

payloadSB := new(strings.Builder)
Expand Down
1 change: 1 addition & 0 deletions modules/git/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ func (tag *Tag) Commit() (*Commit, error) {
// \n\n separate headers from message
func parseTagData(data []byte) (*Tag, error) {
tag := new(Tag)
tag.Tagger = &Signature{}
// we now have the contents of the commit object. Let's investigate...
nextline := 0
l:
Expand Down

0 comments on commit 361d638

Please sign in to comment.