at master 2.2 kB view raw
1package git 2 3import ( 4 "fmt" 5 "strconv" 6 "strings" 7 "time" 8 9 "github.com/go-git/go-git/v5/plumbing" 10 "github.com/go-git/go-git/v5/plumbing/object" 11) 12 13func (g *GitRepo) Tags() ([]object.Tag, error) { 14 fields := []string{ 15 "refname:short", 16 "objectname", 17 "objecttype", 18 "*objectname", 19 "*objecttype", 20 "taggername", 21 "taggeremail", 22 "taggerdate:unix", 23 "contents", 24 } 25 26 var outFormat strings.Builder 27 outFormat.WriteString("--format=") 28 for i, f := range fields { 29 if i != 0 { 30 outFormat.WriteString(fieldSeparator) 31 } 32 outFormat.WriteString(fmt.Sprintf("%%(%s)", f)) 33 } 34 outFormat.WriteString("") 35 outFormat.WriteString(recordSeparator) 36 37 output, err := g.forEachRef(outFormat.String(), "--sort=-creatordate", "refs/tags") 38 if err != nil { 39 return nil, fmt.Errorf("failed to get tags: %w", err) 40 } 41 42 records := strings.Split(strings.TrimSpace(string(output)), recordSeparator) 43 if len(records) == 1 && records[0] == "" { 44 return nil, nil 45 } 46 47 tags := make([]object.Tag, 0, len(records)) 48 49 for _, line := range records { 50 parts := strings.SplitN(strings.TrimSpace(line), fieldSeparator, len(fields)) 51 if len(parts) < 6 { 52 continue 53 } 54 55 tagName := parts[0] 56 objectHash := parts[1] 57 objectType := parts[2] 58 targetHash := parts[3] // dereferenced object hash (empty for lightweight tags) 59 // targetType := parts[4] // dereferenced object type (empty for lightweight tags) 60 taggerName := parts[5] 61 taggerEmail := parts[6] 62 taggerDate := parts[7] 63 message := parts[8] 64 65 // parse creation time 66 var createdAt time.Time 67 if unix, err := strconv.ParseInt(taggerDate, 10, 64); err == nil { 68 createdAt = time.Unix(unix, 0) 69 } 70 71 // parse object type 72 typ, err := plumbing.ParseObjectType(objectType) 73 if err != nil { 74 return nil, err 75 } 76 77 // strip email separators 78 taggerEmail = strings.TrimSuffix(strings.TrimPrefix(taggerEmail, "<"), ">") 79 80 tag := object.Tag{ 81 Hash: plumbing.NewHash(objectHash), 82 Name: tagName, 83 Tagger: object.Signature{ 84 Name: taggerName, 85 Email: taggerEmail, 86 When: createdAt, 87 }, 88 Message: message, 89 TargetType: typ, 90 Target: plumbing.NewHash(targetHash), 91 } 92 93 tags = append(tags, tag) 94 } 95 96 return tags, nil 97}