main
 1package git
 2
 3import (
 4	"fmt"
 5	"strconv"
 6	"strings"
 7	"time"
 8)
 9
10func CompareDiff(base, head, repoDir string) (string, error) {
11	out, err := gitCmd(repoDir, "diff", base+"..."+head)
12	if err != nil {
13		return "", err
14	}
15	return string(out), nil
16}
17
18func CompareCommits(base, head Ref, repoDir string) ([]Commit, error) {
19	format := []string{"%H", "%h", "%s", "%b", "%an", "%ae", "%ad", "%cn", "%ce", "%cd", "%P", "%D"}
20	out, err := gitCmd(repoDir,
21		"log",
22		"--date=unix",
23		"--pretty=format:"+strings.Join(format, "\x1F"),
24		"-z",
25		base.String()+".."+head.String(),
26	)
27	if err != nil {
28		return nil, err
29	}
30
31	lines := strings.Split(string(out), "\x00")
32	commits := make([]Commit, 0, len(lines))
33	for _, line := range lines {
34		if line == "" {
35			continue
36		}
37		parts := strings.Split(line, "\x1F")
38		if len(parts) != len(format) {
39			return nil, fmt.Errorf("unexpected commit format: %s", line)
40		}
41		full, short, subject, body, author, email, date :=
42			parts[0], parts[1], parts[2], parts[3], parts[4], parts[5], parts[6]
43		committerName, committerEmail, committerDate, parents, refs :=
44			parts[7], parts[8], parts[9], parts[10], parts[11]
45
46		timestampInt, err := strconv.Atoi(date)
47		if err != nil {
48			return nil, fmt.Errorf("failed to parse commit date: %w", err)
49		}
50		committerTimestampInt, err := strconv.Atoi(committerDate)
51		if err != nil {
52			return nil, fmt.Errorf("failed to parse committer date: %w", err)
53		}
54		commits = append(commits, Commit{
55			Hash:           full,
56			ShortHash:      short,
57			Subject:        subject,
58			Body:           body,
59			Author:         author,
60			Email:          email,
61			Date:           time.Unix(int64(timestampInt), 0),
62			CommitterName:  committerName,
63			CommitterEmail: committerEmail,
64			CommitterDate:  time.Unix(int64(committerTimestampInt), 0),
65			Parents:        strings.Fields(parents),
66			RefNames:       parseRefNames(refs),
67		})
68	}
69	return commits, nil
70}