mirror of
https://github.com/go-gitea/gitea
synced 2024-08-26 12:05:31 +02:00
Replace #28849. Thanks to @yp05327 for the looking into the problem. Fix #28840 The old behavior of newSignatureFromCommitline is not right. The new parseSignatureFromCommitLine: 1. never fails 2. only accept one format (if there is any other, it could be easily added) And add some tests.
106 lines
2.5 KiB
Go
106 lines
2.5 KiB
Go
// Copyright 2015 The Gogs Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package git
|
|
|
|
import (
|
|
"bytes"
|
|
"sort"
|
|
"strings"
|
|
|
|
"code.gitea.io/gitea/modules/util"
|
|
)
|
|
|
|
const (
|
|
beginpgp = "\n-----BEGIN PGP SIGNATURE-----\n"
|
|
endpgp = "\n-----END PGP SIGNATURE-----"
|
|
)
|
|
|
|
// Tag represents a Git tag.
|
|
type Tag struct {
|
|
Name string
|
|
ID ObjectID
|
|
Object ObjectID // The id of this commit object
|
|
Type string
|
|
Tagger *Signature
|
|
Message string
|
|
Signature *CommitGPGSignature
|
|
}
|
|
|
|
// Commit return the commit of the tag reference
|
|
func (tag *Tag) Commit(gitRepo *Repository) (*Commit, error) {
|
|
return gitRepo.getCommit(tag.Object)
|
|
}
|
|
|
|
// Parse commit information from the (uncompressed) raw
|
|
// data from the commit object.
|
|
// \n\n separate headers from message
|
|
func parseTagData(objectFormat ObjectFormat, data []byte) (*Tag, error) {
|
|
tag := new(Tag)
|
|
tag.ID = objectFormat.EmptyObjectID()
|
|
tag.Object = objectFormat.EmptyObjectID()
|
|
tag.Tagger = &Signature{}
|
|
// we now have the contents of the commit object. Let's investigate...
|
|
nextline := 0
|
|
l:
|
|
for {
|
|
eol := bytes.IndexByte(data[nextline:], '\n')
|
|
switch {
|
|
case eol > 0:
|
|
line := data[nextline : nextline+eol]
|
|
spacepos := bytes.IndexByte(line, ' ')
|
|
reftype := line[:spacepos]
|
|
switch string(reftype) {
|
|
case "object":
|
|
id, err := NewIDFromString(string(line[spacepos+1:]))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
tag.Object = id
|
|
case "type":
|
|
// A commit can have one or more parents
|
|
tag.Type = string(line[spacepos+1:])
|
|
case "tagger":
|
|
tag.Tagger = parseSignatureFromCommitLine(util.UnsafeBytesToString(line[spacepos+1:]))
|
|
}
|
|
nextline += eol + 1
|
|
case eol == 0:
|
|
tag.Message = string(data[nextline+1:])
|
|
break l
|
|
default:
|
|
break l
|
|
}
|
|
}
|
|
idx := strings.LastIndex(tag.Message, beginpgp)
|
|
if idx > 0 {
|
|
endSigIdx := strings.Index(tag.Message[idx:], endpgp)
|
|
if endSigIdx > 0 {
|
|
tag.Signature = &CommitGPGSignature{
|
|
Signature: tag.Message[idx+1 : idx+endSigIdx+len(endpgp)],
|
|
Payload: string(data[:bytes.LastIndex(data, []byte(beginpgp))+1]),
|
|
}
|
|
tag.Message = tag.Message[:idx+1]
|
|
}
|
|
}
|
|
return tag, nil
|
|
}
|
|
|
|
type tagSorter []*Tag
|
|
|
|
func (ts tagSorter) Len() int {
|
|
return len([]*Tag(ts))
|
|
}
|
|
|
|
func (ts tagSorter) Less(i, j int) bool {
|
|
return []*Tag(ts)[i].Tagger.When.After([]*Tag(ts)[j].Tagger.When)
|
|
}
|
|
|
|
func (ts tagSorter) Swap(i, j int) {
|
|
[]*Tag(ts)[i], []*Tag(ts)[j] = []*Tag(ts)[j], []*Tag(ts)[i]
|
|
}
|
|
|
|
// sortTagsByTime
|
|
func sortTagsByTime(tags []*Tag) {
|
|
sorter := tagSorter(tags)
|
|
sort.Sort(sorter)
|
|
}
|