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
This commit is contained in:
parent
ac3613b791
commit
5e759b60cc
12 changed files with 226 additions and 66 deletions
|
@ -12,7 +12,9 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -37,7 +39,12 @@ func withKeyFile(t *testing.T, keyname string, callback func(string)) {
|
||||||
err = ssh.GenKeyPair(keyFile)
|
err = ssh.GenKeyPair(keyFile)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
err = ioutil.WriteFile(path.Join(tmpDir, "ssh"), []byte("#!/bin/bash\n"+
|
||||||
|
"ssh -o \"UserKnownHostsFile=/dev/null\" -o \"StrictHostKeyChecking=no\" -o \"IdentitiesOnly=yes\" -i \""+keyFile+"\" \"$@\""), 0700)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
//Setup ssh wrapper
|
//Setup ssh wrapper
|
||||||
|
os.Setenv("GIT_SSH", path.Join(tmpDir, "ssh"))
|
||||||
os.Setenv("GIT_SSH_COMMAND",
|
os.Setenv("GIT_SSH_COMMAND",
|
||||||
"ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o IdentitiesOnly=yes -i \""+keyFile+"\"")
|
"ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o IdentitiesOnly=yes -i \""+keyFile+"\"")
|
||||||
os.Setenv("GIT_SSH_VARIANT", "ssh")
|
os.Setenv("GIT_SSH_VARIANT", "ssh")
|
||||||
|
@ -54,6 +61,24 @@ func createSSHUrl(gitPath string, u *url.URL) *url.URL {
|
||||||
return &u2
|
return &u2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func allowLFSFilters() []string {
|
||||||
|
// Now here we should explicitly allow lfs filters to run
|
||||||
|
globalArgs := git.GlobalCommandArgs
|
||||||
|
filteredLFSGlobalArgs := make([]string, len(git.GlobalCommandArgs))
|
||||||
|
j := 0
|
||||||
|
for _, arg := range git.GlobalCommandArgs {
|
||||||
|
if strings.Contains(arg, "lfs") {
|
||||||
|
j--
|
||||||
|
} else {
|
||||||
|
filteredLFSGlobalArgs[j] = arg
|
||||||
|
j++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filteredLFSGlobalArgs = filteredLFSGlobalArgs[:j]
|
||||||
|
git.GlobalCommandArgs = filteredLFSGlobalArgs
|
||||||
|
return globalArgs
|
||||||
|
}
|
||||||
|
|
||||||
func onGiteaRun(t *testing.T, callback func(*testing.T, *url.URL)) {
|
func onGiteaRun(t *testing.T, callback func(*testing.T, *url.URL)) {
|
||||||
prepareTestEnv(t, 1)
|
prepareTestEnv(t, 1)
|
||||||
s := http.Server{
|
s := http.Server{
|
||||||
|
@ -79,7 +104,9 @@ func onGiteaRun(t *testing.T, callback func(*testing.T, *url.URL)) {
|
||||||
|
|
||||||
func doGitClone(dstLocalPath string, u *url.URL) func(*testing.T) {
|
func doGitClone(dstLocalPath string, u *url.URL) func(*testing.T) {
|
||||||
return func(t *testing.T) {
|
return func(t *testing.T) {
|
||||||
|
oldGlobals := allowLFSFilters()
|
||||||
assert.NoError(t, git.Clone(u.String(), dstLocalPath, git.CloneRepoOptions{}))
|
assert.NoError(t, git.Clone(u.String(), dstLocalPath, git.CloneRepoOptions{}))
|
||||||
|
git.GlobalCommandArgs = oldGlobals
|
||||||
assert.True(t, com.IsExist(filepath.Join(dstLocalPath, "README.md")))
|
assert.True(t, com.IsExist(filepath.Join(dstLocalPath, "README.md")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,7 +167,9 @@ func doGitCreateBranch(dstPath, branch string) func(*testing.T) {
|
||||||
|
|
||||||
func doGitCheckoutBranch(dstPath string, args ...string) func(*testing.T) {
|
func doGitCheckoutBranch(dstPath string, args ...string) func(*testing.T) {
|
||||||
return func(t *testing.T) {
|
return func(t *testing.T) {
|
||||||
|
oldGlobals := allowLFSFilters()
|
||||||
_, err := git.NewCommand(append([]string{"checkout"}, args...)...).RunInDir(dstPath)
|
_, err := git.NewCommand(append([]string{"checkout"}, args...)...).RunInDir(dstPath)
|
||||||
|
git.GlobalCommandArgs = oldGlobals
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,7 +183,9 @@ func doGitMerge(dstPath string, args ...string) func(*testing.T) {
|
||||||
|
|
||||||
func doGitPull(dstPath string, args ...string) func(*testing.T) {
|
func doGitPull(dstPath string, args ...string) func(*testing.T) {
|
||||||
return func(t *testing.T) {
|
return func(t *testing.T) {
|
||||||
|
oldGlobals := allowLFSFilters()
|
||||||
_, err := git.NewCommand(append([]string{"pull"}, args...)...).RunInDir(dstPath)
|
_, err := git.NewCommand(append([]string{"pull"}, args...)...).RunInDir(dstPath)
|
||||||
|
git.GlobalCommandArgs = oldGlobals
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
@ -135,6 +136,11 @@ func standardCommitAndPushTest(t *testing.T, dstPath string) (little, big string
|
||||||
func lfsCommitAndPushTest(t *testing.T, dstPath string) (littleLFS, bigLFS string) {
|
func lfsCommitAndPushTest(t *testing.T, dstPath string) (littleLFS, bigLFS string) {
|
||||||
t.Run("LFS", func(t *testing.T) {
|
t.Run("LFS", func(t *testing.T) {
|
||||||
PrintCurrentTest(t)
|
PrintCurrentTest(t)
|
||||||
|
setting.CheckLFSVersion()
|
||||||
|
if !setting.LFS.StartServer {
|
||||||
|
t.Skip()
|
||||||
|
return
|
||||||
|
}
|
||||||
prefix := "lfs-data-file-"
|
prefix := "lfs-data-file-"
|
||||||
_, err := git.NewCommand("lfs").AddArguments("install").RunInDir(dstPath)
|
_, err := git.NewCommand("lfs").AddArguments("install").RunInDir(dstPath)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
@ -142,6 +148,21 @@ func lfsCommitAndPushTest(t *testing.T, dstPath string) (littleLFS, bigLFS strin
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
err = git.AddChanges(dstPath, false, ".gitattributes")
|
err = git.AddChanges(dstPath, false, ".gitattributes")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
oldGlobals := allowLFSFilters()
|
||||||
|
err = git.CommitChanges(dstPath, git.CommitChangesOptions{
|
||||||
|
Committer: &git.Signature{
|
||||||
|
Email: "user2@example.com",
|
||||||
|
Name: "User Two",
|
||||||
|
When: time.Now(),
|
||||||
|
},
|
||||||
|
Author: &git.Signature{
|
||||||
|
Email: "user2@example.com",
|
||||||
|
Name: "User Two",
|
||||||
|
When: time.Now(),
|
||||||
|
},
|
||||||
|
Message: fmt.Sprintf("Testing commit @ %v", time.Now()),
|
||||||
|
})
|
||||||
|
git.GlobalCommandArgs = oldGlobals
|
||||||
|
|
||||||
littleLFS, bigLFS = commitAndPushTest(t, dstPath, prefix)
|
littleLFS, bigLFS = commitAndPushTest(t, dstPath, prefix)
|
||||||
|
|
||||||
|
@ -185,21 +206,26 @@ func rawTest(t *testing.T, ctx *APITestContext, little, big, littleLFS, bigLFS s
|
||||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
assert.Equal(t, littleSize, resp.Body.Len())
|
assert.Equal(t, littleSize, resp.Body.Len())
|
||||||
|
|
||||||
|
setting.CheckLFSVersion()
|
||||||
|
if setting.LFS.StartServer {
|
||||||
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", littleLFS))
|
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", littleLFS))
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
assert.NotEqual(t, littleSize, resp.Body.Len())
|
assert.NotEqual(t, littleSize, resp.Body.Len())
|
||||||
assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier)
|
assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier)
|
||||||
|
}
|
||||||
|
|
||||||
if !testing.Short() {
|
if !testing.Short() {
|
||||||
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", big))
|
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", big))
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
assert.Equal(t, bigSize, resp.Body.Len())
|
assert.Equal(t, bigSize, resp.Body.Len())
|
||||||
|
|
||||||
|
if setting.LFS.StartServer {
|
||||||
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", bigLFS))
|
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", bigLFS))
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
assert.NotEqual(t, bigSize, resp.Body.Len())
|
assert.NotEqual(t, bigSize, resp.Body.Len())
|
||||||
assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier)
|
assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,19 +243,24 @@ func mediaTest(t *testing.T, ctx *APITestContext, little, big, littleLFS, bigLFS
|
||||||
resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
||||||
assert.Equal(t, littleSize, resp.Length)
|
assert.Equal(t, littleSize, resp.Length)
|
||||||
|
|
||||||
|
setting.CheckLFSVersion()
|
||||||
|
if setting.LFS.StartServer {
|
||||||
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", littleLFS))
|
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", littleLFS))
|
||||||
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
||||||
assert.Equal(t, littleSize, resp.Length)
|
assert.Equal(t, littleSize, resp.Length)
|
||||||
|
}
|
||||||
|
|
||||||
if !testing.Short() {
|
if !testing.Short() {
|
||||||
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", big))
|
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", big))
|
||||||
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
||||||
assert.Equal(t, bigSize, resp.Length)
|
assert.Equal(t, bigSize, resp.Length)
|
||||||
|
|
||||||
|
if setting.LFS.StartServer {
|
||||||
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", bigLFS))
|
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", bigLFS))
|
||||||
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
||||||
assert.Equal(t, bigSize, resp.Length)
|
assert.Equal(t, bigSize, resp.Length)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,6 +305,8 @@ func generateCommitWithNewData(size int, repoPath, email, fullName, prefix strin
|
||||||
}
|
}
|
||||||
|
|
||||||
//Commit
|
//Commit
|
||||||
|
// Now here we should explicitly allow lfs filters to run
|
||||||
|
oldGlobals := allowLFSFilters()
|
||||||
err = git.AddChanges(repoPath, false, filepath.Base(tmpFile.Name()))
|
err = git.AddChanges(repoPath, false, filepath.Base(tmpFile.Name()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -291,6 +324,7 @@ func generateCommitWithNewData(size int, repoPath, email, fullName, prefix strin
|
||||||
},
|
},
|
||||||
Message: fmt.Sprintf("Testing commit @ %v", time.Now()),
|
Message: fmt.Sprintf("Testing commit @ %v", time.Now()),
|
||||||
})
|
})
|
||||||
|
git.GlobalCommandArgs = oldGlobals
|
||||||
return filepath.Base(tmpFile.Name()), err
|
return filepath.Base(tmpFile.Name()), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,11 @@ func storeObjectInRepo(t *testing.T, repositoryID int64, content *[]byte) string
|
||||||
|
|
||||||
func doLfs(t *testing.T, content *[]byte, expectGzip bool) {
|
func doLfs(t *testing.T, content *[]byte, expectGzip bool) {
|
||||||
prepareTestEnv(t)
|
prepareTestEnv(t)
|
||||||
|
setting.CheckLFSVersion()
|
||||||
|
if !setting.LFS.StartServer {
|
||||||
|
t.Skip()
|
||||||
|
return
|
||||||
|
}
|
||||||
repo, err := models.GetRepositoryByOwnerAndName("user2", "repo1")
|
repo, err := models.GetRepositoryByOwnerAndName("user2", "repo1")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
oid := storeObjectInRepo(t, repo.ID, content)
|
oid := storeObjectInRepo(t, repo.ID, content)
|
||||||
|
|
|
@ -1093,7 +1093,7 @@ func CleanUpMigrateInfo(repo *Repository) (*Repository, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := git.NewCommand("remote", "remove", "origin").RunInDir(repoPath)
|
_, err := git.NewCommand("remote", "rm", "origin").RunInDir(repoPath)
|
||||||
if err != nil && !strings.HasPrefix(err.Error(), "exit status 128 - fatal: No such remote ") {
|
if err != nil && !strings.HasPrefix(err.Error(), "exit status 128 - fatal: No such remote ") {
|
||||||
return repo, fmt.Errorf("CleanUpMigrateInfo: %v", err)
|
return repo, fmt.Errorf("CleanUpMigrateInfo: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,7 +165,7 @@ func (repo *Repository) AddRemote(name, url string, fetch bool) error {
|
||||||
|
|
||||||
// RemoveRemote removes a remote from repository.
|
// RemoveRemote removes a remote from repository.
|
||||||
func (repo *Repository) RemoveRemote(name string) error {
|
func (repo *Repository) RemoveRemote(name string) error {
|
||||||
_, err := NewCommand("remote", "remove", name).RunInDir(repo.Path)
|
_, err := NewCommand("remote", "rm", name).RunInDir(repo.Path)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,13 @@
|
||||||
package git
|
package git
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/mcuadros/go-version"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (repo *Repository) getTree(id SHA1) (*Tree, error) {
|
func (repo *Repository) getTree(id SHA1) (*Tree, error) {
|
||||||
|
@ -61,6 +64,11 @@ type CommitTreeOpts struct {
|
||||||
|
|
||||||
// CommitTree creates a commit from a given tree id for the user with provided message
|
// CommitTree creates a commit from a given tree id for the user with provided message
|
||||||
func (repo *Repository) CommitTree(sig *Signature, tree *Tree, opts CommitTreeOpts) (SHA1, error) {
|
func (repo *Repository) CommitTree(sig *Signature, tree *Tree, opts CommitTreeOpts) (SHA1, error) {
|
||||||
|
binVersion, err := BinVersion()
|
||||||
|
if err != nil {
|
||||||
|
return SHA1{}, err
|
||||||
|
}
|
||||||
|
|
||||||
commitTimeStr := time.Now().Format(time.RFC3339)
|
commitTimeStr := time.Now().Format(time.RFC3339)
|
||||||
|
|
||||||
// Because this may call hooks we should pass in the environment
|
// Because this may call hooks we should pass in the environment
|
||||||
|
@ -78,20 +86,24 @@ func (repo *Repository) CommitTree(sig *Signature, tree *Tree, opts CommitTreeOp
|
||||||
cmd.AddArguments("-p", parent)
|
cmd.AddArguments("-p", parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.AddArguments("-m", opts.Message)
|
messageBytes := new(bytes.Buffer)
|
||||||
|
_, _ = messageBytes.WriteString(opts.Message)
|
||||||
|
_, _ = messageBytes.WriteString("\n")
|
||||||
|
|
||||||
if opts.KeyID != "" {
|
if opts.KeyID != "" {
|
||||||
cmd.AddArguments(fmt.Sprintf("-S%s", opts.KeyID))
|
cmd.AddArguments(fmt.Sprintf("-S%s", opts.KeyID))
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.NoGPGSign {
|
if version.Compare(binVersion, "2.0.0", ">=") && opts.NoGPGSign {
|
||||||
cmd.AddArguments("--no-gpg-sign")
|
cmd.AddArguments("--no-gpg-sign")
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := cmd.RunInDirWithEnv(repo.Path, env)
|
stdout := new(bytes.Buffer)
|
||||||
|
stderr := new(bytes.Buffer)
|
||||||
|
err = cmd.RunInDirTimeoutEnvFullPipeline(env, -1, repo.Path, stdout, stderr, messageBytes)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return SHA1{}, err
|
return SHA1{}, concatenateError(err, stderr.String())
|
||||||
}
|
}
|
||||||
return NewIDFromString(strings.TrimSpace(res))
|
return NewIDFromString(strings.TrimSpace(stdout.String()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -9,6 +10,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
@ -93,6 +95,14 @@ func (pm *Manager) ExecDir(timeout time.Duration, dir, desc, cmdName string, arg
|
||||||
// Returns its complete stdout and stderr
|
// Returns its complete stdout and stderr
|
||||||
// outputs and an error, if any (including timeout)
|
// outputs and an error, if any (including timeout)
|
||||||
func (pm *Manager) ExecDirEnv(timeout time.Duration, dir, desc string, env []string, cmdName string, args ...string) (string, string, error) {
|
func (pm *Manager) ExecDirEnv(timeout time.Duration, dir, desc string, env []string, cmdName string, args ...string) (string, string, error) {
|
||||||
|
return pm.ExecDirEnvStdIn(timeout, dir, desc, env, nil, cmdName, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExecDirEnvStdIn runs a command in given path and environment variables with provided stdIN, and waits for its completion
|
||||||
|
// up to the given timeout (or DefaultTimeout if -1 is given).
|
||||||
|
// Returns its complete stdout and stderr
|
||||||
|
// outputs and an error, if any (including timeout)
|
||||||
|
func (pm *Manager) ExecDirEnvStdIn(timeout time.Duration, dir, desc string, env []string, stdIn io.Reader, cmdName string, args ...string) (string, string, error) {
|
||||||
if timeout == -1 {
|
if timeout == -1 {
|
||||||
timeout = 60 * time.Second
|
timeout = 60 * time.Second
|
||||||
}
|
}
|
||||||
|
@ -108,6 +118,10 @@ func (pm *Manager) ExecDirEnv(timeout time.Duration, dir, desc string, env []str
|
||||||
cmd.Env = env
|
cmd.Env = env
|
||||||
cmd.Stdout = stdOut
|
cmd.Stdout = stdOut
|
||||||
cmd.Stderr = stdErr
|
cmd.Stderr = stdErr
|
||||||
|
if stdIn != nil {
|
||||||
|
cmd.Stdin = stdIn
|
||||||
|
}
|
||||||
|
|
||||||
if err := cmd.Start(); err != nil {
|
if err := cmd.Start(); err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ import (
|
||||||
"code.gitea.io/gitea/modules/process"
|
"code.gitea.io/gitea/modules/process"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/services/gitdiff"
|
"code.gitea.io/gitea/services/gitdiff"
|
||||||
|
|
||||||
|
"github.com/mcuadros/go-version"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TemporaryUploadRepository is a type to wrap our upload repositories as a shallow clone
|
// TemporaryUploadRepository is a type to wrap our upload repositories as a shallow clone
|
||||||
|
@ -254,6 +256,11 @@ func (t *TemporaryUploadRepository) CommitTree(author, committer *models.User, t
|
||||||
authorSig := author.NewGitSig()
|
authorSig := author.NewGitSig()
|
||||||
committerSig := committer.NewGitSig()
|
committerSig := committer.NewGitSig()
|
||||||
|
|
||||||
|
binVersion, err := git.BinVersion()
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("Unable to get git version: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: Should we add SSH_ORIGINAL_COMMAND to this
|
// FIXME: Should we add SSH_ORIGINAL_COMMAND to this
|
||||||
// Because this may call hooks we should pass in the environment
|
// Because this may call hooks we should pass in the environment
|
||||||
env := append(os.Environ(),
|
env := append(os.Environ(),
|
||||||
|
@ -264,11 +271,21 @@ func (t *TemporaryUploadRepository) CommitTree(author, committer *models.User, t
|
||||||
"GIT_COMMITTER_EMAIL="+committerSig.Email,
|
"GIT_COMMITTER_EMAIL="+committerSig.Email,
|
||||||
"GIT_COMMITTER_DATE="+commitTimeStr,
|
"GIT_COMMITTER_DATE="+commitTimeStr,
|
||||||
)
|
)
|
||||||
commitHash, stderr, err := process.GetManager().ExecDirEnv(5*time.Minute,
|
messageBytes := new(bytes.Buffer)
|
||||||
|
_, _ = messageBytes.WriteString(message)
|
||||||
|
_, _ = messageBytes.WriteString("\n")
|
||||||
|
|
||||||
|
args := []string{"commit-tree", treeHash, "-p", "HEAD"}
|
||||||
|
if version.Compare(binVersion, "2.0.0", ">=") {
|
||||||
|
args = append(args, "--no-gpg-sign")
|
||||||
|
}
|
||||||
|
|
||||||
|
commitHash, stderr, err := process.GetManager().ExecDirEnvStdIn(5*time.Minute,
|
||||||
t.basePath,
|
t.basePath,
|
||||||
fmt.Sprintf("commitTree (git commit-tree): %s", t.basePath),
|
fmt.Sprintf("commitTree (git commit-tree): %s", t.basePath),
|
||||||
env,
|
env,
|
||||||
git.GitExecutable, "commit-tree", treeHash, "-p", "HEAD", "-m", message)
|
messageBytes,
|
||||||
|
git.GitExecutable, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("git commit-tree: %s", stderr)
|
return "", fmt.Errorf("git commit-tree: %s", stderr)
|
||||||
}
|
}
|
||||||
|
@ -328,6 +345,12 @@ func (t *TemporaryUploadRepository) DiffIndex() (diff *gitdiff.Diff, err error)
|
||||||
|
|
||||||
// CheckAttribute checks the given attribute of the provided files
|
// CheckAttribute checks the given attribute of the provided files
|
||||||
func (t *TemporaryUploadRepository) CheckAttribute(attribute string, args ...string) (map[string]map[string]string, error) {
|
func (t *TemporaryUploadRepository) CheckAttribute(attribute string, args ...string) (map[string]map[string]string, error) {
|
||||||
|
binVersion, err := git.BinVersion()
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Error retrieving git version: %v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
stdOut := new(bytes.Buffer)
|
stdOut := new(bytes.Buffer)
|
||||||
stdErr := new(bytes.Buffer)
|
stdErr := new(bytes.Buffer)
|
||||||
|
|
||||||
|
@ -335,7 +358,14 @@ func (t *TemporaryUploadRepository) CheckAttribute(attribute string, args ...str
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
cmdArgs := []string{"check-attr", "-z", attribute, "--cached", "--"}
|
cmdArgs := []string{"check-attr", "-z", attribute}
|
||||||
|
|
||||||
|
// git check-attr --cached first appears in git 1.7.8
|
||||||
|
if version.Compare(binVersion, "1.7.8", ">=") {
|
||||||
|
cmdArgs = append(cmdArgs, "--cached")
|
||||||
|
}
|
||||||
|
cmdArgs = append(cmdArgs, "--")
|
||||||
|
|
||||||
for _, arg := range args {
|
for _, arg := range args {
|
||||||
if arg != "" {
|
if arg != "" {
|
||||||
cmdArgs = append(cmdArgs, arg)
|
cmdArgs = append(cmdArgs, arg)
|
||||||
|
@ -353,7 +383,7 @@ func (t *TemporaryUploadRepository) CheckAttribute(attribute string, args ...str
|
||||||
}
|
}
|
||||||
|
|
||||||
pid := process.GetManager().Add(desc, cmd)
|
pid := process.GetManager().Add(desc, cmd)
|
||||||
err := cmd.Wait()
|
err = cmd.Wait()
|
||||||
process.GetManager().Remove(pid)
|
process.GetManager().Remove(pid)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -313,12 +313,6 @@ func CreateOrUpdateRepoFile(repo *models.Repository, doer *models.User, opts *Up
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check there is no way this can return multiple infos
|
|
||||||
filename2attribute2info, err := t.CheckAttribute("filter", treePath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
content := opts.Content
|
content := opts.Content
|
||||||
if bom {
|
if bom {
|
||||||
content = string(charset.UTF8BOM) + content
|
content = string(charset.UTF8BOM) + content
|
||||||
|
@ -341,7 +335,14 @@ func CreateOrUpdateRepoFile(repo *models.Repository, doer *models.User, opts *Up
|
||||||
opts.Content = content
|
opts.Content = content
|
||||||
var lfsMetaObject *models.LFSMetaObject
|
var lfsMetaObject *models.LFSMetaObject
|
||||||
|
|
||||||
if setting.LFS.StartServer && filename2attribute2info[treePath] != nil && filename2attribute2info[treePath]["filter"] == "lfs" {
|
if setting.LFS.StartServer {
|
||||||
|
// Check there is no way this can return multiple infos
|
||||||
|
filename2attribute2info, err := t.CheckAttribute("filter", treePath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if filename2attribute2info[treePath] != nil && filename2attribute2info[treePath]["filter"] == "lfs" {
|
||||||
// OK so we are supposed to LFS this data!
|
// OK so we are supposed to LFS this data!
|
||||||
oid, err := models.GenerateLFSOid(strings.NewReader(opts.Content))
|
oid, err := models.GenerateLFSOid(strings.NewReader(opts.Content))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -350,7 +351,7 @@ func CreateOrUpdateRepoFile(repo *models.Repository, doer *models.User, opts *Up
|
||||||
lfsMetaObject = &models.LFSMetaObject{Oid: oid, Size: int64(len(opts.Content)), RepositoryID: repo.ID}
|
lfsMetaObject = &models.LFSMetaObject{Oid: oid, Size: int64(len(opts.Content)), RepositoryID: repo.ID}
|
||||||
content = lfsMetaObject.Pointer()
|
content = lfsMetaObject.Pointer()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Add the object to the database
|
// Add the object to the database
|
||||||
objectHash, err := t.HashObject(strings.NewReader(content))
|
objectHash, err := t.HashObject(strings.NewReader(content))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -74,10 +74,13 @@ func UploadRepoFiles(repo *models.Repository, doer *models.User, opts *UploadRep
|
||||||
infos[i] = uploadInfo{upload: upload}
|
infos[i] = uploadInfo{upload: upload}
|
||||||
}
|
}
|
||||||
|
|
||||||
filename2attribute2info, err := t.CheckAttribute("filter", names...)
|
var filename2attribute2info map[string]map[string]string
|
||||||
|
if setting.LFS.StartServer {
|
||||||
|
filename2attribute2info, err = t.CheckAttribute("filter", names...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Copy uploaded files into repository.
|
// Copy uploaded files into repository.
|
||||||
for i, uploadInfo := range infos {
|
for i, uploadInfo := range infos {
|
||||||
|
@ -88,7 +91,7 @@ func UploadRepoFiles(repo *models.Repository, doer *models.User, opts *UploadRep
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
var objectHash string
|
var objectHash string
|
||||||
if filename2attribute2info[uploadInfo.upload.Name] != nil && filename2attribute2info[uploadInfo.upload.Name]["filter"] == "lfs" {
|
if setting.LFS.StartServer && filename2attribute2info[uploadInfo.upload.Name] != nil && filename2attribute2info[uploadInfo.upload.Name]["filter"] == "lfs" {
|
||||||
// Handle LFS
|
// Handle LFS
|
||||||
// FIXME: Inefficient! this should probably happen in models.Upload
|
// FIXME: Inefficient! this should probably happen in models.Upload
|
||||||
oid, err := models.GenerateLFSOid(file)
|
oid, err := models.GenerateLFSOid(file)
|
||||||
|
|
|
@ -91,7 +91,7 @@ func AddressNoCredentials(m *models.Mirror) string {
|
||||||
func SaveAddress(m *models.Mirror, addr string) error {
|
func SaveAddress(m *models.Mirror, addr string) error {
|
||||||
repoPath := m.Repo.RepoPath()
|
repoPath := m.Repo.RepoPath()
|
||||||
// Remove old origin
|
// Remove old origin
|
||||||
_, err := git.NewCommand("remote", "remove", "origin").RunInDir(repoPath)
|
_, err := git.NewCommand("remote", "rm", "origin").RunInDir(repoPath)
|
||||||
if err != nil && !strings.HasPrefix(err.Error(), "exit status 128 - fatal: No such remote ") {
|
if err != nil && !strings.HasPrefix(err.Error(), "exit status 128 - fatal: No such remote ") {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -22,6 +21,8 @@ import (
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
|
|
||||||
|
"github.com/mcuadros/go-version"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Merge merges pull request to base repository.
|
// 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)
|
headRepoPath := models.RepoPath(pr.HeadUserName, pr.HeadRepo.Name)
|
||||||
|
|
||||||
if err := git.Clone(baseGitRepo.Path, tmpBasePath, git.CloneRepoOptions{
|
if err := git.InitRepository(tmpBasePath, false); err != nil {
|
||||||
Shared: true,
|
return fmt.Errorf("git init: %v", err)
|
||||||
NoCheckout: true,
|
|
||||||
Branch: pr.BaseBranch,
|
|
||||||
}); err != nil {
|
|
||||||
return fmt.Errorf("git clone: %v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
remoteRepoName := "head_repo"
|
remoteRepoName := "head_repo"
|
||||||
|
baseBranch := "base"
|
||||||
|
|
||||||
// Add head repo remote.
|
// Add head repo remote.
|
||||||
addCacheRepo := func(staging, cache string) error {
|
addCacheRepo := func(staging, cache string) error {
|
||||||
p := filepath.Join(staging, ".git", "objects", "info", "alternates")
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -91,25 +89,41 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor
|
||||||
return nil
|
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)
|
return fmt.Errorf("addCacheRepo [%s -> %s]: %v", headRepoPath, tmpBasePath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var errbuf strings.Builder
|
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 {
|
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())
|
return fmt.Errorf("git remote add [%s -> %s]: %s", headRepoPath, tmpBasePath, errbuf.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trackingBranch := "tracking"
|
||||||
// Fetch head branch
|
// 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())
|
return fmt.Errorf("git fetch [%s -> %s]: %s", headRepoPath, tmpBasePath, errbuf.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
trackingBranch := path.Join(remoteRepoName, pr.HeadBranch)
|
stagingBranch := "staging"
|
||||||
stagingBranch := fmt.Sprintf("%s_%s", remoteRepoName, pr.HeadBranch)
|
|
||||||
|
|
||||||
// Enable sparse-checkout
|
// Enable sparse-checkout
|
||||||
sparseCheckoutList, err := getDiffTree(tmpBasePath, pr.BaseBranch, trackingBranch)
|
sparseCheckoutList, err := getDiffTree(tmpBasePath, baseBranch, trackingBranch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("getDiffTree: %v", err)
|
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)
|
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)
|
// 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())
|
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())
|
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())
|
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())
|
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())
|
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())
|
return fmt.Errorf("git checkout: %s", errbuf.String())
|
||||||
}
|
}
|
||||||
// Rebase before merging
|
// 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())
|
return fmt.Errorf("git rebase [%s -> %s]: %s", headRepoPath, tmpBasePath, errbuf.String())
|
||||||
}
|
}
|
||||||
// Checkout base branch again
|
// 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())
|
return fmt.Errorf("git checkout: %s", errbuf.String())
|
||||||
}
|
}
|
||||||
// Merge fast forward
|
// 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())
|
return fmt.Errorf("git checkout: %s", errbuf.String())
|
||||||
}
|
}
|
||||||
// Rebase before merging
|
// 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())
|
return fmt.Errorf("git rebase [%s -> %s]: %s", headRepoPath, tmpBasePath, errbuf.String())
|
||||||
}
|
}
|
||||||
// Checkout base branch again
|
// 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())
|
return fmt.Errorf("git checkout: %s", errbuf.String())
|
||||||
}
|
}
|
||||||
// Prepare merge with commit
|
// Prepare merge with commit
|
||||||
|
@ -216,7 +246,7 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to get full commit id for HEAD: %v", err)
|
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to get full commit id for origin/%s: %v", pr.BaseBranch, err)
|
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.
|
// 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())
|
return fmt.Errorf("git push: %s", errbuf.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue