Skip to content

Commit 937b4b5

Browse files
typelesslunny
authored andcommitted
Speed up conflict checking in pull request creation (#276)
* Speed up conflict checking in pull request creation In order to check conflicts of a PR, we set up a working tree by cloning the base branch, which is quite time-consuming when the repository is huge. Instead, this PR uses `git read-tree` and `git apply --check --cached` to check conflicts. For #258 * Use $GIT_INDEX_FILE instead of --index-output to avoid lockfile problem The lockfile gets renamed to the final destination after the operation finishes. But it must be located in the same filesystem, which prevents us from using /tmp. * Temporary file names should not prefixed with '-'
1 parent b992858 commit 937b4b5

File tree

1 file changed

+15
-8
lines changed

1 file changed

+15
-8
lines changed

models/pull.go

+15-8
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
"fmt"
99
"os"
1010
"path"
11+
"path/filepath"
12+
"strconv"
1113
"strings"
1214
"time"
1315

@@ -428,17 +430,22 @@ func (pr *PullRequest) testPatch() (err error) {
428430

429431
log.Trace("PullRequest[%d].testPatch (patchPath): %s", pr.ID, patchPath)
430432

431-
// Delete old temp local copy before we create a new temp local copy
432-
RemoveAllWithNotice("Deleting old local copy", pr.BaseRepo.LocalCopyPath())
433+
pr.Status = PullRequestStatusChecking
434+
435+
indexTmpPath := filepath.Join(os.TempDir(), "gitea-"+pr.BaseRepo.Name+"-"+strconv.Itoa(time.Now().Nanosecond()))
436+
defer os.Remove(indexTmpPath)
433437

434-
if err := pr.BaseRepo.UpdateLocalCopyBranch(pr.BaseBranch); err != nil {
435-
return fmt.Errorf("UpdateLocalCopy: %v", err)
438+
var stderr string
439+
_, stderr, err = process.ExecDirEnv(-1, "", fmt.Sprintf("testPatch (git read-tree): %d", pr.BaseRepo.ID),
440+
[]string{"GIT_DIR=" + pr.BaseRepo.RepoPath(), "GIT_INDEX_FILE=" + indexTmpPath},
441+
"git", "read-tree", pr.BaseBranch)
442+
if err != nil {
443+
return fmt.Errorf("git read-tree --index-output=%s %s: %v - %s", indexTmpPath, pr.BaseBranch, err, stderr)
436444
}
437445

438-
pr.Status = PullRequestStatusChecking
439-
_, stderr, err := process.ExecDir(-1, pr.BaseRepo.LocalCopyPath(),
440-
fmt.Sprintf("testPatch (git apply --check): %d", pr.BaseRepo.ID),
441-
"git", "apply", "--check", patchPath)
446+
_, stderr, err = process.ExecDirEnv(-1, "", fmt.Sprintf("testPatch (git apply --check): %d", pr.BaseRepo.ID),
447+
[]string{"GIT_INDEX_FILE=" + indexTmpPath, "GIT_DIR=" + pr.BaseRepo.RepoPath()},
448+
"git", "apply", "--check", "--cached", patchPath)
442449
if err != nil {
443450
for i := range patchConflicts {
444451
if strings.Contains(stderr, patchConflicts[i]) {

0 commit comments

Comments
 (0)