From 10dc33064002f44098668dbd68163aabed6658d3 Mon Sep 17 00:00:00 2001
From: Unknwon <u@gogs.io>
Date: Sat, 30 Jul 2016 23:39:58 +0800
Subject: [PATCH] #3345 dump content directly to HTTP ResponseWriter

---
 README.md              |  2 +-
 gogs.go                |  2 +-
 models/git_diff.go     | 36 +++++++++++++++++++++++-------------
 routers/repo/commit.go | 11 +++++------
 templates/.VERSION     |  2 +-
 5 files changed, 31 insertions(+), 22 deletions(-)

diff --git a/README.md b/README.md
index d19d22ea9c..589ead6415 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@ Gogs - Go Git Service [![Build Status](https://travis-ci.org/gogits/gogs.svg?bra
 
 ![](https://github.com/gogits/gogs/blob/master/public/img/gogs-large-resize.png?raw=true)
 
-##### Current tip version: 0.9.58 (see [Releases](https://github.com/gogits/gogs/releases) for binary versions)
+##### Current tip version: 0.9.59 (see [Releases](https://github.com/gogits/gogs/releases) for binary versions)
 
 | Web | UI  | Preview  |
 |:-------------:|:-------:|:-------:|
diff --git a/gogs.go b/gogs.go
index 2c8fb28644..4e651a53a2 100644
--- a/gogs.go
+++ b/gogs.go
@@ -17,7 +17,7 @@ import (
 	"github.com/gogits/gogs/modules/setting"
 )
 
-const APP_VER = "0.9.58.0726"
+const APP_VER = "0.9.59.0730"
 
 func init() {
 	runtime.GOMAXPROCS(runtime.NumCPU())
diff --git a/models/git_diff.go b/models/git_diff.go
index 9cec5f62b6..a3040081b0 100644
--- a/models/git_diff.go
+++ b/models/git_diff.go
@@ -185,6 +185,7 @@ func (diff *Diff) NumFiles() int {
 
 const DIFF_HEAD = "diff --git "
 
+// TODO: move this function to gogits/git-module
 func ParsePatch(maxLines, maxLineCharacteres, maxFiles int, reader io.Reader) (*Diff, error) {
 	var (
 		diff = &Diff{Files: make([]*DiffFile, 0)}
@@ -371,13 +372,13 @@ func ParsePatch(maxLines, maxLineCharacteres, maxFiles int, reader io.Reader) (*
 	return diff, nil
 }
 
-func GetDiffRange(repoPath, beforeCommitID string, afterCommitID string, maxLines, maxLineCharacteres, maxFiles int) (*Diff, error) {
-	repo, err := git.OpenRepository(repoPath)
+func GetDiffRange(repoPath, beforeCommitID, afterCommitID string, maxLines, maxLineCharacteres, maxFiles int) (*Diff, error) {
+	gitRepo, err := git.OpenRepository(repoPath)
 	if err != nil {
 		return nil, err
 	}
 
-	commit, err := repo.GetCommit(afterCommitID)
+	commit, err := gitRepo.GetCommit(afterCommitID)
 	if err != nil {
 		return nil, err
 	}
@@ -422,27 +423,36 @@ func GetDiffRange(repoPath, beforeCommitID string, afterCommitID string, maxLine
 	return diff, nil
 }
 
-func GetRawDiff(repoPath, commitID, diffType string) (string, error) {
+type RawDiffType string
+
+const (
+	RAW_DIFF_NORMAL RawDiffType = "diff"
+	RAW_DIFF_PATCH  RawDiffType = "patch"
+)
+
+// GetRawDiff dumps diff results of repository in given commit ID to io.Writer.
+// TODO: move this function to gogits/git-module
+func GetRawDiff(repoPath, commitID string, diffType RawDiffType, writer io.Writer) error {
 	repo, err := git.OpenRepository(repoPath)
 	if err != nil {
-		return "", err
+		return fmt.Errorf("OpenRepository: %v", err)
 	}
 
 	commit, err := repo.GetCommit(commitID)
 	if err != nil {
-		return "", err
+		return fmt.Errorf("GetCommit: %v", err)
 	}
 
 	var cmd *exec.Cmd
 	switch diffType {
-	case "diff":
+	case RAW_DIFF_NORMAL:
 		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":
+	case RAW_DIFF_PATCH:
 		if commit.ParentCount() == 0 {
 			cmd = exec.Command("git", "format-patch", "--no-signature", "--stdout", "--root", commitID)
 		} else {
@@ -451,19 +461,19 @@ func GetRawDiff(repoPath, commitID, diffType string) (string, error) {
 			cmd = exec.Command("git", "format-patch", "--no-signature", "--stdout", query)
 		}
 	default:
-		return "", fmt.Errorf("Invalid diffType '%s'", diffType)
+		return fmt.Errorf("invalid diffType: %s", diffType)
 	}
 
 	stderr := new(bytes.Buffer)
 
 	cmd.Dir = repoPath
+	cmd.Stdout = writer
 	cmd.Stderr = stderr
 
-	stdout, err := cmd.Output()
-	if err != nil {
-		return "", fmt.Errorf("%v - %s", err, stderr)
+	if err = cmd.Run(); err != nil {
+		return fmt.Errorf("Run: %v - %s", err, stderr)
 	}
-	return string(stdout), nil
+	return nil
 }
 
 func GetDiffCommit(repoPath, commitID string, maxLines, maxLineCharacteres, maxFiles int) (*Diff, error) {
diff --git a/routers/repo/commit.go b/routers/repo/commit.go
index 779fd644d3..4eb37e6bdb 100644
--- a/routers/repo/commit.go
+++ b/routers/repo/commit.go
@@ -195,16 +195,15 @@ func Diff(ctx *context.Context) {
 }
 
 func RawDiff(ctx *context.Context) {
-	diff, err := models.GetRawDiff(
+	if 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)
+		models.RawDiffType(ctx.Params(":ext")),
+		ctx.Resp,
+	); err != nil {
+		ctx.Handle(500, "GetRawDiff", err)
 		return
 	}
-	ctx.HandleText(200, diff)
 }
 
 func CompareDiff(ctx *context.Context) {
diff --git a/templates/.VERSION b/templates/.VERSION
index ec98469da0..77ce288650 100644
--- a/templates/.VERSION
+++ b/templates/.VERSION
@@ -1 +1 @@
-0.9.58.0726
\ No newline at end of file
+0.9.59.0730
\ No newline at end of file