Browse Source

save PR info as patch and minor fix on PR

tags/v0.9.99
Unknwon 8 years ago
parent
commit
215920772a
7 changed files with 77 additions and 46 deletions
  1. 1
    0
      README.md
  2. 1
    1
      gogs.go
  3. 14
    7
      models/issue.go
  4. 29
    0
      models/repo.go
  5. 3
    15
      modules/git/repo_pull.go
  6. 28
    22
      routers/repo/pull.go
  7. 1
    1
      templates/.VERSION

+ 1
- 0
README.md View File

- [OpenShift](https://github.com/tkisme/gogs-openshift) - [OpenShift](https://github.com/tkisme/gogs-openshift)
- [Cloudron](https://cloudron.io/appstore.html#io.gogs.cloudronapp) - [Cloudron](https://cloudron.io/appstore.html#io.gogs.cloudronapp)
- [Scaleway](https://www.scaleway.com/imagehub/gogs/) - [Scaleway](https://www.scaleway.com/imagehub/gogs/)
- [Portal](https://portaldemo.xyz/cloud/)


## Acknowledgments ## Acknowledgments



+ 1
- 1
gogs.go View File

"github.com/gogits/gogs/modules/setting" "github.com/gogits/gogs/modules/setting"
) )


const APP_VER = "0.6.16.1002 Beta"
const APP_VER = "0.6.16.1004 Beta"


func init() { func init() {
runtime.GOMAXPROCS(runtime.NumCPU()) runtime.GOMAXPROCS(runtime.NumCPU())

+ 14
- 7
models/issue.go View File

Merger *User `xorm:"-"` Merger *User `xorm:"-"`
} }


// Note: don't try to get Pull because will end up recursive querying.
func (pr *PullRequest) AfterSet(colName string, _ xorm.Cell) { func (pr *PullRequest) AfterSet(colName string, _ xorm.Cell) {
var err error var err error
switch colName { switch colName {
case "head_repo_id": 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) pr.HeadRepo, err = GetRepositoryByID(pr.HeadRepoID)
if err != nil { if err != nil {
log.Error(3, "GetRepositoryByID[%d]: %v", pr.ID, err) log.Error(3, "GetRepositoryByID[%d]: %v", pr.ID, err)
if _, stderr, err = process.ExecDir(-1, tmpBasePath, if _, stderr, err = process.ExecDir(-1, tmpBasePath,
fmt.Sprintf("PullRequest.Merge(git pull): %s", tmpBasePath), fmt.Sprintf("PullRequest.Merge(git pull): %s", tmpBasePath),
"git", "pull", headRepoPath, pr.HeadBarcnh); err != nil { "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. // Push back to upstream.
} }


// Test apply patch. // Test apply patch.
if err = repo.UpdateLocalCopy(); err != nil {
return fmt.Errorf("UpdateLocalCopy: %v", err)
}

repoPath, err := repo.RepoPath() repoPath, err := repo.RepoPath()
if err != nil { if err != nil {
return fmt.Errorf("RepoPath: %v", err) 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) os.MkdirAll(path.Dir(patchPath), os.ModePerm)
if err = ioutil.WriteFile(patchPath, patch, 0644); err != nil { if err = ioutil.WriteFile(patchPath, patch, 0644); err != nil {
return fmt.Errorf("save patch: %v", err) 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), fmt.Sprintf("NewPullRequest(git apply --check): %d", repo.ID),
"git", "apply", "--check", "-v", patchPath)
"git", "apply", "--check", patchPath)
if err != nil { 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) return fmt.Errorf("git apply --check: %v - %s", err, stderr)
} }
} }
pr.CanAutoMerge = !strings.Contains(stdout, "error: patch failed:")


pr.PullID = pull.ID pr.PullID = pull.ID
pr.PullIndex = pull.Index pr.PullIndex = pull.Index

+ 29
- 0
models/repo.go View File

return template.HTML(DescPattern.ReplaceAllStringFunc(base.Sanitizer.Sanitize(repo.Description), sanitize)) 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) { func isRepositoryExist(e Engine, u *User, repoName string) (bool, error) {
has, err := e.Get(&Repository{ has, err := e.Get(&Repository{
OwnerID: u.Id, OwnerID: u.Id,

+ 3
- 15
modules/git/repo_pull.go View File

} }
prInfo.MergeBase = strings.TrimSpace(stdout) 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 { if err != nil {
return nil, fmt.Errorf("list diff logs: %v", concatenateError(err, stderr)) return nil, fmt.Errorf("list diff logs: %v", concatenateError(err, stderr))
} }
} }


// GetPatch generates and returns patch data between given branches. // 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 { if err != nil {
return nil, concatenateError(err, string(stderr)) return nil, concatenateError(err, string(stderr))
} }

+ 28
- 22
routers/repo/pull.go View File

ctx.Data["HeadTarget"] = pull.HeadUserName + "/" + pull.HeadBarcnh ctx.Data["HeadTarget"] = pull.HeadUserName + "/" + pull.HeadBarcnh
ctx.Data["BaseTarget"] = ctx.Repo.Owner.Name + "/" + pull.BaseBranch 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) { if pull.HeadRepo == nil || !headGitRepo.IsBranchExist(pull.HeadBarcnh) {
return 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) nothingToCompare := PrepareCompareDiff(ctx, headUser, headRepo, headGitRepo, prInfo, baseBranch, headBranch)
if ctx.Written() { if ctx.Written() {
return return
} }


patch, err := headGitRepo.GetPatch(models.RepoPath(repo.Owner.Name, repo.Name), baseBranch, headBranch)
patch, err := headGitRepo.GetPatch(prInfo.MergeBase, headBranch)
if err != nil { if err != nil {
ctx.Handle(500, "GetPatch", err) ctx.Handle(500, "GetPatch", err)
return return

+ 1
- 1
templates/.VERSION View File

0.6.16.1002 Beta
0.6.16.1004 Beta

Loading…
Cancel
Save