aboutsummaryrefslogtreecommitdiff
path: root/models
diff options
context:
space:
mode:
Diffstat (limited to 'models')
-rw-r--r--models/issue.go21
-rw-r--r--models/repo.go29
2 files changed, 43 insertions, 7 deletions
diff --git a/models/issue.go b/models/issue.go
index 2bc25da4..0dd0b663 100644
--- a/models/issue.go
+++ b/models/issue.go
@@ -930,10 +930,12 @@ type PullRequest struct {
Merger *User `xorm:"-"`
}
+// Note: don't try to get Pull because will end up recursive querying.
func (pr *PullRequest) AfterSet(colName string, _ xorm.Cell) {
var err error
switch colName {
case "head_repo_id":
+ // FIXME: shouldn't show error if it's known that head repository has been removed.
pr.HeadRepo, err = GetRepositoryByID(pr.HeadRepoID)
if err != nil {
log.Error(3, "GetRepositoryByID[%d]: %v", pr.ID, err)
@@ -1017,7 +1019,7 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository) (err error
if _, stderr, err = process.ExecDir(-1, tmpBasePath,
fmt.Sprintf("PullRequest.Merge(git pull): %s", tmpBasePath),
"git", "pull", headRepoPath, pr.HeadBarcnh); err != nil {
- return fmt.Errorf("git pull: %s", stderr)
+ return fmt.Errorf("git pull[%s / %s -> %s]: %s", headRepoPath, pr.HeadBarcnh, tmpBasePath, stderr)
}
// Push back to upstream.
@@ -1059,27 +1061,32 @@ func NewPullRequest(repo *Repository, pull *Issue, labelIDs []int64, uuids []str
}
// Test apply patch.
+ if err = repo.UpdateLocalCopy(); err != nil {
+ return fmt.Errorf("UpdateLocalCopy: %v", err)
+ }
+
repoPath, err := repo.RepoPath()
if err != nil {
return fmt.Errorf("RepoPath: %v", err)
}
- patchPath := path.Join(repoPath, "pulls", com.ToStr(pr.ID)+".patch")
+ patchPath := path.Join(repoPath, "pulls", com.ToStr(pull.ID)+".patch")
os.MkdirAll(path.Dir(patchPath), os.ModePerm)
if err = ioutil.WriteFile(patchPath, patch, 0644); err != nil {
return fmt.Errorf("save patch: %v", err)
}
- defer os.Remove(patchPath)
- stdout, stderr, err := process.ExecDir(-1, repoPath,
+ pr.CanAutoMerge = true
+ _, stderr, err := process.ExecDir(-1, repo.LocalCopyPath(),
fmt.Sprintf("NewPullRequest(git apply --check): %d", repo.ID),
- "git", "apply", "--check", "-v", patchPath)
+ "git", "apply", "--check", patchPath)
if err != nil {
- if strings.Contains(stderr, "fatal:") {
+ if strings.Contains(stderr, "patch does not apply") {
+ pr.CanAutoMerge = false
+ } else {
return fmt.Errorf("git apply --check: %v - %s", err, stderr)
}
}
- pr.CanAutoMerge = !strings.Contains(stdout, "error: patch failed:")
pr.PullID = pull.ID
pr.PullIndex = pull.Index
diff --git a/models/repo.go b/models/repo.go
index d70454fc..31e3660a 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -296,6 +296,35 @@ func (repo *Repository) DescriptionHtml() template.HTML {
return template.HTML(DescPattern.ReplaceAllStringFunc(base.Sanitizer.Sanitize(repo.Description), sanitize))
}
+func (repo *Repository) LocalCopyPath() string {
+ return path.Join(setting.RepoRootPath, "local", com.ToStr(repo.ID))
+}
+
+// UpdateLocalCopy makes sure the local copy of repository is up-to-date.
+func (repo *Repository) UpdateLocalCopy() error {
+ repoPath, err := repo.RepoPath()
+ if err != nil {
+ return err
+ }
+
+ localPath := repo.LocalCopyPath()
+ if !com.IsExist(localPath) {
+ _, stderr, err := process.Exec(
+ fmt.Sprintf("UpdateLocalCopy(git clone): %s", repoPath), "git", "clone", repoPath, localPath)
+ if err != nil {
+ return fmt.Errorf("git clone: %v - %s", err, stderr)
+ }
+ } else {
+ _, stderr, err := process.ExecDir(-1, localPath,
+ fmt.Sprintf("UpdateLocalCopy(git pull): %s", repoPath), "git", "pull")
+ if err != nil {
+ return fmt.Errorf("git pull: %v - %s", err, stderr)
+ }
+ }
+
+ return nil
+}
+
func isRepositoryExist(e Engine, u *User, repoName string) (bool, error) {
has, err := e.Get(&Repository{
OwnerID: u.Id,