forked from tangled.org/core
Monorepo for Tangled — https://tangled.org

use common ancestor to calculate diffs

Changed files
+46 -13
knotserver
+24 -12
knotserver/git/diff.go
···
return &nd, nil
}
-
func (g *GitRepo) DiffTree(rev1, rev2 string) (*types.DiffTree, error) {
-
commit1, err := g.resolveRevision(rev1)
-
if err != nil {
-
return nil, fmt.Errorf("Invalid revision: %s", rev1)
-
}
-
-
commit2, err := g.resolveRevision(rev2)
-
if err != nil {
-
return nil, fmt.Errorf("Invalid revision: %s", rev2)
-
}
-
+
func (g *GitRepo) DiffTree(commit1, commit2 *object.Commit) (*types.DiffTree, error) {
tree1, err := commit1.Tree()
if err != nil {
return nil, err
···
}, nil
}
-
func (g *GitRepo) resolveRevision(revStr string) (*object.Commit, error) {
+
func (g *GitRepo) MergeBase(commit1, commit2 *object.Commit) (*object.Commit, error) {
+
isAncestor, err := commit1.IsAncestor(commit2)
+
if err != nil {
+
return nil, err
+
}
+
+
if isAncestor {
+
return commit1, nil
+
}
+
+
mergeBase, err := commit1.MergeBase(commit2)
+
if err != nil {
+
return nil, err
+
}
+
+
if len(mergeBase) == 0 {
+
return nil, fmt.Errorf("failed to find a merge-base")
+
}
+
+
return mergeBase[0], nil
+
}
+
+
func (g *GitRepo) ResolveRevision(revStr string) (*object.Commit, error) {
rev, err := g.r.ResolveRevision(plumbing.Revision(revStr))
if err != nil {
return nil, fmt.Errorf("resolving revision %s: %w", revStr, err)
+22 -1
knotserver/routes.go
···
return
}
-
difftree, err := gr.DiffTree(rev1, rev2)
+
commit1, err := gr.ResolveRevision(rev1)
+
if err != nil {
+
l.Error("error resolving revision 1", "msg", err.Error())
+
writeError(w, fmt.Sprintf("error resolving revision %s", rev1), http.StatusBadRequest)
+
return
+
}
+
+
commit2, err := gr.ResolveRevision(rev2)
+
if err != nil {
+
l.Error("error resolving revision 2", "msg", err.Error())
+
writeError(w, fmt.Sprintf("error resolving revision %s", rev2), http.StatusBadRequest)
+
return
+
}
+
+
mergeBase, err := gr.MergeBase(commit1, commit2)
+
if err != nil {
+
l.Error("failed to find merge-base", "msg", err.Error())
+
writeError(w, "failed to calculate diff", http.StatusBadRequest)
+
return
+
}
+
+
difftree, err := gr.DiffTree(mergeBase, commit2)
if err != nil {
l.Error("error comparing revisions", "msg", err.Error())
writeError(w, "error comparing revisions", http.StatusBadRequest)