diff options
author | zeripath <art27@cantab.net> | 2019-10-12 01:13:27 +0100 |
---|---|---|
committer | Lunny Xiao <xiaolunwen@gmail.com> | 2019-10-12 08:13:27 +0800 |
commit | 5e759b60cca3cd8484a6235fcc9120d18e8cd455 (patch) | |
tree | b9932067119f16197f69f12ec9b04aa74f68845a /services/pull/merge.go | |
parent | ac3613b791884f29c386bda2ccaad5c7434d822c (diff) | |
download | gitea-5e759b60cca3cd8484a6235fcc9120d18e8cd455.tar.gz gitea-5e759b60cca3cd8484a6235fcc9120d18e8cd455.zip |
Restore functionality for early gits (#7775)
* Change tests to make it possible to run TestGit with 1.7.2
* Make merge run on 1.7.2
* Fix tracking and staging branch name problem
* Ensure that git 1.7.2 works on tests
* ensure that there is no chance for conflicts
* Fix-up missing merge issues
* Final rm
* Ensure LFS filters run on the tests
* Do not sign commits from temp repo
* Restore tracking fetch change
* Apply suggestions from code review
* Update modules/repofiles/temp_repo.go
Diffstat (limited to 'services/pull/merge.go')
-rw-r--r-- | services/pull/merge.go | 78 |
1 files changed, 54 insertions, 24 deletions
diff --git a/services/pull/merge.go b/services/pull/merge.go index 6150c1518e..e83784f31e 100644 --- a/services/pull/merge.go +++ b/services/pull/merge.go @@ -11,7 +11,6 @@ import ( "fmt" "io/ioutil" "os" - "path" "path/filepath" "strings" @@ -22,6 +21,8 @@ import ( "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" + + "github.com/mcuadros/go-version" ) // Merge merges pull request to base repository. @@ -66,20 +67,17 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor headRepoPath := models.RepoPath(pr.HeadUserName, pr.HeadRepo.Name) - if err := git.Clone(baseGitRepo.Path, tmpBasePath, git.CloneRepoOptions{ - Shared: true, - NoCheckout: true, - Branch: pr.BaseBranch, - }); err != nil { - return fmt.Errorf("git clone: %v", err) + if err := git.InitRepository(tmpBasePath, false); err != nil { + return fmt.Errorf("git init: %v", err) } remoteRepoName := "head_repo" + baseBranch := "base" // Add head repo remote. addCacheRepo := func(staging, cache string) error { p := filepath.Join(staging, ".git", "objects", "info", "alternates") - f, err := os.OpenFile(p, os.O_APPEND|os.O_WRONLY, 0600) + f, err := os.OpenFile(p, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600) if err != nil { return err } @@ -91,25 +89,41 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor return nil } - if err := addCacheRepo(tmpBasePath, headRepoPath); err != nil { + if err := addCacheRepo(tmpBasePath, baseGitRepo.Path); err != nil { return fmt.Errorf("addCacheRepo [%s -> %s]: %v", headRepoPath, tmpBasePath, err) } var errbuf strings.Builder + if err := git.NewCommand("remote", "add", "-t", pr.BaseBranch, "-m", pr.BaseBranch, "origin", baseGitRepo.Path).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil { + return fmt.Errorf("git remote add [%s -> %s]: %s", baseGitRepo.Path, tmpBasePath, errbuf.String()) + } + + if err := git.NewCommand("fetch", "origin", "--no-tags", pr.BaseBranch+":"+baseBranch, pr.BaseBranch+":original_"+baseBranch).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil { + return fmt.Errorf("git fetch [%s -> %s]: %s", headRepoPath, tmpBasePath, errbuf.String()) + } + + if err := git.NewCommand("symbolic-ref", "HEAD", git.BranchPrefix+baseBranch).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil { + return fmt.Errorf("git symbolic-ref HEAD base [%s]: %s", tmpBasePath, errbuf.String()) + } + + if err := addCacheRepo(tmpBasePath, headRepoPath); err != nil { + return fmt.Errorf("addCacheRepo [%s -> %s]: %v", headRepoPath, tmpBasePath, err) + } + if err := git.NewCommand("remote", "add", remoteRepoName, headRepoPath).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil { return fmt.Errorf("git remote add [%s -> %s]: %s", headRepoPath, tmpBasePath, errbuf.String()) } + trackingBranch := "tracking" // Fetch head branch - if err := git.NewCommand("fetch", remoteRepoName, fmt.Sprintf("%s:refs/remotes/%s/%s", pr.HeadBranch, remoteRepoName, pr.HeadBranch)).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil { + if err := git.NewCommand("fetch", "--no-tags", remoteRepoName, pr.HeadBranch+":"+trackingBranch).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil { return fmt.Errorf("git fetch [%s -> %s]: %s", headRepoPath, tmpBasePath, errbuf.String()) } - trackingBranch := path.Join(remoteRepoName, pr.HeadBranch) - stagingBranch := fmt.Sprintf("%s_%s", remoteRepoName, pr.HeadBranch) + stagingBranch := "staging" // Enable sparse-checkout - sparseCheckoutList, err := getDiffTree(tmpBasePath, pr.BaseBranch, trackingBranch) + sparseCheckoutList, err := getDiffTree(tmpBasePath, baseBranch, trackingBranch) if err != nil { return fmt.Errorf("getDiffTree: %v", err) } @@ -123,21 +137,37 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor return fmt.Errorf("Writing sparse-checkout file to %s: %v", sparseCheckoutListPath, err) } + gitConfigCommand := func() func() *git.Command { + binVersion, err := git.BinVersion() + if err != nil { + log.Fatal("Error retrieving git version: %v", err) + } + + if version.Compare(binVersion, "1.8.0", ">=") { + return func() *git.Command { + return git.NewCommand("config", "--local") + } + } + return func() *git.Command { + return git.NewCommand("config") + } + }() + // Switch off LFS process (set required, clean and smudge here also) - if err := git.NewCommand("config", "--local", "filter.lfs.process", "").RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil { + if err := gitConfigCommand().AddArguments("filter.lfs.process", "").RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil { return fmt.Errorf("git config [filter.lfs.process -> <> ]: %v", errbuf.String()) } - if err := git.NewCommand("config", "--local", "filter.lfs.required", "false").RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil { + if err := gitConfigCommand().AddArguments("filter.lfs.required", "false").RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil { return fmt.Errorf("git config [filter.lfs.required -> <false> ]: %v", errbuf.String()) } - if err := git.NewCommand("config", "--local", "filter.lfs.clean", "").RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil { + if err := gitConfigCommand().AddArguments("filter.lfs.clean", "").RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil { return fmt.Errorf("git config [filter.lfs.clean -> <> ]: %v", errbuf.String()) } - if err := git.NewCommand("config", "--local", "filter.lfs.smudge", "").RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil { + if err := gitConfigCommand().AddArguments("filter.lfs.smudge", "").RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil { return fmt.Errorf("git config [filter.lfs.smudge -> <> ]: %v", errbuf.String()) } - if err := git.NewCommand("config", "--local", "core.sparseCheckout", "true").RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil { + if err := gitConfigCommand().AddArguments("core.sparseCheckout", "true").RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil { return fmt.Errorf("git config [core.sparsecheckout -> true]: %v", errbuf.String()) } @@ -163,11 +193,11 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor return fmt.Errorf("git checkout: %s", errbuf.String()) } // Rebase before merging - if err := git.NewCommand("rebase", "-q", pr.BaseBranch).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil { + if err := git.NewCommand("rebase", "-q", baseBranch).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil { return fmt.Errorf("git rebase [%s -> %s]: %s", headRepoPath, tmpBasePath, errbuf.String()) } // Checkout base branch again - if err := git.NewCommand("checkout", pr.BaseBranch).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil { + if err := git.NewCommand("checkout", baseBranch).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil { return fmt.Errorf("git checkout: %s", errbuf.String()) } // Merge fast forward @@ -180,11 +210,11 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor return fmt.Errorf("git checkout: %s", errbuf.String()) } // Rebase before merging - if err := git.NewCommand("rebase", "-q", pr.BaseBranch).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil { + if err := git.NewCommand("rebase", "-q", baseBranch).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil { return fmt.Errorf("git rebase [%s -> %s]: %s", headRepoPath, tmpBasePath, errbuf.String()) } // Checkout base branch again - if err := git.NewCommand("checkout", pr.BaseBranch).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil { + if err := git.NewCommand("checkout", baseBranch).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil { return fmt.Errorf("git checkout: %s", errbuf.String()) } // Prepare merge with commit @@ -216,7 +246,7 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor if err != nil { return fmt.Errorf("Failed to get full commit id for HEAD: %v", err) } - mergeBaseSHA, err := git.GetFullCommitID(tmpBasePath, "origin/"+pr.BaseBranch) + mergeBaseSHA, err := git.GetFullCommitID(tmpBasePath, "original_"+baseBranch) if err != nil { return fmt.Errorf("Failed to get full commit id for origin/%s: %v", pr.BaseBranch, err) } @@ -249,7 +279,7 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor ) // Push back to upstream. - if err := git.NewCommand("push", "origin", pr.BaseBranch).RunInDirTimeoutEnvPipeline(env, -1, tmpBasePath, nil, &errbuf); err != nil { + if err := git.NewCommand("push", "origin", baseBranch+":"+pr.BaseBranch).RunInDirTimeoutEnvPipeline(env, -1, tmpBasePath, nil, &errbuf); err != nil { return fmt.Errorf("git push: %s", errbuf.String()) } |