all repos — legit @ 7a6ff3565e8e5f55d50c509c9ee12438b61c850e

web frontend for git, written in go

git/diff.go (view raw)

 1package git
 2
 3import (
 4	"fmt"
 5	"log"
 6	"strings"
 7
 8	"github.com/bluekeyes/go-gitdiff/gitdiff"
 9	"github.com/go-git/go-git/v5/plumbing/object"
10)
11
12type TextFragment struct {
13	Header string
14	Lines  []gitdiff.Line
15}
16
17type Diff struct {
18	Name struct {
19		Old string
20		New string
21	}
22	TextFragments []TextFragment
23}
24
25// A nicer git diff representation.
26type NiceDiff struct {
27	Commit struct {
28		Message string
29		Author  object.Signature
30		This    string
31		Parent  string
32	}
33	Stat struct {
34		FilesChanged int
35		Insertions   int
36		Deletions    int
37	}
38	Diff []Diff
39}
40
41func (g *GitRepo) Diff() (*NiceDiff, error) {
42	c, err := g.r.CommitObject(g.h)
43	if err != nil {
44		return nil, fmt.Errorf("commit object: %w", err)
45	}
46
47	var parent *object.Commit
48	if len(c.ParentHashes) > 0 {
49		parent, err = c.Parent(0)
50		if err != nil {
51			return nil, fmt.Errorf("getting parent: %w", err)
52		}
53	} else {
54		parent = c
55	}
56
57	patch, err := parent.Patch(c)
58	if err != nil {
59		return nil, fmt.Errorf("patch: %w", err)
60	}
61
62	diffs, _, err := gitdiff.Parse(strings.NewReader(patch.String()))
63	if err != nil {
64		log.Println(err)
65	}
66
67	nd := NiceDiff{}
68	nd.Commit.This = c.Hash.String()
69	nd.Commit.Parent = parent.Hash.String()
70	nd.Commit.Author = c.Author
71	nd.Commit.Message = c.Message
72	ndiff := Diff{}
73
74	for _, d := range diffs {
75		ndiff.Name.New = d.NewName
76		ndiff.Name.Old = d.OldName
77
78		for _, tf := range d.TextFragments {
79			ndiff.TextFragments = append(ndiff.TextFragments, TextFragment{
80				Header: tf.Header(),
81				Lines:  tf.Lines,
82			})
83			for _, l := range tf.Lines {
84				switch l.Op {
85				case gitdiff.OpAdd:
86					nd.Stat.Insertions += 1
87				case gitdiff.OpDelete:
88					nd.Stat.Deletions += 1
89				}
90			}
91		}
92
93		nd.Diff = append(nd.Diff, ndiff)
94	}
95
96	nd.Stat.FilesChanged = len(diffs)
97
98	return &nd, nil
99}