diff options
author | Stan Hu <stanhu@gmail.com> | 2020-01-25 11:45:49 +0300 |
---|---|---|
committer | Stan Hu <stanhu@gmail.com> | 2020-01-25 18:13:29 +0300 |
commit | e9fc43bd8bca4aa2a45dd3d4ce596a6615049e01 (patch) | |
tree | 38a2bf0618c05a092fc9c14965c99e5c179a076f /internal | |
parent | cdb513169e7c062f99aa831f827660f869465454 (diff) |
Fix squash when target repository has a renamed file
If a file were renamed on the target branch but the source branch still
contained the original file, previously squash would fail with `error:
Sparse checkout leaves no entry on working directory`. This happens
because of the way a worktree is created with squash:
1. `git diff --name-only <START_SHA>...<END_SHA>`, where START_SHA and
END_SHA are from the source branch.
2. This will populate `info/sparse-checkout` with the files changed on
the source branch.
3. We then checkout the target branch, which fails if all of the changed
files from the source branch do not exist on it.
A squash should not be confused with a squash and rebase. Squash should
simply take the existing commits on the branch and collapse them into
one. The target branch is irrelevant, and so we should ignore the branch
parameter entirely.
Closes https://gitlab.com/gitlab-org/gitaly/issues/2395
Diffstat (limited to 'internal')
-rw-r--r-- | internal/service/operations/squash_test.go | 69 |
1 files changed, 66 insertions, 3 deletions
diff --git a/internal/service/operations/squash_test.go b/internal/service/operations/squash_test.go index 25e4936e0..f7ce71f41 100644 --- a/internal/service/operations/squash_test.go +++ b/internal/service/operations/squash_test.go @@ -108,7 +108,7 @@ func TestSuccessfulUserSquashRequestWith3wayMerge(t *testing.T) { commit, err := log.GetCommit(ctx, testRepo, response.SquashSha) require.NoError(t, err) - require.Equal(t, []string{"3d05a143ac193c1a6fe4d046a6e3fe71e825258a"}, commit.ParentIds) + require.Equal(t, []string{"6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9"}, commit.ParentIds) require.Equal(t, author.Name, commit.Author.Name) require.Equal(t, author.Email, commit.Author.Email) require.Equal(t, user.Name, commit.Committer.Name) @@ -158,7 +158,70 @@ func TestSplitIndex(t *testing.T) { require.False(t, ensureSplitIndexExists(t, testRepoPath)) } -func TestFailedUserSquashRequestDueToGitError(t *testing.T) { +func TestSquashRequestWithRenamedFiles(t *testing.T) { + ctx, cancel := testhelper.Context() + defer cancel() + + server, serverSocketPath := runOperationServiceServer(t) + defer server.Stop() + + client, conn := NewOperationClient(t, serverSocketPath) + defer conn.Close() + + testRepo, testRepoPath, cleanupFn := testhelper.NewTestRepoWithWorktree(t) + defer cleanupFn() + + originalFilename := "original-file.txt" + renamedFilename := "renamed-file.txt" + + testhelper.MustRunCommand(t, nil, "git", "-C", testRepoPath, "config", "user.name", string(author.Name)) + testhelper.MustRunCommand(t, nil, "git", "-C", testRepoPath, "config", "user.email", string(author.Email)) + testhelper.MustRunCommand(t, nil, "git", "-C", testRepoPath, "checkout", "-b", "squash-rename-test", "master") + require.NoError(t, ioutil.WriteFile(filepath.Join(testRepoPath, originalFilename), []byte("This is a test"), 0644)) + testhelper.MustRunCommand(t, nil, "git", "-C", testRepoPath, "add", ".") + testhelper.MustRunCommand(t, nil, "git", "-C", testRepoPath, "commit", "-m", "test file") + + startCommitID := text.ChompBytes(testhelper.MustRunCommand(t, nil, "git", "-C", testRepoPath, "rev-parse", "HEAD")) + + testhelper.MustRunCommand(t, nil, "git", "-C", testRepoPath, "mv", originalFilename, renamedFilename) + testhelper.MustRunCommand(t, nil, "git", "-C", testRepoPath, "commit", "-a", "-m", "renamed test file") + + // Modify the original file in another branch + testhelper.MustRunCommand(t, nil, "git", "-C", testRepoPath, "checkout", "-b", "squash-rename-branch", startCommitID) + require.NoError(t, ioutil.WriteFile(filepath.Join(testRepoPath, originalFilename), []byte("This is a change"), 0644)) + testhelper.MustRunCommand(t, nil, "git", "-C", testRepoPath, "commit", "-a", "-m", "test") + + require.NoError(t, ioutil.WriteFile(filepath.Join(testRepoPath, originalFilename), []byte("This is another change"), 0644)) + testhelper.MustRunCommand(t, nil, "git", "-C", testRepoPath, "commit", "-a", "-m", "test") + + endCommitID := text.ChompBytes(testhelper.MustRunCommand(t, nil, "git", "-C", testRepoPath, "rev-parse", "HEAD")) + + request := &gitalypb.UserSquashRequest{ + Repository: testRepo, + User: user, + SquashId: "1", + Branch: []byte("squash-rename-test"), + Author: author, + CommitMessage: commitMessage, + StartSha: startCommitID, + EndSha: endCommitID, + } + + response, err := client.UserSquash(ctx, request) + require.NoError(t, err) + require.Empty(t, response.GetGitError()) + + commit, err := log.GetCommit(ctx, testRepo, response.SquashSha) + require.NoError(t, err) + require.Equal(t, []string{startCommitID}, commit.ParentIds) + require.Equal(t, author.Name, commit.Author.Name) + require.Equal(t, author.Email, commit.Author.Email) + require.Equal(t, user.Name, commit.Committer.Name) + require.Equal(t, user.Email, commit.Committer.Email) + require.Equal(t, commitMessage, commit.Subject) +} + +func TestSuccessfulUserSquashRequestWithMissingFileOnTargetBranch(t *testing.T) { ctx, cancel := testhelper.Context() defer cancel() @@ -187,7 +250,7 @@ func TestFailedUserSquashRequestDueToGitError(t *testing.T) { response, err := client.UserSquash(ctx, request) require.NoError(t, err) - require.Contains(t, response.GitError, "error: large_diff_old_name.md: does not exist in index") + require.Empty(t, response.GetGitError()) } func TestFailedUserSquashRequestDueToValidations(t *testing.T) { |