Monorepo for Tangled tangled.org

use common ancestor to calculate diffs

Changed files
+46 -13
knotserver
+24 -12
knotserver/git/diff.go
··· 86 86 return &nd, nil 87 87 } 88 88 89 - func (g *GitRepo) DiffTree(rev1, rev2 string) (*types.DiffTree, error) { 90 - commit1, err := g.resolveRevision(rev1) 91 - if err != nil { 92 - return nil, fmt.Errorf("Invalid revision: %s", rev1) 93 - } 94 - 95 - commit2, err := g.resolveRevision(rev2) 96 - if err != nil { 97 - return nil, fmt.Errorf("Invalid revision: %s", rev2) 98 - } 99 - 89 + func (g *GitRepo) DiffTree(commit1, commit2 *object.Commit) (*types.DiffTree, error) { 100 90 tree1, err := commit1.Tree() 101 91 if err != nil { 102 92 return nil, err ··· 130 120 }, nil 131 121 } 132 122 133 - func (g *GitRepo) resolveRevision(revStr string) (*object.Commit, error) { 123 + func (g *GitRepo) MergeBase(commit1, commit2 *object.Commit) (*object.Commit, error) { 124 + isAncestor, err := commit1.IsAncestor(commit2) 125 + if err != nil { 126 + return nil, err 127 + } 128 + 129 + if isAncestor { 130 + return commit1, nil 131 + } 132 + 133 + mergeBase, err := commit1.MergeBase(commit2) 134 + if err != nil { 135 + return nil, err 136 + } 137 + 138 + if len(mergeBase) == 0 { 139 + return nil, fmt.Errorf("failed to find a merge-base") 140 + } 141 + 142 + return mergeBase[0], nil 143 + } 144 + 145 + func (g *GitRepo) ResolveRevision(revStr string) (*object.Commit, error) { 134 146 rev, err := g.r.ResolveRevision(plumbing.Revision(revStr)) 135 147 if err != nil { 136 148 return nil, fmt.Errorf("resolving revision %s: %w", revStr, err)
+22 -1
knotserver/routes.go
··· 775 775 return 776 776 } 777 777 778 - difftree, err := gr.DiffTree(rev1, rev2) 778 + commit1, err := gr.ResolveRevision(rev1) 779 + if err != nil { 780 + l.Error("error resolving revision 1", "msg", err.Error()) 781 + writeError(w, fmt.Sprintf("error resolving revision %s", rev1), http.StatusBadRequest) 782 + return 783 + } 784 + 785 + commit2, err := gr.ResolveRevision(rev2) 786 + if err != nil { 787 + l.Error("error resolving revision 2", "msg", err.Error()) 788 + writeError(w, fmt.Sprintf("error resolving revision %s", rev2), http.StatusBadRequest) 789 + return 790 + } 791 + 792 + mergeBase, err := gr.MergeBase(commit1, commit2) 793 + if err != nil { 794 + l.Error("failed to find merge-base", "msg", err.Error()) 795 + writeError(w, "failed to calculate diff", http.StatusBadRequest) 796 + return 797 + } 798 + 799 + difftree, err := gr.DiffTree(mergeBase, commit2) 779 800 if err != nil { 780 801 l.Error("error comparing revisions", "msg", err.Error()) 781 802 writeError(w, "error comparing revisions", http.StatusBadRequest)