summaryrefslogtreecommitdiff
path: root/internal/git
diff options
context:
space:
mode:
authormo khan <mo@mokhan.ca>2026-01-31 23:46:28 -0700
committermo khan <mo@mokhan.ca>2026-01-31 23:46:28 -0700
commit051e023c1813d4bbf73d683311000652dfc79783 (patch)
tree2e3ef7e91a9092a305e2f56a251fb946d9dd4e6a /internal/git
parent587e8900e455f8e8a1071c93650b9e67120461e9 (diff)
feat: add compare pages
Diffstat (limited to 'internal/git')
-rw-r--r--internal/git/compare.go70
-rw-r--r--internal/git/git.go1
2 files changed, 71 insertions, 0 deletions
diff --git a/internal/git/compare.go b/internal/git/compare.go
new file mode 100644
index 0000000..4b8f120
--- /dev/null
+++ b/internal/git/compare.go
@@ -0,0 +1,70 @@
+package git
+
+import (
+ "fmt"
+ "strconv"
+ "strings"
+ "time"
+)
+
+func CompareDiff(base, head, repoDir string) (string, error) {
+ out, err := gitCmd(repoDir, "diff", base+"..."+head)
+ if err != nil {
+ return "", err
+ }
+ return string(out), nil
+}
+
+func CompareCommits(base, head Ref, repoDir string) ([]Commit, error) {
+ format := []string{"%H", "%h", "%s", "%b", "%an", "%ae", "%ad", "%cn", "%ce", "%cd", "%P", "%D"}
+ out, err := gitCmd(repoDir,
+ "log",
+ "--date=unix",
+ "--pretty=format:"+strings.Join(format, "\x1F"),
+ "-z",
+ base.String()+".."+head.String(),
+ )
+ if err != nil {
+ return nil, err
+ }
+
+ lines := strings.Split(string(out), "\x00")
+ commits := make([]Commit, 0, len(lines))
+ for _, line := range lines {
+ if line == "" {
+ continue
+ }
+ parts := strings.Split(line, "\x1F")
+ if len(parts) != len(format) {
+ return nil, fmt.Errorf("unexpected commit format: %s", line)
+ }
+ full, short, subject, body, author, email, date :=
+ parts[0], parts[1], parts[2], parts[3], parts[4], parts[5], parts[6]
+ committerName, committerEmail, committerDate, parents, refs :=
+ parts[7], parts[8], parts[9], parts[10], parts[11]
+
+ timestampInt, err := strconv.Atoi(date)
+ if err != nil {
+ return nil, fmt.Errorf("failed to parse commit date: %w", err)
+ }
+ committerTimestampInt, err := strconv.Atoi(committerDate)
+ if err != nil {
+ return nil, fmt.Errorf("failed to parse committer date: %w", err)
+ }
+ commits = append(commits, Commit{
+ Hash: full,
+ ShortHash: short,
+ Subject: subject,
+ Body: body,
+ Author: author,
+ Email: email,
+ Date: time.Unix(int64(timestampInt), 0),
+ CommitterName: committerName,
+ CommitterEmail: committerEmail,
+ CommitterDate: time.Unix(int64(committerTimestampInt), 0),
+ Parents: strings.Fields(parents),
+ RefNames: parseRefNames(refs),
+ })
+ }
+ return commits, nil
+}
diff --git a/internal/git/git.go b/internal/git/git.go
index 41031e4..4e09d19 100644
--- a/internal/git/git.go
+++ b/internal/git/git.go
@@ -329,3 +329,4 @@ func CommitDiff(hash, repoDir string) (string, error) {
}
return string(out), nil
}
+