diff options
author | Xing Xin <xingxin.xx@bytedance.com> | 2023-09-18 12:00:37 +0300 |
---|---|---|
committer | Xing Xin <xingxin.xx@bytedance.com> | 2023-09-19 16:48:34 +0300 |
commit | 559b868d594b771e66fbb30e66b3a0a678633bb2 (patch) | |
tree | eb280c0f25824ebd3372d4b97e136b06543bbc40 | |
parent | a94d98ec843a50d3a27f827dbe9b074f135bbdd3 (diff) |
conflict: Respect user timezone for new commits
This commit serves as an addition to the fix for commit signatures
mentioned in [1]. Although we have fixed commit signatures for RPCs in
operations service, we unintentionally neglected the fact that
ResolveConflicts in conflicts service also generates new commits.
1. https://gitlab.com/gitlab-org/gitaly/-/merge_requests/6323
Signed-off-by: Xing Xin <xingxin.xx@bytedance.com>
-rw-r--r-- | internal/gitaly/service/conflicts/resolve_conflicts.go | 29 | ||||
-rw-r--r-- | internal/gitaly/service/conflicts/resolve_conflicts_test.go | 273 |
2 files changed, 201 insertions, 101 deletions
diff --git a/internal/gitaly/service/conflicts/resolve_conflicts.go b/internal/gitaly/service/conflicts/resolve_conflicts.go index 493a2a24e..c22987f72 100644 --- a/internal/gitaly/service/conflicts/resolve_conflicts.go +++ b/internal/gitaly/service/conflicts/resolve_conflicts.go @@ -10,7 +10,6 @@ import ( "path/filepath" "sort" "strings" - "time" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" "gitlab.com/gitlab-org/gitaly/v16/internal/git" @@ -102,6 +101,11 @@ func validateResolveConflictsHeader(locator storage.Locator, header *gitalypb.Re } func (s *server) resolveConflicts(header *gitalypb.ResolveConflictsRequestHeader, stream gitalypb.ConflictsService_ResolveConflictsServer) error { + authorSignature, err := git.SignatureFromRequest(header) + if err != nil { + return structerr.NewInvalidArgument("%w", err) + } + b := bytes.NewBuffer(nil) for { req, err := stream.Recv() @@ -154,11 +158,6 @@ func (s *server) resolveConflicts(header *gitalypb.ResolveConflictsRequestHeader return err } - authorDate := time.Now() - if header.Timestamp != nil { - authorDate = header.Timestamp.AsTime() - } - objectHash, err := quarantineRepo.ObjectHash(ctx) if err != nil { return fmt.Errorf("detecting object hash: %w", err) @@ -175,8 +174,7 @@ func (s *server) resolveConflicts(header *gitalypb.ResolveConflictsRequestHeader header.GetTheirCommitOid(), quarantineRepo, resolutions, - authorDate, - header.User, + authorSignature, header.GetCommitMessage(), ) if err != nil { @@ -203,8 +201,7 @@ func (s *server) resolveConflictsWithGit( ours, theirs string, repo *localrepo.Repo, resolutions []conflict.Resolution, - authorDate time.Time, - user *gitalypb.User, + author git.Signature, commitMessage []byte, ) (git.ObjectID, error) { treeOID, err := repo.MergeTree(ctx, ours, theirs, localrepo.WithAllowUnrelatedHistories()) @@ -344,12 +341,12 @@ func (s *server) resolveConflictsWithGit( commitOID, err := repo.WriteCommit(ctx, localrepo.WriteCommitConfig{ Parents: []git.ObjectID{git.ObjectID(ours), git.ObjectID(theirs)}, - CommitterDate: authorDate, - CommitterEmail: string(user.GetEmail()), - CommitterName: string(user.GetName()), - AuthorDate: authorDate, - AuthorEmail: string(user.GetEmail()), - AuthorName: string(user.GetName()), + CommitterDate: author.When, + CommitterEmail: author.Email, + CommitterName: author.Name, + AuthorDate: author.When, + AuthorEmail: author.Email, + AuthorName: author.Name, Message: string(commitMessage), TreeID: treeOID, }) diff --git a/internal/gitaly/service/conflicts/resolve_conflicts_test.go b/internal/gitaly/service/conflicts/resolve_conflicts_test.go index be4f7c41b..65c5fd71b 100644 --- a/internal/gitaly/service/conflicts/resolve_conflicts_test.go +++ b/internal/gitaly/service/conflicts/resolve_conflicts_test.go @@ -24,15 +24,6 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" ) -var ( - user = &gitalypb.User{ - Name: []byte("John Doe"), - Email: []byte("johndoe@gitlab.com"), - GlId: "user-1", - } - conflictResolutionCommitMessage = "Solve conflicts" -) - func TestResolveConflicts(t *testing.T) { t.Parallel() @@ -43,17 +34,28 @@ func TestResolveConflicts(t *testing.T) { func testResolveConflicts(t *testing.T, ctx context.Context) { type setupData struct { - cfg config.Cfg - requestHeader *gitalypb.ResolveConflictsRequest_Header - requestsFilesJSON []*gitalypb.ResolveConflictsRequest_FilesJson - client gitalypb.ConflictsServiceClient - repo *gitalypb.Repository - repoPath string - expectedContent map[string]map[string][]byte - expectedResponse *gitalypb.ResolveConflictsResponse - expectedError error - skipCommitCheck bool - additionalChecks func() + cfg config.Cfg + requestHeader *gitalypb.ResolveConflictsRequest_Header + requestsFilesJSON []*gitalypb.ResolveConflictsRequest_FilesJson + client gitalypb.ConflictsServiceClient + repo *gitalypb.Repository + repoPath string + expectedContent map[string]map[string][]byte + expectedCommitAuthor *gitalypb.CommitAuthor + expectedResponse *gitalypb.ResolveConflictsResponse + expectedError error + skipCommitCheck bool + additionalChecks func() + } + + conflictResolutionCommitMessage := "Solve conflicts" + defaultUser := gittest.TestUser + defaultTimestamp := ×tamppb.Timestamp{Seconds: 1234567890} + defaultCommitAuthor := &gitalypb.CommitAuthor{ + Name: []byte("Jane Doe"), + Email: []byte("janedoe@gitlab.com"), + Date: defaultTimestamp, + Timezone: []byte(gittest.TimezoneOffset), } for _, tc := range []struct { @@ -88,14 +90,15 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { TargetBranch: []byte("theirs"), SourceBranch: []byte("ours"), CommitMessage: []byte(conflictResolutionCommitMessage), - User: user, - Timestamp: ×tamppb.Timestamp{}, + User: defaultUser, + Timestamp: defaultTimestamp, }, }, requestsFilesJSON: []*gitalypb.ResolveConflictsRequest_FilesJson{ {FilesJson: filesJSON}, }, - expectedResponse: &gitalypb.ResolveConflictsResponse{}, + expectedCommitAuthor: defaultCommitAuthor, + expectedResponse: &gitalypb.ResolveConflictsResponse{}, expectedContent: map[string]map[string][]byte{ "refs/heads/ours": { "b": []byte("apricot"), @@ -147,15 +150,16 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { TargetBranch: []byte("theirs"), SourceBranch: []byte("ours"), CommitMessage: []byte(conflictResolutionCommitMessage), - User: user, - Timestamp: ×tamppb.Timestamp{}, + User: defaultUser, + Timestamp: defaultTimestamp, }, }, requestsFilesJSON: []*gitalypb.ResolveConflictsRequest_FilesJson{ {FilesJson: filesJSON[:50]}, {FilesJson: filesJSON[50:]}, }, - expectedResponse: &gitalypb.ResolveConflictsResponse{}, + expectedCommitAuthor: defaultCommitAuthor, + expectedResponse: &gitalypb.ResolveConflictsResponse{}, expectedContent: map[string]map[string][]byte{ "refs/heads/ours": { "a": []byte("apricot"), @@ -206,15 +210,16 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { TargetBranch: []byte("theirs"), SourceBranch: []byte("ours"), CommitMessage: []byte(conflictResolutionCommitMessage), - User: user, - Timestamp: ×tamppb.Timestamp{}, + User: defaultUser, + Timestamp: defaultTimestamp, }, }, requestsFilesJSON: []*gitalypb.ResolveConflictsRequest_FilesJson{ {FilesJson: filesJSON[:50]}, {FilesJson: filesJSON[50:]}, }, - expectedResponse: &gitalypb.ResolveConflictsResponse{}, + expectedCommitAuthor: defaultCommitAuthor, + expectedResponse: &gitalypb.ResolveConflictsResponse{}, expectedContent: map[string]map[string][]byte{ "refs/heads/ours": { "a": []byte("acai"), @@ -275,15 +280,16 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { TargetBranch: []byte("theirs"), SourceBranch: []byte("ours"), CommitMessage: []byte(conflictResolutionCommitMessage), - User: user, - Timestamp: ×tamppb.Timestamp{}, + User: defaultUser, + Timestamp: defaultTimestamp, }, }, requestsFilesJSON: []*gitalypb.ResolveConflictsRequest_FilesJson{ {FilesJson: filesJSON[:50]}, {FilesJson: filesJSON[50:]}, }, - expectedResponse: &gitalypb.ResolveConflictsResponse{}, + expectedCommitAuthor: defaultCommitAuthor, + expectedResponse: &gitalypb.ResolveConflictsResponse{}, expectedContent: map[string]map[string][]byte{ "refs/heads/ours": { "subdir/a": []byte("apricot"), @@ -330,15 +336,16 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { TargetBranch: []byte("theirs"), SourceBranch: []byte("ours"), CommitMessage: []byte(conflictResolutionCommitMessage), - User: user, - Timestamp: ×tamppb.Timestamp{}, + User: defaultUser, + Timestamp: defaultTimestamp, }, }, requestsFilesJSON: []*gitalypb.ResolveConflictsRequest_FilesJson{ {FilesJson: filesJSON[:50]}, {FilesJson: filesJSON[50:]}, }, - expectedResponse: &gitalypb.ResolveConflictsResponse{}, + expectedCommitAuthor: defaultCommitAuthor, + expectedResponse: &gitalypb.ResolveConflictsResponse{}, expectedContent: map[string]map[string][]byte{ "refs/heads/ours": { "a": []byte("apricot"), @@ -396,15 +403,16 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { TargetBranch: []byte("theirs"), SourceBranch: []byte("ours"), CommitMessage: []byte(conflictResolutionCommitMessage), - User: user, - Timestamp: ×tamppb.Timestamp{}, + User: defaultUser, + Timestamp: defaultTimestamp, }, }, requestsFilesJSON: []*gitalypb.ResolveConflictsRequest_FilesJson{ {FilesJson: filesJSON[:50]}, {FilesJson: filesJSON[50:]}, }, - expectedResponse: &gitalypb.ResolveConflictsResponse{}, + expectedCommitAuthor: defaultCommitAuthor, + expectedResponse: &gitalypb.ResolveConflictsResponse{}, expectedContent: map[string]map[string][]byte{ "refs/heads/ours": { "a": []byte("apricot\n" + strings.Repeat("filler\n", 10) + "birne"), @@ -470,15 +478,16 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { TargetBranch: []byte("theirs"), SourceBranch: []byte("ours"), CommitMessage: []byte(conflictResolutionCommitMessage), - User: user, - Timestamp: ×tamppb.Timestamp{}, + User: defaultUser, + Timestamp: defaultTimestamp, }, }, requestsFilesJSON: []*gitalypb.ResolveConflictsRequest_FilesJson{ {FilesJson: filesJSON[:50]}, {FilesJson: filesJSON[50:]}, }, - expectedResponse: &gitalypb.ResolveConflictsResponse{}, + expectedCommitAuthor: defaultCommitAuthor, + expectedResponse: &gitalypb.ResolveConflictsResponse{}, expectedContent: map[string]map[string][]byte{ "refs/heads/ours": { "a": []byte("apricot\n" + strings.Repeat("filler\n", 10) + "birne"), @@ -537,8 +546,8 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { TargetBranch: []byte("theirs"), SourceBranch: []byte("ours"), CommitMessage: []byte(conflictResolutionCommitMessage), - User: user, - Timestamp: ×tamppb.Timestamp{}, + User: defaultUser, + Timestamp: defaultTimestamp, }, }, requestsFilesJSON: []*gitalypb.ResolveConflictsRequest_FilesJson{ @@ -593,15 +602,16 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { TargetBranch: []byte("theirs"), SourceBranch: []byte("ours"), CommitMessage: []byte(conflictResolutionCommitMessage), - User: user, - Timestamp: ×tamppb.Timestamp{}, + User: defaultUser, + Timestamp: defaultTimestamp, }, }, requestsFilesJSON: []*gitalypb.ResolveConflictsRequest_FilesJson{ {FilesJson: filesJSON[:50]}, {FilesJson: filesJSON[50:]}, }, - expectedResponse: &gitalypb.ResolveConflictsResponse{}, + expectedCommitAuthor: defaultCommitAuthor, + expectedResponse: &gitalypb.ResolveConflictsResponse{}, expectedContent: map[string]map[string][]byte{ "refs/heads/ours": { "a": []byte("apricot"), @@ -640,14 +650,15 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { TargetBranch: []byte("theirs"), SourceBranch: []byte("ours"), CommitMessage: []byte(conflictResolutionCommitMessage), - User: user, - Timestamp: ×tamppb.Timestamp{}, + User: defaultUser, + Timestamp: defaultTimestamp, }, }, requestsFilesJSON: []*gitalypb.ResolveConflictsRequest_FilesJson{ {FilesJson: filesJSON}, }, - expectedResponse: &gitalypb.ResolveConflictsResponse{}, + expectedCommitAuthor: defaultCommitAuthor, + expectedResponse: &gitalypb.ResolveConflictsResponse{}, expectedContent: map[string]map[string][]byte{ "refs/heads/ours": { "a": []byte("\n"), @@ -694,14 +705,15 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { TargetBranch: []byte("theirs"), SourceBranch: []byte("ours"), CommitMessage: []byte(conflictResolutionCommitMessage), - User: user, - Timestamp: ×tamppb.Timestamp{}, + User: defaultUser, + Timestamp: defaultTimestamp, }, }, requestsFilesJSON: []*gitalypb.ResolveConflictsRequest_FilesJson{ {FilesJson: filesJSON}, }, - expectedResponse: &gitalypb.ResolveConflictsResponse{}, + expectedCommitAuthor: defaultCommitAuthor, + expectedResponse: &gitalypb.ResolveConflictsResponse{}, expectedContent: map[string]map[string][]byte{ "refs/heads/ours": { "a": []byte("\nA\n"), @@ -748,14 +760,15 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { TargetBranch: []byte("theirs"), SourceBranch: []byte("ours"), CommitMessage: []byte(conflictResolutionCommitMessage), - User: user, - Timestamp: ×tamppb.Timestamp{}, + User: defaultUser, + Timestamp: defaultTimestamp, }, }, requestsFilesJSON: []*gitalypb.ResolveConflictsRequest_FilesJson{ {FilesJson: filesJSON}, }, - expectedResponse: &gitalypb.ResolveConflictsResponse{}, + expectedCommitAuthor: defaultCommitAuthor, + expectedResponse: &gitalypb.ResolveConflictsResponse{}, expectedContent: map[string]map[string][]byte{ "refs/heads/ours": { "a": []byte("A\nB\nX\nD\nE\n"), @@ -802,14 +815,15 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { TargetBranch: []byte("theirs"), SourceBranch: []byte("ours"), CommitMessage: []byte(conflictResolutionCommitMessage), - User: user, - Timestamp: ×tamppb.Timestamp{}, + User: defaultUser, + Timestamp: defaultTimestamp, }, }, requestsFilesJSON: []*gitalypb.ResolveConflictsRequest_FilesJson{ {FilesJson: filesJSON}, }, - expectedResponse: &gitalypb.ResolveConflictsResponse{}, + expectedCommitAuthor: defaultCommitAuthor, + expectedResponse: &gitalypb.ResolveConflictsResponse{}, expectedContent: map[string]map[string][]byte{ "refs/heads/ours": { "a": []byte("A\nB"), @@ -856,8 +870,8 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { TargetBranch: []byte("theirs"), SourceBranch: []byte("ours"), CommitMessage: []byte(conflictResolutionCommitMessage), - User: user, - Timestamp: ×tamppb.Timestamp{}, + User: defaultUser, + Timestamp: defaultTimestamp, }, }, requestsFilesJSON: []*gitalypb.ResolveConflictsRequest_FilesJson{ @@ -898,8 +912,8 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { SourceBranch: []byte("ours"), TargetBranch: []byte("theirs"), CommitMessage: []byte(conflictResolutionCommitMessage), - User: user, - Timestamp: ×tamppb.Timestamp{}, + User: defaultUser, + Timestamp: defaultTimestamp, }, }, requestsFilesJSON: []*gitalypb.ResolveConflictsRequest_FilesJson{ @@ -946,8 +960,8 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { TargetBranch: []byte("theirs"), SourceBranch: []byte("ours"), CommitMessage: []byte(conflictResolutionCommitMessage), - User: user, - Timestamp: ×tamppb.Timestamp{}, + User: defaultUser, + Timestamp: defaultTimestamp, }, }, requestsFilesJSON: []*gitalypb.ResolveConflictsRequest_FilesJson{ @@ -996,8 +1010,8 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { TargetBranch: []byte("theirs"), SourceBranch: []byte("ours"), CommitMessage: []byte(conflictResolutionCommitMessage), - User: user, - Timestamp: ×tamppb.Timestamp{}, + User: defaultUser, + Timestamp: defaultTimestamp, }, }, requestsFilesJSON: []*gitalypb.ResolveConflictsRequest_FilesJson{ @@ -1030,7 +1044,7 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { TargetBranch: []byte("theirs"), SourceBranch: []byte("ours"), CommitMessage: []byte(conflictResolutionCommitMessage), - Timestamp: ×tamppb.Timestamp{}, + Timestamp: defaultTimestamp, }, }, skipCommitCheck: true, @@ -1051,14 +1065,14 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { repo: repo, requestHeader: &gitalypb.ResolveConflictsRequest_Header{ Header: &gitalypb.ResolveConflictsRequestHeader{ - User: user, + User: defaultUser, TargetRepository: repo, OurCommitOid: gittest.DefaultObjectHash.EmptyTreeOID.String(), TheirCommitOid: gittest.DefaultObjectHash.EmptyTreeOID.String(), TargetBranch: []byte("theirs"), SourceBranch: []byte("ours"), CommitMessage: []byte(conflictResolutionCommitMessage), - Timestamp: ×tamppb.Timestamp{}, + Timestamp: defaultTimestamp, }, }, skipCommitCheck: true, @@ -1079,14 +1093,14 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { repo: repo, requestHeader: &gitalypb.ResolveConflictsRequest_Header{ Header: &gitalypb.ResolveConflictsRequestHeader{ - User: user, + User: defaultUser, Repository: repo, OurCommitOid: gittest.DefaultObjectHash.EmptyTreeOID.String(), TheirCommitOid: gittest.DefaultObjectHash.EmptyTreeOID.String(), TargetBranch: []byte("theirs"), SourceBranch: []byte("ours"), CommitMessage: []byte(conflictResolutionCommitMessage), - Timestamp: ×tamppb.Timestamp{}, + Timestamp: defaultTimestamp, }, }, skipCommitCheck: true, @@ -1107,14 +1121,14 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { repo: repo, requestHeader: &gitalypb.ResolveConflictsRequest_Header{ Header: &gitalypb.ResolveConflictsRequestHeader{ - User: user, + User: defaultUser, Repository: repo, TargetRepository: repo, TheirCommitOid: gittest.DefaultObjectHash.EmptyTreeOID.String(), TargetBranch: []byte("theirs"), SourceBranch: []byte("ours"), CommitMessage: []byte(conflictResolutionCommitMessage), - Timestamp: ×tamppb.Timestamp{}, + Timestamp: defaultTimestamp, }, }, skipCommitCheck: true, @@ -1135,14 +1149,14 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { repo: repo, requestHeader: &gitalypb.ResolveConflictsRequest_Header{ Header: &gitalypb.ResolveConflictsRequestHeader{ - User: user, + User: defaultUser, Repository: repo, TargetRepository: repo, OurCommitOid: gittest.DefaultObjectHash.EmptyTreeOID.String(), TargetBranch: []byte("theirs"), SourceBranch: []byte("ours"), CommitMessage: []byte(conflictResolutionCommitMessage), - Timestamp: ×tamppb.Timestamp{}, + Timestamp: defaultTimestamp, }, }, skipCommitCheck: true, @@ -1163,14 +1177,14 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { repo: repo, requestHeader: &gitalypb.ResolveConflictsRequest_Header{ Header: &gitalypb.ResolveConflictsRequestHeader{ - User: user, + User: defaultUser, Repository: repo, TargetRepository: repo, OurCommitOid: gittest.DefaultObjectHash.EmptyTreeOID.String(), TheirCommitOid: gittest.DefaultObjectHash.EmptyTreeOID.String(), TargetBranch: []byte("theirs"), SourceBranch: []byte("ours"), - Timestamp: ×tamppb.Timestamp{}, + Timestamp: defaultTimestamp, }, }, skipCommitCheck: true, @@ -1191,14 +1205,14 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { repo: repo, requestHeader: &gitalypb.ResolveConflictsRequest_Header{ Header: &gitalypb.ResolveConflictsRequestHeader{ - User: user, + User: defaultUser, Repository: repo, TargetRepository: repo, OurCommitOid: gittest.DefaultObjectHash.EmptyTreeOID.String(), TheirCommitOid: gittest.DefaultObjectHash.EmptyTreeOID.String(), TargetBranch: []byte("theirs"), CommitMessage: []byte(conflictResolutionCommitMessage), - Timestamp: ×tamppb.Timestamp{}, + Timestamp: defaultTimestamp, }, }, skipCommitCheck: true, @@ -1219,14 +1233,14 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { repo: repo, requestHeader: &gitalypb.ResolveConflictsRequest_Header{ Header: &gitalypb.ResolveConflictsRequestHeader{ - User: user, + User: defaultUser, Repository: repo, TargetRepository: repo, OurCommitOid: gittest.DefaultObjectHash.EmptyTreeOID.String(), TheirCommitOid: gittest.DefaultObjectHash.EmptyTreeOID.String(), SourceBranch: []byte("ours"), CommitMessage: []byte(conflictResolutionCommitMessage), - Timestamp: ×tamppb.Timestamp{}, + Timestamp: defaultTimestamp, }, }, skipCommitCheck: true, @@ -1290,8 +1304,8 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { TargetBranch: []byte("theirs"), SourceBranch: []byte("ours"), CommitMessage: []byte(conflictResolutionCommitMessage), - User: user, - Timestamp: ×tamppb.Timestamp{}, + User: defaultUser, + Timestamp: defaultTimestamp, }, }, requestsFilesJSON: []*gitalypb.ResolveConflictsRequest_FilesJson{ @@ -1311,6 +1325,95 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { } }, }, + { + "no user timezone specified, use UTC", + func(tb testing.TB, ctx context.Context) setupData { + cfg, client := setupConflictsService(tb, nil) + repo, repoPath := gittest.CreateRepository(tb, ctx, cfg) + + ourCommitID := gittest.WriteCommit(tb, cfg, repoPath, gittest.WithBranch("ours"), + gittest.WithTreeEntries(gittest.TreeEntry{Path: "b", Mode: "100644", Content: "apricot"})) + theirCommitID := gittest.WriteCommit(tb, cfg, repoPath, gittest.WithBranch("theirs"), + gittest.WithTreeEntries(gittest.TreeEntry{Path: "c", Mode: "100644", Content: "acai"})) + + filesJSON, err := json.Marshal([]map[string]interface{}{}) + require.NoError(t, err) + + return setupData{ + cfg: cfg, + client: client, + repoPath: repoPath, + repo: repo, + requestHeader: &gitalypb.ResolveConflictsRequest_Header{ + Header: &gitalypb.ResolveConflictsRequestHeader{ + Repository: repo, + TargetRepository: repo, + OurCommitOid: ourCommitID.String(), + TheirCommitOid: theirCommitID.String(), + TargetBranch: []byte("theirs"), + SourceBranch: []byte("ours"), + CommitMessage: []byte(conflictResolutionCommitMessage), + User: &gitalypb.User{ + Name: []byte("Jane Doe"), + Email: []byte("janedoe@gitlab.com"), + GlId: "user-123", + }, + Timestamp: defaultTimestamp, + }, + }, + requestsFilesJSON: []*gitalypb.ResolveConflictsRequest_FilesJson{ + {FilesJson: filesJSON}, + }, + expectedCommitAuthor: &gitalypb.CommitAuthor{ + Name: []byte("Jane Doe"), + Email: []byte("janedoe@gitlab.com"), + Date: defaultTimestamp, + Timezone: []byte("+0000"), + }, + expectedResponse: &gitalypb.ResolveConflictsResponse{}, + expectedContent: map[string]map[string][]byte{ + "refs/heads/ours": { + "b": []byte("apricot"), + "c": []byte("acai"), + }, + }, + } + }, + }, + { + "invalid user timezone", + func(tb testing.TB, ctx context.Context) setupData { + cfg, client := setupConflictsService(tb, nil) + repo, repoPath := gittest.CreateRepository(tb, ctx, cfg) + + return setupData{ + cfg: cfg, + client: client, + repoPath: repoPath, + repo: repo, + requestHeader: &gitalypb.ResolveConflictsRequest_Header{ + Header: &gitalypb.ResolveConflictsRequestHeader{ + Repository: repo, + TargetRepository: repo, + OurCommitOid: gittest.DefaultObjectHash.EmptyTreeOID.String(), + TheirCommitOid: gittest.DefaultObjectHash.EmptyTreeOID.String(), + TargetBranch: []byte("theirs"), + SourceBranch: []byte("ours"), + CommitMessage: []byte(conflictResolutionCommitMessage), + User: &gitalypb.User{ + Name: []byte("Jane Doe"), + Email: []byte("janedoe@gitlab.com"), + GlId: "user-123", + Timezone: "Invalid/Timezone", + }, + Timestamp: defaultTimestamp, + }, + }, + expectedError: structerr.NewInvalidArgument("unknown time zone Invalid/Timezone"), + skipCommitCheck: true, + } + }, + }, } { tc := tc ctx := ctx @@ -1349,8 +1452,8 @@ func testResolveConflicts(t *testing.T, ctx context.Context) { require.NoError(t, err) require.Contains(t, headCommit.ParentIds, setup.requestHeader.Header.OurCommitOid) require.Contains(t, headCommit.ParentIds, setup.requestHeader.Header.TheirCommitOid) - require.Equal(t, headCommit.Author.Email, user.Email) - require.Equal(t, headCommit.Committer.Email, user.Email) + testhelper.ProtoEqual(t, setup.expectedCommitAuthor, headCommit.Author) + testhelper.ProtoEqual(t, setup.expectedCommitAuthor, headCommit.Committer) require.Equal(t, string(headCommit.Subject), conflictResolutionCommitMessage) } |