package gitcmd import ( "strconv" "strings" ) type CompareResult struct { Base string `json:"base"` Head string `json:"head"` Ahead int `json:"ahead"` Behind int `json:"behind"` Commits []Commit `json:"commits"` Diff DiffResult `json:"diff"` } func (r *Repository) Compare(base, head string) (*CompareResult, error) { if base == "" { base = "HEAD" } if head == "" { head = "HEAD" } ahead, behind, err := r.countAheadBehind(base, head) if err != nil { return nil, err } commits, err := r.ListCommits(base+".."+head, 0) if err != nil { return nil, err } diff, err := r.Diff(base, head, nil) if err != nil { return nil, err } return &CompareResult{ Base: base, Head: head, Ahead: ahead, Behind: behind, Commits: commits, Diff: *diff, }, nil } func (r *Repository) countAheadBehind(base, head string) (ahead, behind int, err error) { out, _, err := NewCommand("rev-list", "--left-right", "--count"). AddDynamicArguments(base + "..." + head). WithDir(r.Path). RunStdString(r.ctx) if err != nil { return 0, 0, err } parts := strings.Fields(strings.TrimSpace(out)) if len(parts) >= 2 { behind, _ = strconv.Atoi(parts[0]) ahead, _ = strconv.Atoi(parts[1]) } return ahead, behind, nil }