diff options
Diffstat (limited to 'models')
-rw-r--r-- | models/issue.go | 21 | ||||
-rw-r--r-- | models/repo.go | 29 |
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, |