Migration This is my new public git source viewer. Source coming soon. Please contact with concerns/bugs. Contact me

internal/modules/compare.go

cb5a7c7c656de5a381e0234208c552c0856e43e3 · 1.6 KB · 59 lines raw

1 package modules
2
3 import (
4 "net/http"
5
6 "gsg/internal/core"
7 "gsg/internal/gitx"
8 )
9
10 type Compare struct {
11 Base, Head string // as the user spelled them
12 BaseSHA, HeadSHA string
13 MergeBase string
14 ThreeDot bool
15 Diff gitx.Diff
16 Commits []gitx.Commit // what Head has that Base does not
17 }
18
19 func init() { core.Register("compare", compareMod) }
20
21 // compare: diff between two arbitrary commits.
22 //
23 // Ctx.Vars carries the pair, already resolved to SHAs by the server -- so
24 // the ref text never reaches git, same rule as everywhere else.
25 //
26 // "a...b" (three dots) diffs from the merge base, which is what you want
27 // when reviewing a branch: it excludes changes that landed on the base
28 // since the branch forked. "a..b" is the literal endpoint difference.
29 func compareMod(c *core.Ctx, args ...string) (any, error) {
30 base, head := c.Var("baseSHA"), c.Var("headSHA")
31 if base == "" || head == "" {
32 return nil, core.Errorf(http.StatusBadRequest, "compare needs two commits")
33 }
34 cmp := Compare{
35 Base: c.Var("base"), Head: c.Var("head"),
36 BaseSHA: base, HeadSHA: head,
37 ThreeDot: c.Var("dots") == "3",
38 }
39
40 from := base
41 if cmp.ThreeDot {
42 mb, err := c.Repo.MergeBase(base, head)
43 if err != nil {
44 return nil, core.Errorf(http.StatusNotFound, "no common ancestor")
45 }
46 cmp.MergeBase, from = mb, mb
47 }
48
49 d, err := c.Repo.DiffRange(from, head, false)
50 if err != nil && err != gitx.ErrTruncated {
51 return nil, err
52 }
53 cmp.Diff = d
54
55 if log, err := c.Repo.Log(from+".."+head, 250, 0, false); err == nil {
56 cmp.Commits = log
57 }
58 return cmp, nil
59 }