this repo has no description
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 IsBinary bool 24 IsNew bool 25 IsDelete bool 26} 27 28// A nicer git diff representation. 29type NiceDiff struct { 30 Commit struct { 31 Message string 32 Author object.Signature 33 This string 34 Parent string 35 } 36 Stat struct { 37 FilesChanged int 38 Insertions int 39 Deletions int 40 } 41 Diff []Diff 42} 43 44func (g *GitRepo) Diff() (*NiceDiff, error) { 45 c, err := g.r.CommitObject(g.h) 46 if err != nil { 47 return nil, fmt.Errorf("commit object: %w", err) 48 } 49 50 patch := &object.Patch{} 51 commitTree, err := c.Tree() 52 parent := &object.Commit{} 53 if err == nil { 54 parentTree := &object.Tree{} 55 if c.NumParents() != 0 { 56 parent, err = c.Parents().Next() 57 if err == nil { 58 parentTree, err = parent.Tree() 59 if err == nil { 60 patch, err = parentTree.Patch(commitTree) 61 if err != nil { 62 return nil, fmt.Errorf("patch: %w", err) 63 } 64 } 65 } 66 } else { 67 patch, err = parentTree.Patch(commitTree) 68 if err != nil { 69 return nil, fmt.Errorf("patch: %w", err) 70 } 71 } 72 } 73 74 diffs, _, err := gitdiff.Parse(strings.NewReader(patch.String())) 75 if err != nil { 76 log.Println(err) 77 } 78 79 nd := NiceDiff{} 80 nd.Commit.This = c.Hash.String() 81 82 if parent.Hash.IsZero() { 83 nd.Commit.Parent = "" 84 } else { 85 nd.Commit.Parent = parent.Hash.String() 86 } 87 nd.Commit.Author = c.Author 88 nd.Commit.Message = c.Message 89 90 for _, d := range diffs { 91 ndiff := Diff{} 92 ndiff.Name.New = d.NewName 93 ndiff.Name.Old = d.OldName 94 ndiff.IsBinary = d.IsBinary 95 ndiff.IsNew = d.IsNew 96 ndiff.IsDelete = d.IsDelete 97 98 for _, tf := range d.TextFragments { 99 ndiff.TextFragments = append(ndiff.TextFragments, TextFragment{ 100 Header: tf.Header(), 101 Lines: tf.Lines, 102 }) 103 for _, l := range tf.Lines { 104 switch l.Op { 105 case gitdiff.OpAdd: 106 nd.Stat.Insertions += 1 107 case gitdiff.OpDelete: 108 nd.Stat.Deletions += 1 109 } 110 } 111 } 112 113 nd.Diff = append(nd.Diff, ndiff) 114 } 115 116 nd.Stat.FilesChanged = len(diffs) 117 118 return &nd, nil 119}