forked from tangled.org/core
Monorepo for Tangled — https://tangled.org
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 "github.com/sotangled/tangled/types" 11) 12 13func (g *GitRepo) Diff() (*types.NiceDiff, error) { 14 c, err := g.r.CommitObject(g.h) 15 if err != nil { 16 return nil, fmt.Errorf("commit object: %w", err) 17 } 18 19 patch := &object.Patch{} 20 commitTree, err := c.Tree() 21 parent := &object.Commit{} 22 if err == nil { 23 parentTree := &object.Tree{} 24 if c.NumParents() != 0 { 25 parent, err = c.Parents().Next() 26 if err == nil { 27 parentTree, err = parent.Tree() 28 if err == nil { 29 patch, err = parentTree.Patch(commitTree) 30 if err != nil { 31 return nil, fmt.Errorf("patch: %w", err) 32 } 33 } 34 } 35 } else { 36 patch, err = parentTree.Patch(commitTree) 37 if err != nil { 38 return nil, fmt.Errorf("patch: %w", err) 39 } 40 } 41 } 42 43 diffs, _, err := gitdiff.Parse(strings.NewReader(patch.String())) 44 if err != nil { 45 log.Println(err) 46 } 47 48 nd := types.NiceDiff{} 49 nd.Commit.This = c.Hash.String() 50 51 if parent.Hash.IsZero() { 52 nd.Commit.Parent = "" 53 } else { 54 nd.Commit.Parent = parent.Hash.String() 55 } 56 nd.Commit.Author = c.Author 57 nd.Commit.Message = c.Message 58 59 for _, d := range diffs { 60 ndiff := types.Diff{} 61 ndiff.Name.New = d.NewName 62 ndiff.Name.Old = d.OldName 63 ndiff.IsBinary = d.IsBinary 64 ndiff.IsNew = d.IsNew 65 ndiff.IsDelete = d.IsDelete 66 67 for _, tf := range d.TextFragments { 68 ndiff.TextFragments = append(ndiff.TextFragments, *tf) 69 for _, l := range tf.Lines { 70 switch l.Op { 71 case gitdiff.OpAdd: 72 nd.Stat.Insertions += 1 73 case gitdiff.OpDelete: 74 nd.Stat.Deletions += 1 75 } 76 } 77 } 78 79 nd.Diff = append(nd.Diff, ndiff) 80 } 81 82 nd.Stat.FilesChanged = len(diffs) 83 84 return &nd, nil 85}