Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Couder <chriscool@tuxfamily.org>2022-03-23 13:47:50 +0300
committerJohn Cai <jcai@gitlab.com>2022-11-03 16:15:13 +0300
commit86386d888ef621a89fca36d78f20e4df5d2caad7 (patch)
treec35c7abc40d39f0dfa5b58eb27a0b0373c36713e
parent7f688e1c2d0be4b21811f81b80eab2908c9432d4 (diff)
operations: Introduce MergeTreeMerge featureflag
This new featureflag is for using an implementation of UserMergeBranch that uses `git merge-tree` instead of the previous implementation based on git2go. Co-authored-by: John Cai <jcai@gitlab.com>
-rw-r--r--internal/gitaly/service/operations/merge.go50
-rw-r--r--internal/gitaly/service/operations/merge_test.go75
-rw-r--r--internal/metadata/featureflag/ff_merge_git_merge-tree.go10
3 files changed, 112 insertions, 23 deletions
diff --git a/internal/gitaly/service/operations/merge.go b/internal/gitaly/service/operations/merge.go
index d1a1f6b8b..876a6bcf4 100644
--- a/internal/gitaly/service/operations/merge.go
+++ b/internal/gitaly/service/operations/merge.go
@@ -15,6 +15,7 @@ import (
"gitlab.com/gitlab-org/gitaly/v15/internal/git2go"
"gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook"
"gitlab.com/gitlab-org/gitaly/v15/internal/helper"
+ "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag"
"gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"
)
@@ -46,6 +47,20 @@ func validateMergeBranchRequest(request *gitalypb.UserMergeBranchRequest) error
return nil
}
+func (s *Server) merge(
+ ctx context.Context,
+ repoPath string,
+ quarantineRepo *localrepo.Repo,
+ authorName string,
+ authorMail string,
+ authorDate time.Time,
+ message string,
+ ours string,
+ theirs string,
+) (string, error) {
+ return "", helper.ErrInternalf("UserMergeBranch using Git is not yet implemented")
+}
+
func (s *Server) mergeWithGit2Go(
ctx context.Context,
repoPath string,
@@ -66,7 +81,6 @@ func (s *Server) mergeWithGit2Go(
Ours: ours,
Theirs: theirs,
})
-
if err != nil {
if errors.Is(err, git2go.ErrInvalidArgument) {
return "", helper.ErrInvalidArgument(err)
@@ -113,16 +127,30 @@ func (s *Server) UserMergeBranch(stream gitalypb.OperationService_UserMergeBranc
return helper.ErrInvalidArgument(err)
}
- commitID, err := s.mergeWithGit2Go(ctx, repoPath, quarantineRepo,
- string(firstRequest.User.Name),
- string(firstRequest.User.Email),
- authorDate,
- string(firstRequest.Message),
- revision.String(),
- firstRequest.CommitId)
- if err != nil {
+ var mergeCommitID string
+ var mergeErr error
+
+ if featureflag.MergeTreeMerge.IsEnabled(ctx) {
+ mergeCommitID, mergeErr = s.merge(ctx, repoPath, quarantineRepo,
+ string(firstRequest.User.Name),
+ string(firstRequest.User.Email),
+ authorDate,
+ string(firstRequest.Message),
+ revision.String(),
+ firstRequest.CommitId)
+ } else {
+ mergeCommitID, mergeErr = s.mergeWithGit2Go(ctx, repoPath, quarantineRepo,
+ string(firstRequest.User.Name),
+ string(firstRequest.User.Email),
+ authorDate,
+ string(firstRequest.Message),
+ revision.String(),
+ firstRequest.CommitId)
+ }
+
+ if mergeErr != nil {
var conflictErr git2go.ConflictingFilesError
- if errors.As(err, &conflictErr) {
+ if errors.As(mergeErr, &conflictErr) {
conflictingFiles := make([][]byte, 0, len(conflictErr.ConflictingFiles))
for _, conflictingFile := range conflictErr.ConflictingFiles {
conflictingFiles = append(conflictingFiles, []byte(conflictingFile))
@@ -152,7 +180,7 @@ func (s *Server) UserMergeBranch(stream gitalypb.OperationService_UserMergeBranc
return err
}
- mergeOID, err := git.ObjectHashSHA1.FromHex(commitID)
+ mergeOID, err := git.ObjectHashSHA1.FromHex(mergeCommitID)
if err != nil {
return helper.ErrInternalf("could not parse merge ID: %w", err)
}
diff --git a/internal/gitaly/service/operations/merge_test.go b/internal/gitaly/service/operations/merge_test.go
index 3965bb435..af041e720 100644
--- a/internal/gitaly/service/operations/merge_test.go
+++ b/internal/gitaly/service/operations/merge_test.go
@@ -24,6 +24,7 @@ import (
"gitlab.com/gitlab-org/gitaly/v15/internal/gitlab"
"gitlab.com/gitlab-org/gitaly/v15/internal/helper"
"gitlab.com/gitlab-org/gitaly/v15/internal/helper/text"
+ "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag"
"gitlab.com/gitlab-org/gitaly/v15/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg"
"gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver"
@@ -42,8 +43,14 @@ var (
func TestUserMergeBranch_successful(t *testing.T) {
t.Parallel()
+ testhelper.NewFeatureSets(featureflag.MergeTreeMerge).Run(
+ t,
+ testUserMergeBranchSuccessful,
+ )
+}
- ctx := testhelper.Context(t)
+func testUserMergeBranchSuccessful(t *testing.T, ctx context.Context) {
+ t.Parallel()
ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx)
@@ -224,9 +231,13 @@ func TestUserMergeBranch_failure(t *testing.T) {
func TestUserMergeBranch_quarantine(t *testing.T) {
t.Parallel()
+ testhelper.NewFeatureSets(featureflag.MergeTreeMerge).Run(
+ t,
+ testUserMergeBranchQuarantine,
+ )
+}
- ctx := testhelper.Context(t)
-
+func testUserMergeBranchQuarantine(t *testing.T, ctx context.Context) {
ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx)
repo := localrepo.NewTestRepo(t, cfg, repoProto)
@@ -282,8 +293,14 @@ func TestUserMergeBranch_quarantine(t *testing.T) {
func TestUserMergeBranch_stableMergeIDs(t *testing.T) {
t.Parallel()
+ testhelper.NewFeatureSets(featureflag.MergeTreeMerge).Run(
+ t,
+ testUserMergeBranchStableMergeIDs,
+ )
+}
- ctx := testhelper.Context(t)
+func testUserMergeBranchStableMergeIDs(t *testing.T, ctx context.Context) {
+ t.Parallel()
ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx)
@@ -309,7 +326,7 @@ func TestUserMergeBranch_stableMergeIDs(t *testing.T) {
require.NoError(t, mergeBidi.Send(firstRequest), "send first request")
response, err := mergeBidi.Recv()
require.NoError(t, err, "receive first response")
- require.Equal(t, response.CommitId, expectedMergeID)
+ require.Equal(t, expectedMergeID, response.CommitId)
require.NoError(t, mergeBidi.Send(&gitalypb.UserMergeBranchRequest{Apply: true}), "apply merge")
response, err = mergeBidi.Recv()
@@ -350,8 +367,14 @@ func TestUserMergeBranch_stableMergeIDs(t *testing.T) {
func TestUserMergeBranch_abort(t *testing.T) {
t.Parallel()
+ testhelper.NewFeatureSets(featureflag.MergeTreeMerge).Run(
+ t,
+ testUserMergeBranchAbort,
+ )
+}
- ctx := testhelper.Context(t)
+func testUserMergeBranchAbort(t *testing.T, ctx context.Context) {
+ t.Parallel()
ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx)
@@ -414,8 +437,14 @@ func TestUserMergeBranch_abort(t *testing.T) {
func TestUserMergeBranch_concurrentUpdate(t *testing.T) {
t.Parallel()
+ testhelper.NewFeatureSets(featureflag.MergeTreeMerge).Run(
+ t,
+ testUserMergeBranchConcurrentUpdate,
+ )
+}
- ctx := testhelper.Context(t)
+func testUserMergeBranchConcurrentUpdate(t *testing.T, ctx context.Context) {
+ t.Parallel()
ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx)
@@ -470,8 +499,14 @@ func TestUserMergeBranch_concurrentUpdate(t *testing.T) {
func TestUserMergeBranch_ambiguousReference(t *testing.T) {
t.Parallel()
+ testhelper.NewFeatureSets(featureflag.MergeTreeMerge).Run(
+ t,
+ testUserMergeBranchAmbiguousReference,
+ )
+}
- ctx := testhelper.Context(t)
+func testUserMergeBranchAmbiguousReference(t *testing.T, ctx context.Context) {
+ t.Parallel()
ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx)
@@ -532,8 +567,14 @@ func TestUserMergeBranch_ambiguousReference(t *testing.T) {
func TestUserMergeBranch_failingHooks(t *testing.T) {
t.Parallel()
+ testhelper.NewFeatureSets(featureflag.MergeTreeMerge).Run(
+ t,
+ testUserMergeBranchFailingHooks,
+ )
+}
- ctx := testhelper.Context(t)
+func testUserMergeBranchFailingHooks(t *testing.T, ctx context.Context) {
+ t.Parallel()
ctx, cfg, repo, repoPath, client := setupOperationsService(t, ctx)
@@ -623,8 +664,14 @@ func TestUserMergeBranch_failingHooks(t *testing.T) {
func TestUserMergeBranch_conflict(t *testing.T) {
t.Parallel()
+ testhelper.NewFeatureSets(featureflag.MergeTreeMerge).Run(
+ t,
+ testUserMergeBranchConflict,
+ )
+}
- ctx := testhelper.Context(t)
+func testUserMergeBranchConflict(t *testing.T, ctx context.Context) {
+ t.Parallel()
ctx, cfg, repoProto, repoPath, client := setupOperationsService(t, ctx)
@@ -679,9 +726,13 @@ func TestUserMergeBranch_conflict(t *testing.T) {
func TestUserMergeBranch_allowed(t *testing.T) {
t.Parallel()
+ testhelper.NewFeatureSets(featureflag.MergeTreeMerge).Run(
+ t,
+ testUserMergeBranchAllowed,
+ )
+}
- ctx := testhelper.Context(t)
-
+func testUserMergeBranchAllowed(t *testing.T, ctx context.Context) {
mergeBranchHeadAfter := "ff0ac4dfa30d6b26fd14aa83a75650355270bf76"
for _, tc := range []struct {
diff --git a/internal/metadata/featureflag/ff_merge_git_merge-tree.go b/internal/metadata/featureflag/ff_merge_git_merge-tree.go
new file mode 100644
index 000000000..38539e074
--- /dev/null
+++ b/internal/metadata/featureflag/ff_merge_git_merge-tree.go
@@ -0,0 +1,10 @@
+package featureflag
+
+// MergeTreeMerge enables implementation of UserMergeBranch using
+// `git merge-tree` instead of s.git2goExecutor.Merge()
+var MergeTreeMerge = NewFeatureFlag(
+ "merge_tree_merge",
+ "15.6.0",
+ "https://gitlab.com/gitlab-org/gitaly/-/issues/4600",
+ false,
+)