aboutsummaryrefslogtreecommitdiffstats
path: root/services/pull/merge.go
diff options
context:
space:
mode:
authorzeripath <art27@cantab.net>2019-10-12 01:13:27 +0100
committerLunny Xiao <xiaolunwen@gmail.com>2019-10-12 08:13:27 +0800
commit5e759b60cca3cd8484a6235fcc9120d18e8cd455 (patch)
treeb9932067119f16197f69f12ec9b04aa74f68845a /services/pull/merge.go
parentac3613b791884f29c386bda2ccaad5c7434d822c (diff)
downloadgitea-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.go78
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())
}