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:
authorPatrick Steinhardt <psteinhardt@gitlab.com>2021-07-01 09:24:18 +0300
committerPatrick Steinhardt <psteinhardt@gitlab.com>2021-07-01 09:24:18 +0300
commit9924b3263079fb507525d5c164741bb733ebfcde (patch)
tree708773345790f5a399d9dd640275f2a661b08306
parent152db141420ac08ff6dd322c3fe9b8ccb83c48ab (diff)
parent78c38deaa1c6d43c02c3d5ada735fcfd1296f8db (diff)
Merge branch 'fix/operations_lose_timezone' into 'master'
Fix Web GUI operations timezone See merge request gitlab-org/gitaly!3586
-rw-r--r--internal/git/gittest/user.go6
-rw-r--r--internal/gitaly/service/operations/commit_files.go11
-rw-r--r--internal/gitaly/service/operations/commit_files_test.go11
-rw-r--r--internal/gitaly/service/operations/merge.go20
-rw-r--r--internal/gitaly/service/operations/merge_test.go18
-rw-r--r--internal/gitaly/service/operations/revert.go11
-rw-r--r--internal/gitaly/service/operations/revert_test.go10
-rw-r--r--internal/gitaly/service/operations/squash.go15
-rw-r--r--internal/gitaly/service/operations/squash_test.go17
-rw-r--r--internal/gitaly/service/operations/submodules.go11
-rw-r--r--internal/gitaly/service/operations/submodules_test.go13
-rw-r--r--internal/gitaly/service/operations/utils.go30
-rw-r--r--internal/gitaly/service/operations/utils_test.go44
-rw-r--r--proto/go/gitalypb/shared.pb.go74
-rw-r--r--proto/shared.proto3
-rw-r--r--ruby/proto/gitaly/shared_pb.rb1
16 files changed, 189 insertions, 106 deletions
diff --git a/internal/git/gittest/user.go b/internal/git/gittest/user.go
index 94cfc522d..5d3b54094 100644
--- a/internal/git/gittest/user.go
+++ b/internal/git/gittest/user.go
@@ -7,6 +7,11 @@ import (
const (
// GlID is the ID of the default user.
GlID = "user-123"
+
+ // Timezone is the Timezone of the default user.
+ Timezone = "Asia/Shanghai"
+ // TimezoneOffset is ISO 8601-like format of the default user Timezone.
+ TimezoneOffset = "+0800"
)
var (
@@ -16,5 +21,6 @@ var (
Email: []byte("janedoe@gitlab.com"),
GlId: GlID,
GlUsername: "janedoe",
+ Timezone: Timezone,
}
)
diff --git a/internal/gitaly/service/operations/commit_files.go b/internal/gitaly/service/operations/commit_files.go
index 33011e2f3..9b819c861 100644
--- a/internal/gitaly/service/operations/commit_files.go
+++ b/internal/gitaly/service/operations/commit_files.go
@@ -8,9 +8,7 @@ import (
"fmt"
"io"
"strings"
- "time"
- "github.com/golang/protobuf/ptypes"
"github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus"
"github.com/sirupsen/logrus"
"gitlab.com/gitlab-org/gitaly/v14/internal/git"
@@ -284,12 +282,9 @@ func (s *Server) userCommitFiles(ctx context.Context, header *gitalypb.UserCommi
}
}
- now := time.Now()
- if header.Timestamp != nil {
- now, err = ptypes.Timestamp(header.Timestamp)
- if err != nil {
- return helper.ErrInvalidArgument(err)
- }
+ now, err := dateFromProto(header)
+ if err != nil {
+ return helper.ErrInvalidArgument(err)
}
committer := git2go.NewSignature(string(header.User.Name), string(header.User.Email), now)
diff --git a/internal/gitaly/service/operations/commit_files_test.go b/internal/gitaly/service/operations/commit_files_test.go
index d4838a4d3..93b2a0d49 100644
--- a/internal/gitaly/service/operations/commit_files_test.go
+++ b/internal/gitaly/service/operations/commit_files_test.go
@@ -932,6 +932,9 @@ func TestUserCommitFiles(t *testing.T) {
require.Equal(t, step.branchCreated, resp.BranchUpdate.BranchCreated, "step %d", i+1)
require.Equal(t, step.repoCreated, resp.BranchUpdate.RepoCreated, "step %d", i+1)
gittest.RequireTree(t, cfg, repoPath, branch, step.treeEntries)
+
+ authorDate := gittest.Exec(t, cfg, "-C", repoPath, "log", "--pretty='format:%ai'", "-1")
+ require.Contains(t, string(authorDate), gittest.TimezoneOffset)
}
})
}
@@ -966,7 +969,7 @@ func TestUserCommitFilesStableCommitID(t *testing.T) {
resp, err := stream.CloseAndRecv()
require.NoError(t, err)
- require.Equal(t, resp.BranchUpdate.CommitId, "4f0ca1fbf05e04dbd5f68d14677034e0afee58ff")
+ require.Equal(t, resp.BranchUpdate.CommitId, "23ec4ccd7fcc6ecf39431805bbff1cbcb6c23b9d")
require.True(t, resp.BranchUpdate.BranchCreated)
require.True(t, resp.BranchUpdate.RepoCreated)
gittest.RequireTree(t, cfg, repoPath, "refs/heads/master", []gittest.TreeEntry{
@@ -976,7 +979,7 @@ func TestUserCommitFilesStableCommitID(t *testing.T) {
commit, err := repo.ReadCommit(ctx, "refs/heads/master")
require.NoError(t, err)
require.Equal(t, &gitalypb.GitCommit{
- Id: "4f0ca1fbf05e04dbd5f68d14677034e0afee58ff",
+ Id: "23ec4ccd7fcc6ecf39431805bbff1cbcb6c23b9d",
TreeId: "541550ddcf8a29bcd80b0800a142a7d47890cfd6",
Subject: []byte("commit message"),
Body: []byte("commit message"),
@@ -985,13 +988,13 @@ func TestUserCommitFilesStableCommitID(t *testing.T) {
Name: []byte("Author Name"),
Email: []byte("author.email@example.com"),
Date: &timestamp.Timestamp{Seconds: 12345},
- Timezone: []byte("+0000"),
+ Timezone: []byte(gittest.TimezoneOffset),
},
Committer: &gitalypb.CommitAuthor{
Name: gittest.TestUser.Name,
Email: gittest.TestUser.Email,
Date: &timestamp.Timestamp{Seconds: 12345},
- Timezone: []byte("+0000"),
+ Timezone: []byte(gittest.TimezoneOffset),
},
}, commit)
}
diff --git a/internal/gitaly/service/operations/merge.go b/internal/gitaly/service/operations/merge.go
index ff9c3f42a..7c70360c4 100644
--- a/internal/gitaly/service/operations/merge.go
+++ b/internal/gitaly/service/operations/merge.go
@@ -5,9 +5,7 @@ import (
"errors"
"fmt"
"strings"
- "time"
- "github.com/golang/protobuf/ptypes"
"github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus"
"github.com/sirupsen/logrus"
"gitlab.com/gitlab-org/gitaly/v14/internal/git"
@@ -62,12 +60,9 @@ func (s *Server) UserMergeBranch(stream gitalypb.OperationService_UserMergeBranc
return err
}
- authorDate := time.Now()
- if firstRequest.Timestamp != nil {
- authorDate, err = ptypes.Timestamp(firstRequest.Timestamp)
- if err != nil {
- return helper.ErrInvalidArgument(err)
- }
+ authorDate, err := dateFromProto(firstRequest)
+ if err != nil {
+ return helper.ErrInvalidArgument(err)
}
merge, err := git2go.MergeCommand{
@@ -260,12 +255,9 @@ func (s *Server) UserMergeToRef(ctx context.Context, request *gitalypb.UserMerge
return nil, helper.ErrInvalidArgument(errors.New("Invalid merge source"))
}
- authorDate := time.Now()
- if request.Timestamp != nil {
- authorDate, err = ptypes.Timestamp(request.Timestamp)
- if err != nil {
- return nil, helper.ErrInvalidArgument(err)
- }
+ authorDate, err := dateFromProto(request)
+ if err != nil {
+ return nil, helper.ErrInvalidArgument(err)
}
// Resolve the current state of the target reference. We do not care whether it
diff --git a/internal/gitaly/service/operations/merge_test.go b/internal/gitaly/service/operations/merge_test.go
index d3abca08a..65253b68c 100644
--- a/internal/gitaly/service/operations/merge_test.go
+++ b/internal/gitaly/service/operations/merge_test.go
@@ -96,6 +96,7 @@ func TestSuccessfulMerge(t *testing.T) {
author := commit.Author
require.Equal(t, gittest.TestUser.Name, author.Name)
require.Equal(t, gittest.TestUser.Email, author.Email)
+ require.Equal(t, gittest.TimezoneOffset, string(author.Timezone))
expectedGlID := "GL_ID=" + gittest.TestUser.GlId
for i, h := range hooks {
@@ -134,7 +135,7 @@ func TestSuccessfulMerge_stableMergeIDs(t *testing.T) {
}
// Because the timestamp is
- expectedMergeID := "cd66941816adc76cc31fc6620d7b36a3dcb045e5"
+ expectedMergeID := "f0165798887392f9148b55d54a832b005f93a38c"
require.NoError(t, mergeBidi.Send(firstRequest), "send first request")
response, err := mergeBidi.Recv()
@@ -144,7 +145,7 @@ func TestSuccessfulMerge_stableMergeIDs(t *testing.T) {
require.NoError(t, mergeBidi.Send(&gitalypb.UserMergeBranchRequest{Apply: true}), "apply merge")
response, err = mergeBidi.Recv()
require.NoError(t, err, "receive second response")
- require.Equal(t, response.BranchUpdate.CommitId, expectedMergeID)
+ require.Equal(t, expectedMergeID, response.BranchUpdate.CommitId)
testhelper.ReceiveEOFWithTimeout(t, func() error {
_, err = mergeBidi.Recv()
@@ -168,14 +169,14 @@ func TestSuccessfulMerge_stableMergeIDs(t *testing.T) {
Email: gittest.TestUser.Email,
// Nanoseconds get ignored because commit timestamps aren't that granular.
Date: &timestamp.Timestamp{Seconds: 12},
- Timezone: []byte("+0000"),
+ Timezone: []byte(gittest.TimezoneOffset),
},
Committer: &gitalypb.CommitAuthor{
Name: gittest.TestUser.Name,
Email: gittest.TestUser.Email,
// Nanoseconds get ignored because commit timestamps aren't that granular.
Date: &timestamp.Timestamp{Seconds: 12},
- Timezone: []byte("+0000"),
+ Timezone: []byte(gittest.TimezoneOffset),
},
})
}
@@ -682,6 +683,7 @@ func TestSuccessfulUserMergeToRefRequest(t *testing.T) {
author := commit.Author
require.Equal(t, gittest.TestUser.Name, author.Name)
require.Equal(t, gittest.TestUser.Email, author.Email)
+ require.Equal(t, gittest.TimezoneOffset, string(author.Timezone))
require.Equal(t, resp.CommitId, commit.Id)
@@ -850,7 +852,7 @@ func TestUserMergeToRef_stableMergeID(t *testing.T) {
Timestamp: &timestamp.Timestamp{Seconds: 12, Nanos: 34},
})
require.NoError(t, err)
- require.Equal(t, "a04514f4e6b4e272989b39cca1ebdbb670abdfd6", response.CommitId)
+ require.Equal(t, "c7b65194ce2da804557582408ab94713983d0b70", response.CommitId)
commit, err := repo.ReadCommit(ctx, git.Revision("refs/merge-requests/x/written"))
require.NoError(t, err, "look up git commit after call has finished")
@@ -858,7 +860,7 @@ func TestUserMergeToRef_stableMergeID(t *testing.T) {
Subject: []byte("Merge message"),
Body: []byte("Merge message"),
BodySize: 13,
- Id: "a04514f4e6b4e272989b39cca1ebdbb670abdfd6",
+ Id: "c7b65194ce2da804557582408ab94713983d0b70",
ParentIds: []string{
"281d3a76f31c812dbf48abce82ccf6860adedd81",
"1450cd639e0bc6721eb02800169e464f212cde06",
@@ -869,14 +871,14 @@ func TestUserMergeToRef_stableMergeID(t *testing.T) {
Email: gittest.TestUser.Email,
// Nanoseconds get ignored because commit timestamps aren't that granular.
Date: &timestamp.Timestamp{Seconds: 12},
- Timezone: []byte("+0000"),
+ Timezone: []byte(gittest.TimezoneOffset),
},
Committer: &gitalypb.CommitAuthor{
Name: gittest.TestUser.Name,
Email: gittest.TestUser.Email,
// Nanoseconds get ignored because commit timestamps aren't that granular.
Date: &timestamp.Timestamp{Seconds: 12},
- Timezone: []byte("+0000"),
+ Timezone: []byte(gittest.TimezoneOffset),
},
}, commit)
}
diff --git a/internal/gitaly/service/operations/revert.go b/internal/gitaly/service/operations/revert.go
index 715e7b0c1..7f84266a9 100644
--- a/internal/gitaly/service/operations/revert.go
+++ b/internal/gitaly/service/operations/revert.go
@@ -4,9 +4,7 @@ import (
"context"
"errors"
"fmt"
- "time"
- "github.com/golang/protobuf/ptypes"
"gitlab.com/gitlab-org/gitaly/v14/internal/git"
"gitlab.com/gitlab-org/gitaly/v14/internal/git/remoterepo"
"gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref"
@@ -41,12 +39,9 @@ func (s *Server) UserRevert(ctx context.Context, req *gitalypb.UserRevertRequest
mainline = 1
}
- authorDate := time.Now()
- if req.Timestamp != nil {
- authorDate, err = ptypes.Timestamp(req.Timestamp)
- if err != nil {
- return nil, helper.ErrInvalidArgument(err)
- }
+ authorDate, err := dateFromProto(req)
+ if err != nil {
+ return nil, helper.ErrInvalidArgument(err)
}
newrev, err := git2go.RevertCommand{
diff --git a/internal/gitaly/service/operations/revert_test.go b/internal/gitaly/service/operations/revert_test.go
index 69d95818e..4eb491b12 100644
--- a/internal/gitaly/service/operations/revert_test.go
+++ b/internal/gitaly/service/operations/revert_test.go
@@ -164,6 +164,8 @@ func TestServer_UserRevert_successful(t *testing.T) {
} else {
require.Equal(t, testCase.request.Message, headCommit.Subject)
require.Equal(t, masterHeadCommit.Id, headCommit.ParentIds[0])
+ require.Equal(t, gittest.TimezoneOffset, string(headCommit.Committer.Timezone))
+ require.Equal(t, gittest.TimezoneOffset, string(headCommit.Author.Timezone))
}
})
}
@@ -191,7 +193,7 @@ func TestServer_UserRevert_stableID(t *testing.T) {
require.NoError(t, err)
require.Equal(t, &gitalypb.OperationBranchUpdate{
- CommitId: "9ebfd44039a9e36d88dcdfe11550399ec6a212f7",
+ CommitId: "9c15289b0a129c562dddf7b364eb979d41173b41",
}, response.BranchUpdate)
require.Empty(t, response.CreateTreeError)
require.Empty(t, response.CreateTreeErrorCode)
@@ -200,7 +202,7 @@ func TestServer_UserRevert_stableID(t *testing.T) {
require.NoError(t, err)
require.Equal(t, &gitalypb.GitCommit{
- Id: "9ebfd44039a9e36d88dcdfe11550399ec6a212f7",
+ Id: "9c15289b0a129c562dddf7b364eb979d41173b41",
ParentIds: []string{
"1e292f8fedd741b75372e19097c76d327140c312",
},
@@ -212,13 +214,13 @@ func TestServer_UserRevert_stableID(t *testing.T) {
Name: []byte("Jane Doe"),
Email: []byte("janedoe@gitlab.com"),
Date: &timestamp.Timestamp{Seconds: 12345},
- Timezone: []byte("+0000"),
+ Timezone: []byte(gittest.TimezoneOffset),
},
Committer: &gitalypb.CommitAuthor{
Name: []byte("Jane Doe"),
Email: []byte("janedoe@gitlab.com"),
Date: &timestamp.Timestamp{Seconds: 12345},
- Timezone: []byte("+0000"),
+ Timezone: []byte(gittest.TimezoneOffset),
},
}, revertedCommit)
}
diff --git a/internal/gitaly/service/operations/squash.go b/internal/gitaly/service/operations/squash.go
index 53e3cb117..824aa6515 100644
--- a/internal/gitaly/service/operations/squash.go
+++ b/internal/gitaly/service/operations/squash.go
@@ -11,9 +11,7 @@ import (
"os"
"path/filepath"
"strings"
- "time"
- "github.com/golang/protobuf/ptypes"
"github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus"
"gitlab.com/gitlab-org/gitaly/v14/internal/command"
"gitlab.com/gitlab-org/gitaly/v14/internal/git"
@@ -383,21 +381,18 @@ func (s *Server) applyDiff(ctx context.Context, repo *gitalypb.Repository, req *
return "", fmt.Errorf("wait for 'git apply' for range %q: %w", diffRange, gitError{ErrMsg: applyStderr.String(), Err: err})
}
- commitDate := time.Now()
- if req.Timestamp != nil {
- commitDate, err = ptypes.Timestamp(req.Timestamp)
- if err != nil {
- return "", helper.ErrInvalidArgument(err)
- }
+ commitDate, err := dateFromProto(req)
+ if err != nil {
+ return "", helper.ErrInvalidArgument(err)
}
commitEnv := append(env,
"GIT_COMMITTER_NAME="+string(req.GetUser().Name),
"GIT_COMMITTER_EMAIL="+string(req.GetUser().Email),
- fmt.Sprintf("GIT_COMMITTER_DATE=%d +0000", commitDate.Unix()),
+ fmt.Sprintf("GIT_COMMITTER_DATE=%d %s", commitDate.Unix(), commitDate.Format("-0700")),
"GIT_AUTHOR_NAME="+string(req.GetAuthor().Name),
"GIT_AUTHOR_EMAIL="+string(req.GetAuthor().Email),
- fmt.Sprintf("GIT_AUTHOR_DATE=%d +0000", commitDate.Unix()),
+ fmt.Sprintf("GIT_AUTHOR_DATE=%d %s", commitDate.Unix(), commitDate.Format("-0700")),
)
var commitStderr bytes.Buffer
diff --git a/internal/gitaly/service/operations/squash_test.go b/internal/gitaly/service/operations/squash_test.go
index e300fad33..af94f8beb 100644
--- a/internal/gitaly/service/operations/squash_test.go
+++ b/internal/gitaly/service/operations/squash_test.go
@@ -24,8 +24,9 @@ import (
var (
author = &gitalypb.User{
- Name: []byte("John Doe"),
- Email: []byte("johndoe@gitlab.com"),
+ Name: []byte("John Doe"),
+ Email: []byte("johndoe@gitlab.com"),
+ Timezone: gittest.Timezone,
}
branchName = "not-merged-branch"
startSha = "b83d6e391c22777fca1ed3012fce84f633d7fed0"
@@ -73,6 +74,8 @@ func testSuccessfulUserSquashRequest(t *testing.T, ctx context.Context, start, e
require.Equal(t, author.Email, commit.Author.Email)
require.Equal(t, gittest.TestUser.Name, commit.Committer.Name)
require.Equal(t, gittest.TestUser.Email, commit.Committer.Email)
+ require.Equal(t, gittest.TimezoneOffset, string(commit.Committer.Timezone))
+ require.Equal(t, gittest.TimezoneOffset, string(commit.Author.Timezone))
require.Equal(t, commitMessage, commit.Subject)
treeData := gittest.Exec(t, cfg, "-C", repoPath, "ls-tree", "--name-only", response.SquashSha)
@@ -104,7 +107,7 @@ func TestUserSquash_stableID(t *testing.T) {
commit, err := repo.ReadCommit(ctx, git.Revision(response.SquashSha))
require.NoError(t, err)
require.Equal(t, &gitalypb.GitCommit{
- Id: "2773b7aee7d81ea96d2f48aa080cae08eaae26d5",
+ Id: "c653dc8f98dba7f7a42c2e3c4b8d850d195e60b6",
TreeId: "324242f415a3cdbfc088103b496379fd91965854",
ParentIds: []string{
"b83d6e391c22777fca1ed3012fce84f633d7fed0",
@@ -116,13 +119,13 @@ func TestUserSquash_stableID(t *testing.T) {
Name: author.Name,
Email: author.Email,
Date: &timestamp.Timestamp{Seconds: 1234512345},
- Timezone: []byte("+0000"),
+ Timezone: []byte(gittest.TimezoneOffset),
},
Committer: &gitalypb.CommitAuthor{
Name: gittest.TestUser.Name,
Email: gittest.TestUser.Email,
Date: &timestamp.Timestamp{Seconds: 1234512345},
- Timezone: []byte("+0000"),
+ Timezone: []byte(gittest.TimezoneOffset),
},
}, commit)
}
@@ -169,6 +172,8 @@ func TestSuccessfulUserSquashRequestWith3wayMerge(t *testing.T) {
require.Equal(t, author.Name, commit.Author.Name)
require.Equal(t, author.Email, commit.Author.Email)
require.Equal(t, gittest.TestUser.Name, commit.Committer.Name)
+ require.Equal(t, gittest.TimezoneOffset, string(commit.Committer.Timezone))
+ require.Equal(t, gittest.TimezoneOffset, string(commit.Author.Timezone))
require.Equal(t, gittest.TestUser.Email, commit.Committer.Email)
require.Equal(t, commitMessage, commit.Subject)
@@ -266,6 +271,8 @@ func TestSquashRequestWithRenamedFiles(t *testing.T) {
require.Equal(t, author.Email, commit.Author.Email)
require.Equal(t, gittest.TestUser.Name, commit.Committer.Name)
require.Equal(t, gittest.TestUser.Email, commit.Committer.Email)
+ require.Equal(t, gittest.TimezoneOffset, string(commit.Committer.Timezone))
+ require.Equal(t, gittest.TimezoneOffset, string(commit.Author.Timezone))
require.Equal(t, commitMessage, commit.Subject)
}
diff --git a/internal/gitaly/service/operations/submodules.go b/internal/gitaly/service/operations/submodules.go
index 2d7117450..c595f7c44 100644
--- a/internal/gitaly/service/operations/submodules.go
+++ b/internal/gitaly/service/operations/submodules.go
@@ -6,9 +6,7 @@ import (
"fmt"
"regexp"
"strings"
- "time"
- "github.com/golang/protobuf/ptypes"
"github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus"
"gitlab.com/gitlab-org/gitaly/v14/internal/git"
"gitlab.com/gitlab-org/gitaly/v14/internal/git/updateref"
@@ -88,12 +86,9 @@ func (s *Server) userUpdateSubmodule(ctx context.Context, req *gitalypb.UserUpda
return nil, fmt.Errorf("%s: locate repo: %w", userUpdateSubmoduleName, err)
}
- authorDate := time.Now()
- if req.Timestamp != nil {
- authorDate, err = ptypes.Timestamp(req.Timestamp)
- if err != nil {
- return nil, helper.ErrInvalidArgument(err)
- }
+ authorDate, err := dateFromProto(req)
+ if err != nil {
+ return nil, helper.ErrInvalidArgument(err)
}
result, err := git2go.SubmoduleCommand{
diff --git a/internal/gitaly/service/operations/submodules_test.go b/internal/gitaly/service/operations/submodules_test.go
index d993b041e..49c2fe20e 100644
--- a/internal/gitaly/service/operations/submodules_test.go
+++ b/internal/gitaly/service/operations/submodules_test.go
@@ -83,9 +83,10 @@ func TestSuccessfulUserUpdateSubmoduleRequest(t *testing.T) {
commit, err := repo.ReadCommit(ctx, git.Revision(response.BranchUpdate.CommitId))
require.NoError(t, err)
- require.Equal(t, commit.Author.Email, gittest.TestUser.Email)
- require.Equal(t, commit.Committer.Email, gittest.TestUser.Email)
- require.Equal(t, commit.Subject, commitMessage)
+ require.Equal(t, gittest.TestUser.Email, commit.Author.Email)
+ require.Equal(t, gittest.TimezoneOffset, string(commit.Author.Timezone))
+ require.Equal(t, gittest.TestUser.Email, commit.Committer.Email)
+ require.Equal(t, commitMessage, commit.Subject)
entry := gittest.Exec(t, cfg, "-C", repoPath, "ls-tree", "-z", fmt.Sprintf("%s^{tree}:", response.BranchUpdate.CommitId), testCase.submodule)
parser := lstree.NewParser(bytes.NewReader(entry))
@@ -120,7 +121,7 @@ func TestUserUpdateSubmoduleStableID(t *testing.T) {
commit, err := repo.ReadCommit(ctx, git.Revision(response.BranchUpdate.CommitId))
require.NoError(t, err)
require.Equal(t, &gitalypb.GitCommit{
- Id: "e7752dfc2105bc830f8fa59b19dd4f3e49c8c44e",
+ Id: "928a79b1c5bbe64759f540aad8b339d281719118",
ParentIds: []string{
"1e292f8fedd741b75372e19097c76d327140c312",
},
@@ -132,13 +133,13 @@ func TestUserUpdateSubmoduleStableID(t *testing.T) {
Name: gittest.TestUser.Name,
Email: gittest.TestUser.Email,
Date: &timestamp.Timestamp{Seconds: 12345},
- Timezone: []byte("+0000"),
+ Timezone: []byte(gittest.TimezoneOffset),
},
Committer: &gitalypb.CommitAuthor{
Name: gittest.TestUser.Name,
Email: gittest.TestUser.Email,
Date: &timestamp.Timestamp{Seconds: 12345},
- Timezone: []byte("+0000"),
+ Timezone: []byte(gittest.TimezoneOffset),
},
}, commit)
}
diff --git a/internal/gitaly/service/operations/utils.go b/internal/gitaly/service/operations/utils.go
index 3ec79cb05..63d95ddc7 100644
--- a/internal/gitaly/service/operations/utils.go
+++ b/internal/gitaly/service/operations/utils.go
@@ -2,8 +2,11 @@ package operations
import (
"fmt"
+ "time"
+ "github.com/golang/protobuf/ptypes"
"gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"
+ "google.golang.org/protobuf/types/known/timestamppb"
)
type cherryPickOrRevertRequest interface {
@@ -32,3 +35,30 @@ func validateCherryPickOrRevertRequest(req cherryPickOrRevertRequest) error {
return nil
}
+
+type userTimestampProto interface {
+ GetUser() *gitalypb.User
+ GetTimestamp() *timestamppb.Timestamp
+}
+
+func dateFromProto(p userTimestampProto) (time.Time, error) {
+ date := time.Now()
+
+ if timestamp := p.GetTimestamp(); timestamp != nil {
+ var err error
+ date, err = ptypes.Timestamp(timestamp)
+ if err != nil {
+ return time.Time{}, err
+ }
+ }
+
+ if user := p.GetUser(); user != nil {
+ location, err := time.LoadLocation(user.GetTimezone())
+ if err != nil {
+ return time.Time{}, err
+ }
+ date = date.In(location)
+ }
+
+ return date, nil
+}
diff --git a/internal/gitaly/service/operations/utils_test.go b/internal/gitaly/service/operations/utils_test.go
new file mode 100644
index 000000000..2745ccabf
--- /dev/null
+++ b/internal/gitaly/service/operations/utils_test.go
@@ -0,0 +1,44 @@
+package operations
+
+import (
+ "errors"
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/assert"
+ "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"
+ "google.golang.org/protobuf/types/known/timestamppb"
+)
+
+func TestDateFromProto(t *testing.T) {
+ locUtc, _ := time.LoadLocation("UTC")
+ locShanghai, _ := time.LoadLocation("Asia/Shanghai")
+ staticNow := time.Now()
+
+ testCases := []struct {
+ timezone string
+ want *time.Location
+ err error
+ }{
+ {"UTC", locUtc, nil},
+ {"Asia/Shanghai", locShanghai, nil},
+ {"Illegal/Format", locUtc, errors.New("unknown time zone Illegal/Format")},
+ {"", locUtc, nil},
+ }
+ for _, testCase := range testCases {
+ t.Run(testCase.timezone, func(t *testing.T) {
+ req := &gitalypb.UserSquashRequest{
+ User: &gitalypb.User{Timezone: testCase.timezone},
+ Timestamp: timestamppb.New(staticNow),
+ }
+ got, err := dateFromProto(req)
+
+ if testCase.err != nil {
+ assert.Equal(t, testCase.err.Error(), err.Error())
+ } else {
+ assert.Equal(t, staticNow.UnixNano(), got.UnixNano())
+ }
+ assert.Equal(t, testCase.want, got.Location())
+ })
+ }
+}
diff --git a/proto/go/gitalypb/shared.pb.go b/proto/go/gitalypb/shared.pb.go
index e1d040014..192d33976 100644
--- a/proto/go/gitalypb/shared.pb.go
+++ b/proto/go/gitalypb/shared.pb.go
@@ -694,6 +694,9 @@ type User struct {
Name []byte `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
Email []byte `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"`
GlUsername string `protobuf:"bytes,4,opt,name=gl_username,json=glUsername,proto3" json:"gl_username,omitempty"`
+ // Timezone is the timezone as configured by the user in the web interface. This
+ // timezone may be used when new commits are created via RPC calls.
+ Timezone string `protobuf:"bytes,5,opt,name=timezone,proto3" json:"timezone,omitempty"`
}
func (x *User) Reset() {
@@ -756,6 +759,13 @@ func (x *User) GetGlUsername() string {
return ""
}
+func (x *User) GetTimezone() string {
+ if x != nil {
+ return x.Timezone
+ }
+ return ""
+}
+
type ObjectPool struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -1004,37 +1014,39 @@ var file_shared_proto_rawDesc = []byte{
0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x67, 0x69, 0x74, 0x61,
0x6c, 0x79, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x54, 0x79, 0x70, 0x65,
0x52, 0x0d, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22,
- 0x66, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x13, 0x0a, 0x05, 0x67, 0x6c, 0x5f, 0x69, 0x64,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x6c, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04,
- 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
- 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52,
- 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x67, 0x6c, 0x5f, 0x75, 0x73, 0x65,
- 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x67, 0x6c, 0x55,
- 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x46, 0x0a, 0x0a, 0x4f, 0x62, 0x6a, 0x65, 0x63,
- 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74,
- 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61,
- 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x90,
- 0xc6, 0x2c, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22,
- 0x4a, 0x0a, 0x13, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72,
- 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74,
- 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65,
- 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02,
- 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x3c, 0x0a, 0x0d, 0x47,
- 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2b, 0x0a, 0x11,
- 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x73, 0x70, 0x65, 0x63,
- 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c,
- 0x50, 0x61, 0x74, 0x68, 0x73, 0x70, 0x65, 0x63, 0x73, 0x2a, 0x42, 0x0a, 0x0a, 0x4f, 0x62, 0x6a,
- 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f,
- 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x10, 0x01,
- 0x12, 0x08, 0x0a, 0x04, 0x42, 0x4c, 0x4f, 0x42, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x54, 0x52,
- 0x45, 0x45, 0x10, 0x03, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x41, 0x47, 0x10, 0x04, 0x2a, 0x2c, 0x0a,
- 0x0d, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08,
- 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x50, 0x47, 0x50, 0x10,
- 0x01, 0x12, 0x08, 0x0a, 0x04, 0x58, 0x35, 0x30, 0x39, 0x10, 0x02, 0x42, 0x34, 0x5a, 0x32, 0x67,
- 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62,
- 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x34, 0x2f,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70,
- 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x82, 0x01, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x13, 0x0a, 0x05, 0x67, 0x6c, 0x5f, 0x69,
+ 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x6c, 0x49, 0x64, 0x12, 0x12, 0x0a,
+ 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6e, 0x61, 0x6d,
+ 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c,
+ 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x67, 0x6c, 0x5f, 0x75, 0x73,
+ 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x67, 0x6c,
+ 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65,
+ 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65,
+ 0x7a, 0x6f, 0x6e, 0x65, 0x22, 0x46, 0x0a, 0x0a, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x6f,
+ 0x6f, 0x6c, 0x12, 0x38, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e,
+ 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x04, 0x90, 0xc6, 0x2c, 0x01,
+ 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x4a, 0x0a, 0x13,
+ 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65,
+ 0x74, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65,
+ 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b,
+ 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x05, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x3c, 0x0a, 0x0d, 0x47, 0x6c, 0x6f, 0x62,
+ 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x6c, 0x69, 0x74,
+ 0x65, 0x72, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x73, 0x70, 0x65, 0x63, 0x73, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x50, 0x61, 0x74,
+ 0x68, 0x73, 0x70, 0x65, 0x63, 0x73, 0x2a, 0x42, 0x0a, 0x0a, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74,
+ 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10,
+ 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x10, 0x01, 0x12, 0x08, 0x0a,
+ 0x04, 0x42, 0x4c, 0x4f, 0x42, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x54, 0x52, 0x45, 0x45, 0x10,
+ 0x03, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x41, 0x47, 0x10, 0x04, 0x2a, 0x2c, 0x0a, 0x0d, 0x53, 0x69,
+ 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x4e,
+ 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x50, 0x47, 0x50, 0x10, 0x01, 0x12, 0x08,
+ 0x0a, 0x04, 0x58, 0x35, 0x30, 0x39, 0x10, 0x02, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c,
+ 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72,
+ 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, 0x76, 0x31, 0x34, 0x2f, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
diff --git a/proto/shared.proto b/proto/shared.proto
index 4d357a3fe..dd69882fc 100644
--- a/proto/shared.proto
+++ b/proto/shared.proto
@@ -117,6 +117,9 @@ message User {
bytes name = 2;
bytes email = 3;
string gl_username = 4;
+ // Timezone is the timezone as configured by the user in the web interface. This
+ // timezone may be used when new commits are created via RPC calls.
+ string timezone = 5;
}
message ObjectPool {
diff --git a/ruby/proto/gitaly/shared_pb.rb b/ruby/proto/gitaly/shared_pb.rb
index d20479f96..0a9853223 100644
--- a/ruby/proto/gitaly/shared_pb.rb
+++ b/ruby/proto/gitaly/shared_pb.rb
@@ -58,6 +58,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
optional :name, :bytes, 2
optional :email, :bytes, 3
optional :gl_username, :string, 4
+ optional :timezone, :string, 5
end
add_message "gitaly.ObjectPool" do
optional :repository, :message, 1, "gitaly.Repository"