From dfab54d5a2739b3b2a1fe45481c2269d1aeec1a9 Mon Sep 17 00:00:00 2001 From: Dennis Chen Date: Sat, 30 Jul 2016 11:02:22 -0400 Subject: [PATCH] Diff patch (#3345) * Add support for .diff and .patch Add the ability to get text-diff and format-patch by adding .diff or .patch in the end of a commit url. Issue #2641 * models: git_diff: various fixes * Renames commitId to commitID. * Writes stderr to a bytes.Buffer and displays proper error message on command failure. * Various style changes. Signed-off-by: Dennis Chen --- models/git_diff.go | 48 ++++++++++++++++++++++++++++++++++++++++-- routers/repo/commit.go | 11 +++++++++- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/models/git_diff.go b/models/git_diff.go index 33a63295f02..9cec5f62b69 100644 --- a/models/git_diff.go +++ b/models/git_diff.go @@ -422,6 +422,50 @@ func GetDiffRange(repoPath, beforeCommitID string, afterCommitID string, maxLine return diff, nil } -func GetDiffCommit(repoPath, commitId string, maxLines, maxLineCharacteres, maxFiles int) (*Diff, error) { - return GetDiffRange(repoPath, "", commitId, maxLines, maxLineCharacteres, maxFiles) +func GetRawDiff(repoPath, commitID, diffType string) (string, error) { + repo, err := git.OpenRepository(repoPath) + if err != nil { + return "", err + } + + commit, err := repo.GetCommit(commitID) + if err != nil { + return "", err + } + + var cmd *exec.Cmd + switch diffType { + case "diff": + if commit.ParentCount() == 0 { + cmd = exec.Command("git", "show", commitID) + } else { + c, _ := commit.Parent(0) + cmd = exec.Command("git", "diff", "-M", c.ID.String(), commitID) + } + case "patch": + if commit.ParentCount() == 0 { + cmd = exec.Command("git", "format-patch", "--no-signature", "--stdout", "--root", commitID) + } else { + c, _ := commit.Parent(0) + query := fmt.Sprintf("%s...%s", commitID, c.ID.String()) + cmd = exec.Command("git", "format-patch", "--no-signature", "--stdout", query) + } + default: + return "", fmt.Errorf("Invalid diffType '%s'", diffType) + } + + stderr := new(bytes.Buffer) + + cmd.Dir = repoPath + cmd.Stderr = stderr + + stdout, err := cmd.Output() + if err != nil { + return "", fmt.Errorf("%v - %s", err, stderr) + } + return string(stdout), nil +} + +func GetDiffCommit(repoPath, commitID string, maxLines, maxLineCharacteres, maxFiles int) (*Diff, error) { + return GetDiffRange(repoPath, "", commitID, maxLines, maxLineCharacteres, maxFiles) } diff --git a/routers/repo/commit.go b/routers/repo/commit.go index 436a06ee9b8..779fd644d3f 100644 --- a/routers/repo/commit.go +++ b/routers/repo/commit.go @@ -195,7 +195,16 @@ func Diff(ctx *context.Context) { } func RawDiff(ctx *context.Context) { - panic("not implemented") + diff, err := models.GetRawDiff( + models.RepoPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name), + ctx.Params(":sha"), + ctx.Params(":ext"), + ) + if err != nil { + ctx.Handle(404, "GetRawDiff", err) + return + } + ctx.HandleText(200, diff) } func CompareDiff(ctx *context.Context) {