@@ -1,6 +1,7 @@
package git
import (
+ "io"
"path/filepath"
"strings"
@@ -160,6 +161,19 @@ func (r *Repository) Patch(commit *Commit) (string, error) {
return diff.Patch(), err
}
+// RawDiffFormat represents the format type for raw diffs.
+type RawDiffFormat = git.RawDiffFormat
+
+const (
+ RawDiffNormal RawDiffFormat = git.RawDiffNormal
+ RawDiffPatch RawDiffFormat = git.RawDiffPatch
+)
+
+// RawDiff writes raw diff output to the provided writer.
+func (r *Repository) RawDiff(rev string, diffType RawDiffFormat, w io.Writer, opts ...git.RawDiffOptions) error {
+ return r.Repository.RawDiff(rev, diffType, w, opts...)
+}
+
// CountCommits returns the number of commits in the repository.
func (r *Repository) CountCommits(ref *Reference) (int64, error) {
return r.RevListCount([]string{ref.Name().String()})
@@ -278,6 +278,12 @@ func WebUIController(ctx context.Context, r *mux.Router) {
r.Handle(basePrefix+"/commit/{hash:[0-9a-f]+}", withRepoVars(withWebUIAccess(http.HandlerFunc(repoCommit)))).
Methods(http.MethodGet)
+ // Commit patch and diff routes
+ r.Handle(basePrefix+"/commit/{hash:[0-9a-f]+}.patch", withRepoVars(withWebUIAccess(http.HandlerFunc(repoCommitPatch)))).
+ Methods(http.MethodGet)
+ r.Handle(basePrefix+"/commit/{hash:[0-9a-f]+}.diff", withRepoVars(withWebUIAccess(http.HandlerFunc(repoCommitDiff)))).
+ Methods(http.MethodGet)
+
// Branches route
r.Handle(basePrefix+"/branches", withRepoVars(withWebUIAccess(http.HandlerFunc(repoBranches)))).
Methods(http.MethodGet)
@@ -73,3 +73,57 @@ func repoCommit(w http.ResponseWriter, r *http.Request) {
renderHTML(w, "commit.html", data)
}
+
+func repoCommitPatch(w http.ResponseWriter, r *http.Request) {
+ ctx := r.Context()
+ logger := log.FromContext(ctx)
+ repo := proto.RepositoryFromContext(ctx)
+ vars := mux.Vars(r)
+ hash := vars["hash"]
+
+ gr, err := openRepository(repo)
+ if err != nil {
+ logger.Debug("failed to open repository", "repo", repo.Name(), "err", err)
+ renderInternalServerError(w, r)
+ return
+ }
+
+ _, err = gr.CatFileCommit(hash)
+ if err != nil {
+ logger.Debug("failed to get commit", "repo", repo.Name(), "hash", hash, "err", err)
+ renderNotFound(w, r)
+ return
+ }
+
+ w.Header().Set("Content-Type", "text/plain; charset=utf-8")
+ if err := gr.RawDiff(hash, git.RawDiffPatch, w); err != nil {
+ logger.Debug("failed to generate patch", "repo", repo.Name(), "hash", hash, "err", err)
+ }
+}
+
+func repoCommitDiff(w http.ResponseWriter, r *http.Request) {
+ ctx := r.Context()
+ logger := log.FromContext(ctx)
+ repo := proto.RepositoryFromContext(ctx)
+ vars := mux.Vars(r)
+ hash := vars["hash"]
+
+ gr, err := openRepository(repo)
+ if err != nil {
+ logger.Debug("failed to open repository", "repo", repo.Name(), "err", err)
+ renderInternalServerError(w, r)
+ return
+ }
+
+ _, err = gr.CatFileCommit(hash)
+ if err != nil {
+ logger.Debug("failed to get commit", "repo", repo.Name(), "hash", hash, "err", err)
+ renderNotFound(w, r)
+ return
+ }
+
+ w.Header().Set("Content-Type", "text/plain; charset=utf-8")
+ if err := gr.RawDiff(hash, git.RawDiffNormal, w); err != nil {
+ logger.Debug("failed to generate diff", "repo", repo.Name(), "hash", hash, "err", err)
+ }
+}