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:
authorPiotr Stankowski <git@trakos.pl>2022-01-10 17:41:29 +0300
committerPiotr Stankowski <git@trakos.pl>2022-03-07 22:25:08 +0300
commit017cbb2606fe2e92596476d9174533bcdc2faa2a (patch)
treec8167c2176d4f7db20e759346f0df3de47a6a780
parent1d72d52eb7743c84b268e0fe9aceaed5c4f56b88 (diff)
git2go: Add squash parameter to MergeCommand
This change adds support for squashing in gitaly-git2go merge. This will allow developing new RPC for squash that would be more optimized, and wouldn't have to use rebase before performing merge. We simply use the same strategy as for merge, the only difference is that we set only one parent to the merge commit. Changelog: added
-rw-r--r--cmd/gitaly-git2go/merge.go8
-rw-r--r--cmd/gitaly-git2go/merge_test.go127
-rw-r--r--internal/git2go/merge.go4
3 files changed, 138 insertions, 1 deletions
diff --git a/cmd/gitaly-git2go/merge.go b/cmd/gitaly-git2go/merge.go
index f97125061..80c9662d1 100644
--- a/cmd/gitaly-git2go/merge.go
+++ b/cmd/gitaly-git2go/merge.go
@@ -98,7 +98,13 @@ func merge(request git2go.MergeCommand) (string, error) {
committer = git.Signature(git2go.NewSignature(request.CommitterName, request.CommitterMail, request.CommitterDate))
}
- commit, err := repo.CreateCommitFromIds("", &author, &committer, request.Message, tree, ours.Id(), theirs.Id())
+ var parents []*git.Oid
+ if request.Squash {
+ parents = []*git.Oid{ours.Id()}
+ } else {
+ parents = []*git.Oid{ours.Id(), theirs.Id()}
+ }
+ commit, err := repo.CreateCommitFromIds("", &author, &committer, request.Message, tree, parents...)
if err != nil {
return "", fmt.Errorf("could not create merge commit: %w", err)
}
diff --git a/cmd/gitaly-git2go/merge_test.go b/cmd/gitaly-git2go/merge_test.go
index b9fff3f6e..da438e527 100644
--- a/cmd/gitaly-git2go/merge_test.go
+++ b/cmd/gitaly-git2go/merge_test.go
@@ -118,6 +118,7 @@ func TestMerge_trees(t *testing.T) {
theirs map[string]string
expected map[string]string
withCommitter bool
+ squash bool
expectedResponse git2go.MergeResult
expectedErr error
}{
@@ -159,6 +160,25 @@ func TestMerge_trees(t *testing.T) {
},
},
{
+ desc: "trivial squash succeeds",
+ base: map[string]string{
+ "file": "a",
+ },
+ ours: map[string]string{
+ "file": "a",
+ },
+ theirs: map[string]string{
+ "file": "a",
+ },
+ expected: map[string]string{
+ "file": "a",
+ },
+ squash: true,
+ expectedResponse: git2go.MergeResult{
+ CommitID: "d4c52f063cd6544959d6b0d9a3d8fa8463c34086",
+ },
+ },
+ {
desc: "non-trivial merge succeeds",
base: map[string]string{
"file": "a\nb\nc\nd\ne\nf\n",
@@ -177,6 +197,25 @@ func TestMerge_trees(t *testing.T) {
},
},
{
+ desc: "non-trivial squash succeeds",
+ base: map[string]string{
+ "file": "a\nb\nc\nd\ne\nf\n",
+ },
+ ours: map[string]string{
+ "file": "0\na\nb\nc\nd\ne\nf\n",
+ },
+ theirs: map[string]string{
+ "file": "a\nb\nc\nd\ne\nf\n0\n",
+ },
+ expected: map[string]string{
+ "file": "0\na\nb\nc\nd\ne\nf\n0\n",
+ },
+ squash: true,
+ expectedResponse: git2go.MergeResult{
+ CommitID: "7ef7460f69503265a247e06218391cfa57c521fc",
+ },
+ },
+ {
desc: "multiple files succeed",
base: map[string]string{
"1": "foo",
@@ -203,6 +242,33 @@ func TestMerge_trees(t *testing.T) {
},
},
{
+ desc: "multiple files squash succeed",
+ base: map[string]string{
+ "1": "foo",
+ "2": "bar",
+ "3": "qux",
+ },
+ ours: map[string]string{
+ "1": "foo",
+ "2": "modified",
+ "3": "qux",
+ },
+ theirs: map[string]string{
+ "1": "modified",
+ "2": "bar",
+ "3": "qux",
+ },
+ expected: map[string]string{
+ "1": "modified",
+ "2": "modified",
+ "3": "qux",
+ },
+ squash: true,
+ expectedResponse: git2go.MergeResult{
+ CommitID: "a680459fe541be728c8494fb76c233a344c04460",
+ },
+ },
+ {
desc: "conflicting merge fails",
base: map[string]string{
"1": "foo",
@@ -240,6 +306,7 @@ func TestMerge_trees(t *testing.T) {
Message: "Merge message",
Ours: ours.String(),
Theirs: theirs.String(),
+ Squash: tc.squash,
}
if tc.withCommitter {
mergeCommand.CommitterName = "Jane Doe"
@@ -282,6 +349,66 @@ func TestMerge_trees(t *testing.T) {
}
}
+func TestMerge_squash(t *testing.T) {
+ t.Parallel()
+
+ ctx := testhelper.Context(t)
+
+ cfg, repoProto, repoPath := testcfg.BuildWithRepo(t)
+ testcfg.BuildGitalyGit2Go(t, cfg)
+ executor := buildExecutor(t, cfg)
+
+ baseFiles := map[string]string{"file.txt": "b\nc"}
+ ourFiles := map[string]string{"file.txt": "a\nb\nc"}
+ theirFiles1 := map[string]string{"file.txt": "b\nc\nd"}
+ theirFiles2 := map[string]string{"file.txt": "b\nc\nd\ne"}
+
+ base := cmdtesthelper.BuildCommit(t, repoPath, []*git.Oid{nil}, baseFiles)
+ ours := cmdtesthelper.BuildCommit(t, repoPath, []*git.Oid{base}, ourFiles)
+ theirs1 := cmdtesthelper.BuildCommit(t, repoPath, []*git.Oid{base}, theirFiles1)
+ theirs2 := cmdtesthelper.BuildCommit(t, repoPath, []*git.Oid{theirs1}, theirFiles2)
+
+ date := time.Date(2020, 7, 30, 7, 45, 50, 0, time.FixedZone("UTC+2", +2*60*60))
+ response, err := executor.Merge(ctx, repoProto, git2go.MergeCommand{
+ Repository: repoPath,
+ AuthorName: "John Doe",
+ AuthorMail: "john.doe@example.com",
+ AuthorDate: date,
+ Message: "Merge message",
+ Ours: ours.String(),
+ Theirs: theirs2.String(),
+ Squash: true,
+ })
+ require.NoError(t, err)
+ assert.Equal(t, "027d909803fbb3d17c3b10c1dfe8f120d99392e4", response.CommitID)
+
+ repo, err := git2goutil.OpenRepository(repoPath)
+ require.NoError(t, err)
+
+ commitOid, err := git.NewOid(response.CommitID)
+ require.NoError(t, err)
+
+ isDescendant, err := repo.DescendantOf(commitOid, theirs2)
+ require.NoError(t, err)
+ require.False(t, isDescendant)
+
+ commit, err := repo.LookupCommit(commitOid)
+ require.NoError(t, err)
+
+ require.Equal(t, uint(1), commit.ParentCount())
+ require.Equal(t, ours, commit.ParentId(0))
+
+ tree, err := commit.Tree()
+ require.NoError(t, err)
+
+ entry := tree.EntryByName("file.txt")
+ require.NotNil(t, entry)
+
+ blob, err := repo.LookupBlob(entry.Id)
+ require.NoError(t, err)
+ require.Equal(t, "a\nb\nc\nd\ne", string(blob.Contents()))
+}
+
func TestMerge_recursive(t *testing.T) {
t.Parallel()
ctx := testhelper.Context(t)
diff --git a/internal/git2go/merge.go b/internal/git2go/merge.go
index 17e9a4fe2..b0f2e5503 100644
--- a/internal/git2go/merge.go
+++ b/internal/git2go/merge.go
@@ -43,6 +43,10 @@ type MergeCommand struct {
// AllowConflicts controls whether conflicts are allowed. If they are,
// then conflicts will be committed as part of the result.
AllowConflicts bool
+ // Squash controls whether to perform squash merge.
+ // If set to `true`, then the resulting commit will have `Ours` as its only parent.
+ // Otherwise, a merge commit will be created with `Ours` and `Theirs` as its parents.
+ Squash bool
}
// MergeResult contains results from a merge.