This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / knotserver / xrpc / repo_compare.go
2.9 kB 105 lines
1package xrpc 2 3import ( 4 "fmt" 5 "net/http" 6 7 "github.com/bluekeyes/go-gitdiff/gitdiff" 8 "tangled.org/core/knotserver/git" 9 "tangled.org/core/types" 10 xrpcerr "tangled.org/core/xrpc/errors" 11) 12 13func (x *Xrpc) RepoCompare(w http.ResponseWriter, r *http.Request) { 14 repo := r.URL.Query().Get("repo") 15 repoPath, err := x.parseRepoParam(repo) 16 if err != nil { 17 writeError(w, err.(xrpcerr.XrpcError), http.StatusBadRequest) 18 return 19 } 20 21 rev1 := r.URL.Query().Get("rev1") 22 if rev1 == "" { 23 writeError(w, xrpcerr.NewXrpcError( 24 xrpcerr.WithTag("InvalidRequest"), 25 xrpcerr.WithMessage("missing rev1 parameter"), 26 ), http.StatusBadRequest) 27 return 28 } 29 30 rev2 := r.URL.Query().Get("rev2") 31 if rev2 == "" { 32 writeError(w, xrpcerr.NewXrpcError( 33 xrpcerr.WithTag("InvalidRequest"), 34 xrpcerr.WithMessage("missing rev2 parameter"), 35 ), http.StatusBadRequest) 36 return 37 } 38 39 gr, err := git.PlainOpen(repoPath) 40 if err != nil { 41 writeError(w, xrpcerr.RepoNotFoundError, http.StatusNoContent) 42 return 43 } 44 45 commit1, err := gr.ResolveRevision(rev1) 46 if err != nil { 47 x.Logger.Error("error resolving revision 1", "msg", err.Error()) 48 writeError(w, xrpcerr.NewXrpcError( 49 xrpcerr.WithTag("RevisionNotFound"), 50 xrpcerr.WithMessage(fmt.Sprintf("error resolving revision %s", rev1)), 51 ), http.StatusBadRequest) 52 return 53 } 54 55 commit2, err := gr.ResolveRevision(rev2) 56 if err != nil { 57 x.Logger.Error("error resolving revision 2", "msg", err.Error()) 58 writeError(w, xrpcerr.NewXrpcError( 59 xrpcerr.WithTag("RevisionNotFound"), 60 xrpcerr.WithMessage(fmt.Sprintf("error resolving revision %s", rev2)), 61 ), http.StatusBadRequest) 62 return 63 } 64 65 rawPatch, formatPatch, err := gr.FormatPatch(commit1, commit2) 66 if err != nil { 67 x.Logger.Error("error comparing revisions", "msg", err.Error()) 68 writeError(w, xrpcerr.NewXrpcError( 69 xrpcerr.WithTag("CompareError"), 70 xrpcerr.WithMessage("error comparing revisions"), 71 ), http.StatusBadRequest) 72 return 73 } 74 75 var combinedPatch []*gitdiff.File 76 var combinedPatchRaw string 77 var mergeBase string 78 if mergeBaseCommit, err := gr.MergeBase(commit1, commit2); err != nil { 79 x.Logger.Error("error finding merge base", "msg", err.Error()) 80 } else { 81 mergeBase = mergeBaseCommit.Hash.String() 82 // nothing to combine with fewer than two patches 83 if len(formatPatch) >= 2 { 84 diffTree, err := gr.DiffTree(mergeBaseCommit, commit2) 85 if err != nil { 86 x.Logger.Error("error comparing revisions", "msg", err.Error()) 87 } else { 88 combinedPatch = diffTree.Diff 89 combinedPatchRaw = diffTree.Patch 90 } 91 } 92 } 93 94 response := types.RepoFormatPatchResponse{ 95 Rev1: commit1.Hash.String(), 96 Rev2: commit2.Hash.String(), 97 MergeBase: mergeBase, 98 FormatPatch: formatPatch, 99 FormatPatchRaw: rawPatch, 100 CombinedPatch: combinedPatch, 101 CombinedPatchRaw: combinedPatchRaw, 102 } 103 104 x.writeJson(w, response) 105}