diff --git a/README.md b/README.md index 582ac7bee9d..19e8920cd88 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,7 @@ There are 5 ways to install Gogs: - [OpenShift](https://github.com/tkisme/gogs-openshift) - [Cloudron](https://cloudron.io/appstore.html#io.gogs.cloudronapp) - [Scaleway](https://www.scaleway.com/imagehub/gogs/) +- [Portal](https://portaldemo.xyz/cloud/) ## Acknowledgments diff --git a/gogs.go b/gogs.go index c11111a2694..fe379aa23a0 100644 --- a/gogs.go +++ b/gogs.go @@ -17,7 +17,7 @@ import ( "github.com/gogits/gogs/modules/setting" ) -const APP_VER = "0.6.16.1002 Beta" +const APP_VER = "0.6.16.1004 Beta" func init() { runtime.GOMAXPROCS(runtime.NumCPU()) diff --git a/models/issue.go b/models/issue.go index 2bc25da447c..0dd0b66370e 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 d70454fc1c2..31e3660ae71 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, diff --git a/modules/git/repo_pull.go b/modules/git/repo_pull.go index add32df9085..a9cc33a1d41 100644 --- a/modules/git/repo_pull.go +++ b/modules/git/repo_pull.go @@ -44,7 +44,7 @@ func (repo *Repository) GetPullRequestInfo(basePath, baseBranch, headBranch stri } prInfo.MergeBase = strings.TrimSpace(stdout) - stdout, stderr, err = com.ExecCmdDir(repo.Path, "git", "log", remoteBranch+"..."+headBranch, prettyLogFormat) + stdout, stderr, err = com.ExecCmdDir(repo.Path, "git", "log", prInfo.MergeBase+"..."+headBranch, prettyLogFormat) if err != nil { return nil, fmt.Errorf("list diff logs: %v", concatenateError(err, stderr)) } @@ -64,20 +64,8 @@ func (repo *Repository) GetPullRequestInfo(basePath, baseBranch, headBranch stri } // GetPatch generates and returns patch data between given branches. -func (repo *Repository) GetPatch(basePath, baseBranch, headBranch string) ([]byte, error) { - // Add a temporary remote. - tmpRemote := com.ToStr(time.Now().UnixNano()) - _, stderr, err := com.ExecCmdDirBytes(repo.Path, "git", "remote", "add", "-f", tmpRemote, basePath) - if err != nil { - return nil, fmt.Errorf("add base as remote: %v", concatenateError(err, string(stderr))) - } - defer func() { - com.ExecCmdDir(repo.Path, "git", "remote", "remove", tmpRemote) - }() - - var stdout []byte - remoteBranch := "remotes/" + tmpRemote + "/" + baseBranch - stdout, stderr, err = com.ExecCmdDirBytes(repo.Path, "git", "diff", "-p", remoteBranch, headBranch) +func (repo *Repository) GetPatch(mergeBase, headBranch string) ([]byte, error) { + stdout, stderr, err := com.ExecCmdDirBytes(repo.Path, "git", "diff", "-p", mergeBase, headBranch) if err != nil { return nil, concatenateError(err, string(stderr)) } diff --git a/routers/repo/pull.go b/routers/repo/pull.go index c1eec7cc2f5..40c83351ca8 100644 --- a/routers/repo/pull.go +++ b/routers/repo/pull.go @@ -187,16 +187,22 @@ func PrepareViewPullInfo(ctx *middleware.Context, pull *models.Issue) *git.PullR ctx.Data["HeadTarget"] = pull.HeadUserName + "/" + pull.HeadBarcnh ctx.Data["BaseTarget"] = ctx.Repo.Owner.Name + "/" + pull.BaseBranch - headRepoPath, err := pull.HeadRepo.RepoPath() - if err != nil { - ctx.Handle(500, "HeadRepo.RepoPath", err) - return nil - } + var ( + headGitRepo *git.Repository + err error + ) + if pull.HeadRepo != nil { + headRepoPath, err := pull.HeadRepo.RepoPath() + if err != nil { + ctx.Handle(500, "HeadRepo.RepoPath", err) + return nil + } - headGitRepo, err := git.OpenRepository(headRepoPath) - if err != nil { - ctx.Handle(500, "OpenRepository", err) - return nil + headGitRepo, err = git.OpenRepository(headRepoPath) + if err != nil { + ctx.Handle(500, "OpenRepository", err) + return nil + } } if pull.HeadRepo == nil || !headGitRepo.IsBranchExist(pull.HeadBarcnh) { @@ -530,18 +536,18 @@ func CompareAndPullRequest(ctx *middleware.Context) { return } - pr, err := models.GetUnmergedPullRequest(headRepo.ID, ctx.Repo.Repository.ID, headBranch, baseBranch) - if err != nil { - if !models.IsErrPullRequestNotExist(err) { - ctx.Handle(500, "GetUnmergedPullRequest", err) - return - } - } else { - ctx.Data["HasPullRequest"] = true - ctx.Data["PullRequest"] = pr - ctx.HTML(200, COMPARE_PULL) - return - } + // pr, err := models.GetUnmergedPullRequest(headRepo.ID, ctx.Repo.Repository.ID, headBranch, baseBranch) + // if err != nil { + // if !models.IsErrPullRequestNotExist(err) { + // ctx.Handle(500, "GetUnmergedPullRequest", err) + // return + // } + // } else { + // ctx.Data["HasPullRequest"] = true + // ctx.Data["PullRequest"] = pr + // ctx.HTML(200, COMPARE_PULL) + // return + // } nothingToCompare := PrepareCompareDiff(ctx, headUser, headRepo, headGitRepo, prInfo, baseBranch, headBranch) if ctx.Written() { @@ -575,7 +581,7 @@ func CompareAndPullRequestPost(ctx *middleware.Context, form auth.CreateIssueFor return } - patch, err := headGitRepo.GetPatch(models.RepoPath(repo.Owner.Name, repo.Name), baseBranch, headBranch) + patch, err := headGitRepo.GetPatch(prInfo.MergeBase, headBranch) if err != nil { ctx.Handle(500, "GetPatch", err) return diff --git a/templates/.VERSION b/templates/.VERSION index 96127f4a46d..79f6fe8a178 100644 --- a/templates/.VERSION +++ b/templates/.VERSION @@ -1 +1 @@ -0.6.16.1002 Beta \ No newline at end of file +0.6.16.1004 Beta \ No newline at end of file