diff options
author | Anirudh Oppiliappan <x@icyphox.sh> | 2022-12-12 17:17:49 +0530 |
---|---|---|
committer | Anirudh Oppiliappan <x@icyphox.sh> | 2022-12-12 17:17:49 +0530 |
commit | c165c447685d68c2b0b2293a31937a903394f943 (patch) | |
tree | b2aa9f24cb263a2cc72c3167ec7233139e192c3a /git/diff.go | |
parent | ce71721c6dc80db8af63f2098a1548308e2621b2 (diff) | |
download | legit-c165c447685d68c2b0b2293a31937a903394f943.tar.gz legit-c165c447685d68c2b0b2293a31937a903394f943.tar.bz2 legit-c165c447685d68c2b0b2293a31937a903394f943.zip |
git, routes: commit diff view
Diffstat (limited to '')
-rw-r--r-- | git/diff.go | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/git/diff.go b/git/diff.go new file mode 100644 index 0000000..f7e5b0e --- /dev/null +++ b/git/diff.go @@ -0,0 +1,99 @@ +package git + +import ( + "fmt" + "log" + "strings" + + "github.com/bluekeyes/go-gitdiff/gitdiff" + "github.com/go-git/go-git/v5/plumbing/object" +) + +type TextFragment struct { + Header string + Lines []gitdiff.Line +} + +type Diff struct { + Name struct { + Old string + New string + } + TextFragments []TextFragment +} + +// A nicer git diff representation. +type NiceDiff struct { + Commit struct { + Message string + Author object.Signature + This string + Parent string + } + Stat struct { + FilesChanged int + Insertions int + Deletions int + } + Diff []Diff +} + +func (g *GitRepo) Diff() (*NiceDiff, error) { + c, err := g.r.CommitObject(g.h) + if err != nil { + return nil, fmt.Errorf("commit object: %w", err) + } + + var parent *object.Commit + if len(c.ParentHashes) > 0 { + parent, err = c.Parent(0) + if err != nil { + return nil, fmt.Errorf("getting parent: %w", err) + } + } else { + parent = c + } + + patch, err := parent.Patch(c) + if err != nil { + return nil, fmt.Errorf("patch: %w", err) + } + + diffs, _, err := gitdiff.Parse(strings.NewReader(patch.String())) + if err != nil { + log.Println(err) + } + + nd := NiceDiff{} + nd.Commit.This = c.Hash.String() + nd.Commit.Parent = parent.Hash.String() + nd.Commit.Author = c.Author + nd.Commit.Message = c.Message + ndiff := Diff{} + + for _, d := range diffs { + ndiff.Name.New = d.NewName + ndiff.Name.Old = d.OldName + + for _, tf := range d.TextFragments { + ndiff.TextFragments = append(ndiff.TextFragments, TextFragment{ + Header: tf.Header(), + Lines: tf.Lines, + }) + for _, l := range tf.Lines { + switch l.Op { + case gitdiff.OpAdd: + nd.Stat.Insertions += 1 + case gitdiff.OpDelete: + nd.Stat.Deletions += 1 + } + } + } + + nd.Diff = append(nd.Diff, ndiff) + } + + nd.Stat.FilesChanged = len(diffs) + + return &nd, nil +} |