Signed-off-by: oppiliappan me@oppi.li
+112
knotserver/git/branch.go
+112
knotserver/git/branch.go
···
1
+
package git
2
+
3
+
import (
4
+
"fmt"
5
+
"slices"
6
+
"strconv"
7
+
"strings"
8
+
"time"
9
+
10
+
"github.com/go-git/go-git/v5/plumbing"
11
+
"github.com/go-git/go-git/v5/plumbing/object"
12
+
"tangled.sh/tangled.sh/core/types"
13
+
)
14
+
15
+
func (g *GitRepo) Branches() ([]types.Branch, error) {
16
+
fields := []string{
17
+
"refname:short",
18
+
"objectname",
19
+
"authorname",
20
+
"authoremail",
21
+
"authordate:unix",
22
+
"committername",
23
+
"committeremail",
24
+
"committerdate:unix",
25
+
"tree",
26
+
"parent",
27
+
"contents",
28
+
}
29
+
30
+
var outFormat strings.Builder
31
+
outFormat.WriteString("--format=")
32
+
for i, f := range fields {
33
+
if i != 0 {
34
+
outFormat.WriteString(fieldSeparator)
35
+
}
36
+
outFormat.WriteString(fmt.Sprintf("%%(%s)", f))
37
+
}
38
+
outFormat.WriteString("")
39
+
outFormat.WriteString(recordSeparator)
40
+
41
+
output, err := g.forEachRef(outFormat.String(), "refs/heads")
42
+
if err != nil {
43
+
return nil, fmt.Errorf("failed to get branches: %w", err)
44
+
}
45
+
46
+
records := strings.Split(strings.TrimSpace(string(output)), recordSeparator)
47
+
if len(records) == 1 && records[0] == "" {
48
+
return nil, nil
49
+
}
50
+
51
+
branches := make([]types.Branch, 0, len(records))
52
+
53
+
// ignore errors here
54
+
defaultBranch, _ := g.FindMainBranch()
55
+
56
+
for _, line := range records {
57
+
parts := strings.SplitN(strings.TrimSpace(line), fieldSeparator, len(fields))
58
+
if len(parts) < 6 {
59
+
continue
60
+
}
61
+
62
+
branchName := parts[0]
63
+
commitHash := plumbing.NewHash(parts[1])
64
+
authorName := parts[2]
65
+
authorEmail := strings.TrimSuffix(strings.TrimPrefix(parts[3], "<"), ">")
66
+
authorDate := parts[4]
67
+
committerName := parts[5]
68
+
committerEmail := strings.TrimSuffix(strings.TrimPrefix(parts[6], "<"), ">")
69
+
committerDate := parts[7]
70
+
treeHash := plumbing.NewHash(parts[8])
71
+
parentHash := plumbing.NewHash(parts[9])
72
+
message := parts[10]
73
+
74
+
// parse creation time
75
+
var authoredAt, committedAt time.Time
76
+
if unix, err := strconv.ParseInt(authorDate, 10, 64); err == nil {
77
+
authoredAt = time.Unix(unix, 0)
78
+
}
79
+
if unix, err := strconv.ParseInt(committerDate, 10, 64); err == nil {
80
+
committedAt = time.Unix(unix, 0)
81
+
}
82
+
83
+
branch := types.Branch{
84
+
IsDefault: branchName == defaultBranch,
85
+
Reference: types.Reference{
86
+
Name: branchName,
87
+
Hash: commitHash.String(),
88
+
},
89
+
Commit: &object.Commit{
90
+
Hash: commitHash,
91
+
Author: object.Signature{
92
+
Name: authorName,
93
+
Email: authorEmail,
94
+
When: authoredAt,
95
+
},
96
+
Committer: object.Signature{
97
+
Name: committerName,
98
+
Email: committerEmail,
99
+
When: committedAt,
100
+
},
101
+
TreeHash: treeHash,
102
+
ParentHashes: []plumbing.Hash{parentHash},
103
+
Message: message,
104
+
},
105
+
}
106
+
107
+
branches = append(branches, branch)
108
+
}
109
+
110
+
slices.Reverse(branches)
111
+
return branches, nil
112
+
}
-34
knotserver/git/git.go
-34
knotserver/git/git.go
···
14
14
"github.com/go-git/go-git/v5"
15
15
"github.com/go-git/go-git/v5/plumbing"
16
16
"github.com/go-git/go-git/v5/plumbing/object"
17
-
"tangled.sh/tangled.sh/core/types"
18
17
)
19
18
20
19
var (
···
264
263
return io.ReadAll(reader)
265
264
}
266
265
267
-
func (g *GitRepo) Branches() ([]types.Branch, error) {
268
-
bi, err := g.r.Branches()
269
-
if err != nil {
270
-
return nil, fmt.Errorf("branchs: %w", err)
271
-
}
272
-
273
-
branches := []types.Branch{}
274
-
275
-
defaultBranch, err := g.FindMainBranch()
276
-
277
-
_ = bi.ForEach(func(ref *plumbing.Reference) error {
278
-
b := types.Branch{}
279
-
b.Hash = ref.Hash().String()
280
-
b.Name = ref.Name().Short()
281
-
282
-
// resolve commit that this branch points to
283
-
commit, _ := g.Commit(ref.Hash())
284
-
if commit != nil {
285
-
b.Commit = commit
286
-
}
287
-
288
-
if defaultBranch != "" && defaultBranch == b.Name {
289
-
b.IsDefault = true
290
-
}
291
-
292
-
branches = append(branches, b)
293
-
294
-
return nil
295
-
})
296
-
297
-
return branches, nil
298
-
}
299
-
300
266
func (g *GitRepo) Branch(name string) (*plumbing.Reference, error) {
301
267
ref, err := g.r.Reference(plumbing.NewBranchReferenceName(name), false)
302
268
if err != nil {