Skip to content

Commit 8ff386b

Browse files
committed
Save patches to temporary files
1 parent 7f0d7c0 commit 8ff386b

File tree

7 files changed

+85
-23
lines changed

7 files changed

+85
-23
lines changed

models/issue_xref_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ func testCreatePR(t *testing.T, repo, doer int64, title, content string) *PullRe
143143
d := AssertExistsAndLoadBean(t, &User{ID: doer}).(*User)
144144
i := &Issue{RepoID: r.ID, PosterID: d.ID, Poster: d, Title: title, Content: content, IsPull: true}
145145
pr := &PullRequest{HeadRepoID: repo, BaseRepoID: repo, HeadBranch: "head", BaseBranch: "base"}
146-
assert.NoError(t, NewPullRequest(r, i, nil, nil, pr, nil))
146+
assert.NoError(t, NewPullRequest(r, i, nil, nil, pr, 0, "unknown"))
147147
pr.Issue = i
148148
return pr
149149
}

models/pull.go

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package models
88
import (
99
"bufio"
1010
"fmt"
11+
"io/ioutil"
1112
"os"
1213
"path"
1314
"path/filepath"
@@ -595,11 +596,11 @@ func (pr *PullRequest) testPatch(e Engine) (err error) {
595596
}
596597

597598
// NewPullRequest creates new pull request with labels for repository.
598-
func NewPullRequest(repo *Repository, pull *Issue, labelIDs []int64, uuids []string, pr *PullRequest, patch []byte) (err error) {
599+
func NewPullRequest(repo *Repository, pull *Issue, labelIDs []int64, uuids []string, pr *PullRequest, patchFileSize int64, patchFileName string) (err error) {
599600
// Retry several times in case INSERT fails due to duplicate key for (repo_id, index); see #7887
600601
i := 0
601602
for {
602-
if err = newPullRequestAttempt(repo, pull, labelIDs, uuids, pr, patch); err == nil {
603+
if err = newPullRequestAttempt(repo, pull, labelIDs, uuids, pr, patchFileSize, patchFileName); err == nil {
603604
return nil
604605
}
605606
if !IsErrNewIssueInsert(err) {
@@ -613,7 +614,7 @@ func NewPullRequest(repo *Repository, pull *Issue, labelIDs []int64, uuids []str
613614
return fmt.Errorf("NewPullRequest: too many errors attempting to insert the new issue. Last error was: %v", err)
614615
}
615616

616-
func newPullRequestAttempt(repo *Repository, pull *Issue, labelIDs []int64, uuids []string, pr *PullRequest, patch []byte) (err error) {
617+
func newPullRequestAttempt(repo *Repository, pull *Issue, labelIDs []int64, uuids []string, pr *PullRequest, patchFileSize int64, patchFileName string) (err error) {
617618
sess := x.NewSession()
618619
defer sess.Close()
619620
if err = sess.Begin(); err != nil {
@@ -636,8 +637,8 @@ func newPullRequestAttempt(repo *Repository, pull *Issue, labelIDs []int64, uuid
636637
pr.Index = pull.Index
637638
pr.BaseRepo = repo
638639
pr.Status = PullRequestStatusChecking
639-
if len(patch) > 0 {
640-
if err = repo.savePatch(sess, pr.Index, patch); err != nil {
640+
if patchFileSize > 0 {
641+
if err = repo.savePatch(sess, pr.Index, patchFileName); err != nil {
641642
return fmt.Errorf("SavePatch: %v", err)
642643
}
643644

@@ -800,12 +801,23 @@ func (pr *PullRequest) UpdatePatch() (err error) {
800801
return fmt.Errorf("Update: %v", err)
801802
}
802803

803-
patch, err := headGitRepo.GetPatch(pr.MergeBase, pr.HeadBranch)
804+
tmpPatchFile, err := ioutil.TempFile("", "patch")
804805
if err != nil {
805-
return fmt.Errorf("GetPatch: %v", err)
806+
log.Error("Unable to create temporary patch file! Error: %v", err)
807+
return fmt.Errorf("Unable to create temporary patch file! Error: %v", err)
808+
}
809+
defer func() {
810+
_ = os.Remove(tmpPatchFile.Name())
811+
}()
812+
813+
if err := headGitRepo.GetPatch(pr.MergeBase, pr.HeadBranch, tmpPatchFile); err != nil {
814+
tmpPatchFile.Close()
815+
log.Error("Unable to get patch file from %s to %s in %s/%s Error: %v", pr.MergeBase, pr.HeadBranch, pr.BaseRepo.MustOwner().Name, pr.BaseRepo.Name, err)
816+
return fmt.Errorf("Unable to get patch file from %s to %s in %s/%s Error: %v", pr.MergeBase, pr.HeadBranch, pr.BaseRepo.MustOwner().Name, pr.BaseRepo.Name, err)
806817
}
807818

808-
if err = pr.BaseRepo.SavePatch(pr.Index, patch); err != nil {
819+
tmpPatchFile.Close()
820+
if err = pr.BaseRepo.SavePatch(pr.Index, tmpPatchFile.Name()); err != nil {
809821
return fmt.Errorf("BaseRepo.SavePatch: %v", err)
810822
}
811823

models/repo.go

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
// Needed for jpeg support
1616
_ "image/jpeg"
1717
"image/png"
18+
"io"
1819
"io/ioutil"
1920
"net/url"
2021
"os"
@@ -901,11 +902,11 @@ func (repo *Repository) patchPath(e Engine, index int64) (string, error) {
901902
}
902903

903904
// SavePatch saves patch data to corresponding location by given issue ID.
904-
func (repo *Repository) SavePatch(index int64, patch []byte) error {
905-
return repo.savePatch(x, index, patch)
905+
func (repo *Repository) SavePatch(index int64, name string) error {
906+
return repo.savePatch(x, index, name)
906907
}
907908

908-
func (repo *Repository) savePatch(e Engine, index int64, patch []byte) error {
909+
func (repo *Repository) savePatch(e Engine, index int64, name string) error {
909910
patchPath, err := repo.patchPath(e, index)
910911
if err != nil {
911912
return fmt.Errorf("PatchPath: %v", err)
@@ -916,10 +917,21 @@ func (repo *Repository) savePatch(e Engine, index int64, patch []byte) error {
916917
return fmt.Errorf("Failed to create dir %s: %v", dir, err)
917918
}
918919

919-
if err = ioutil.WriteFile(patchPath, patch, 0644); err != nil {
920-
return fmt.Errorf("WriteFile: %v", err)
920+
inputFile, err := os.Open(name)
921+
if err != nil {
922+
return fmt.Errorf("Couldn't open temporary patch file: %s", err)
923+
}
924+
outputFile, err := os.Create(patchPath)
925+
if err != nil {
926+
inputFile.Close()
927+
return fmt.Errorf("Couldn't open destination patch file: %s", err)
928+
}
929+
defer outputFile.Close()
930+
_, err = io.Copy(outputFile, inputFile)
931+
inputFile.Close()
932+
if err != nil {
933+
return fmt.Errorf("Writing to patch file failed: %s", err)
921934
}
922-
923935
return nil
924936
}
925937

modules/git/repo_compare.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ func (repo *Repository) GetCompareInfo(basePath, baseBranch, headBranch string)
9595
}
9696

9797
// GetPatch generates and returns patch data between given revisions.
98-
func (repo *Repository) GetPatch(base, head string) ([]byte, error) {
99-
return NewCommand("diff", "-p", "--binary", base, head).RunInDirBytes(repo.Path)
98+
func (repo *Repository) GetPatch(base, head string, w io.Writer) error {
99+
return NewCommand("diff", "-p", "--binary", base, head).RunInDirPipeline(repo.Path, w, nil)
100100
}
101101

102102
// GetFormatPatch generates and returns format-patch data between given revisions.

routers/api/v1/repo/pull.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ package repo
66

77
import (
88
"fmt"
9+
"io/ioutil"
910
"net/http"
11+
"os"
1012
"strings"
1113
"time"
1214

@@ -244,12 +246,29 @@ func CreatePullRequest(ctx *context.APIContext, form api.CreatePullRequestOption
244246
milestoneID = milestone.ID
245247
}
246248

247-
patch, err := headGitRepo.GetPatch(compareInfo.MergeBase, headBranch)
249+
tmpPatchFile, err := ioutil.TempFile("", "patch")
248250
if err != nil {
251+
ctx.Error(500, "CreateTemporaryFile", err)
252+
return
253+
}
254+
defer func() {
255+
_ = os.Remove(tmpPatchFile.Name())
256+
}()
257+
258+
if err := headGitRepo.GetPatch(compareInfo.MergeBase, headBranch, tmpPatchFile); err != nil {
259+
tmpPatchFile.Close()
249260
ctx.Error(500, "GetPatch", err)
250261
return
251262
}
252263

264+
stat, err := tmpPatchFile.Stat()
265+
if err != nil {
266+
tmpPatchFile.Close()
267+
ctx.Error(500, "StatPatch", err)
268+
return
269+
}
270+
271+
tmpPatchFile.Close()
253272
var deadlineUnix timeutil.TimeStamp
254273
if form.Deadline != nil {
255274
deadlineUnix = timeutil.TimeStamp(form.Deadline.Unix())
@@ -306,7 +325,7 @@ func CreatePullRequest(ctx *context.APIContext, form api.CreatePullRequestOption
306325
}
307326
}
308327

309-
if err := pull_service.NewPullRequest(repo, prIssue, labelIDs, []string{}, pr, patch, assigneeIDs); err != nil {
328+
if err := pull_service.NewPullRequest(repo, prIssue, labelIDs, []string{}, pr, stat.Size(), tmpPatchFile.Name(), assigneeIDs); err != nil {
310329
if models.IsErrUserDoesNotHaveAccessToRepo(err) {
311330
ctx.Error(400, "UserDoesNotHaveAccessToRepo", err)
312331
return

routers/repo/pull.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import (
1212
"fmt"
1313
"html"
1414
"io"
15+
"io/ioutil"
16+
"os"
1517
"path"
1618
"strings"
1719

@@ -785,12 +787,29 @@ func CompareAndPullRequestPost(ctx *context.Context, form auth.CreateIssueForm)
785787
return
786788
}
787789

788-
patch, err := headGitRepo.GetPatch(prInfo.MergeBase, headBranch)
790+
tmpPatchFile, err := ioutil.TempFile("", "patch")
789791
if err != nil {
792+
ctx.ServerError("CreateTemporaryFile", err)
793+
return
794+
}
795+
defer func() {
796+
_ = os.Remove(tmpPatchFile.Name())
797+
}()
798+
799+
if err := headGitRepo.GetPatch(prInfo.MergeBase, headBranch, tmpPatchFile); err != nil {
800+
tmpPatchFile.Close()
790801
ctx.ServerError("GetPatch", err)
791802
return
792803
}
793804

805+
stat, err := tmpPatchFile.Stat()
806+
if err != nil {
807+
tmpPatchFile.Close()
808+
ctx.ServerError("StatPatch", err)
809+
return
810+
}
811+
tmpPatchFile.Close()
812+
794813
pullIssue := &models.Issue{
795814
RepoID: repo.ID,
796815
Title: form.Title,
@@ -813,7 +832,7 @@ func CompareAndPullRequestPost(ctx *context.Context, form auth.CreateIssueForm)
813832
// FIXME: check error in the case two people send pull request at almost same time, give nice error prompt
814833
// instead of 500.
815834

816-
if err := pull_service.NewPullRequest(repo, pullIssue, labelIDs, attachments, pullRequest, patch, assigneeIDs); err != nil {
835+
if err := pull_service.NewPullRequest(repo, pullIssue, labelIDs, attachments, pullRequest, stat.Size(), tmpPatchFile.Name(), assigneeIDs); err != nil {
817836
if models.IsErrUserDoesNotHaveAccessToRepo(err) {
818837
ctx.Error(400, "UserDoesNotHaveAccessToRepo", err.Error())
819838
return

services/pull/pull.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ import (
1515
)
1616

1717
// NewPullRequest creates new pull request with labels for repository.
18-
func NewPullRequest(repo *models.Repository, pull *models.Issue, labelIDs []int64, uuids []string, pr *models.PullRequest, patch []byte, assigneeIDs []int64) error {
19-
if err := models.NewPullRequest(repo, pull, labelIDs, uuids, pr, patch); err != nil {
18+
func NewPullRequest(repo *models.Repository, pull *models.Issue, labelIDs []int64, uuids []string, pr *models.PullRequest, patchFileSize int64, patchFileName string, assigneeIDs []int64) error {
19+
if err := models.NewPullRequest(repo, pull, labelIDs, uuids, pr, patchFileSize, patchFileName); err != nil {
2020
return err
2121
}
2222

0 commit comments

Comments
 (0)