Files

62 lines
1.3 KiB
Go

package git
import (
"context"
"strconv"
"strings"
"time"
)
// Commit 表示一条 git log 记录。
type Commit struct {
Hash string
Author string
Email string
Date time.Time
Subject string
}
// Log 返回 dir 的最近 n 条提交历史。n <= 0 时默认 50 条。
func (r *DefaultRunner) Log(ctx context.Context, dir string, n int) ([]Commit, error) {
ctx, cancel := withCtx(ctx, r.cfg.OpsTimeout)
defer cancel()
if n <= 0 {
n = 50
}
out, _, err := r.exec(ctx, dir, nil, "log", "--format=%H%x00%an%x00%ae%x00%aI%x00%s%x00", "-n", strconv.Itoa(n))
if err != nil {
return nil, err
}
return parseLog(out), nil
}
func parseLog(buf []byte) []Commit {
if len(buf) == 0 {
return nil
}
parts := strings.Split(string(buf), "\x00")
var commits []Commit
// parts 以空字符串结尾(因为 format 最后有 %x00),所以每 5 个字段为一组。
for i := 0; i+4 < len(parts); i += 5 {
hash := parts[i]
if hash == "" {
continue
}
author := parts[i+1]
email := parts[i+2]
dateStr := parts[i+3]
subject := parts[i+4]
date, _ := time.Parse(time.RFC3339, dateStr)
commits = append(commits, Commit{
Hash: hash,
Author: author,
Email: email,
Date: date,
Subject: subject,
})
}
return commits
}