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:
authorJohn Cai <jcai@gitlab.com>2019-07-16 23:24:39 +0300
committerJohn Cai <jcai@gitlab.com>2019-07-16 23:24:39 +0300
commit66ff8a274152bea7a3e6221e8b1673760b3ff441 (patch)
treea5164fdff7da4cfa5c471bfad865afba19759c47
parent99b5be6a8d14c7bb5070864b28e4b8832a88ea36 (diff)
parent5a4e3a4c9eff84e0dba0662b53d6d755bddf984f (diff)
Merge branch 'add-list-commits-by-ref-name-rpc' into 'master'
Add ListCommitsByRefName RPC See merge request gitlab-org/gitaly!1365
-rw-r--r--changelogs/unreleased/add-list-commits-by-ref-name-rpc.yml5
-rw-r--r--go.mod2
-rw-r--r--go.sum4
-rw-r--r--internal/service/commit/list_commits_by_ref_name.go48
-rw-r--r--internal/service/commit/list_commits_by_ref_name_test.go222
5 files changed, 278 insertions, 3 deletions
diff --git a/changelogs/unreleased/add-list-commits-by-ref-name-rpc.yml b/changelogs/unreleased/add-list-commits-by-ref-name-rpc.yml
new file mode 100644
index 000000000..8473459be
--- /dev/null
+++ b/changelogs/unreleased/add-list-commits-by-ref-name-rpc.yml
@@ -0,0 +1,5 @@
+---
+title: Add ListCommitsByRefName RPC
+merge_request: 1365
+author:
+type: added
diff --git a/go.mod b/go.mod
index f1e0b072e..512f62805 100644
--- a/go.mod
+++ b/go.mod
@@ -14,7 +14,7 @@ require (
github.com/sirupsen/logrus v1.2.0
github.com/stretchr/testify v1.3.0
github.com/tinylib/msgp v1.1.0 // indirect
- gitlab.com/gitlab-org/gitaly-proto v1.36.0
+ gitlab.com/gitlab-org/gitaly-proto v1.37.0
gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4
diff --git a/go.sum b/go.sum
index 3e59959df..6dfdc7794 100644
--- a/go.sum
+++ b/go.sum
@@ -103,8 +103,8 @@ github.com/uber/jaeger-client-go v2.15.0+incompatible h1:NP3qsSqNxh8VYr956ur1N/1
github.com/uber/jaeger-client-go v2.15.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
github.com/uber/jaeger-lib v1.5.0 h1:OHbgr8l656Ub3Fw5k9SWnBfIEwvoHQ+W2y+Aa9D1Uyo=
github.com/uber/jaeger-lib v1.5.0/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
-gitlab.com/gitlab-org/gitaly-proto v1.36.0 h1:TnWEwCwq/1epAcz1VTAiUMhlKYpnlAV8X1CO1Jwb8hE=
-gitlab.com/gitlab-org/gitaly-proto v1.36.0/go.mod h1:zNjk/86bjwLVJ4NcvInBcXcLdptdRFQ28sYrdFbrFgY=
+gitlab.com/gitlab-org/gitaly-proto v1.37.0 h1:cRQXF3kW+AR1eLIYTWfb+Eqa+Wd0PIcTq4FkaSCWvK4=
+gitlab.com/gitlab-org/gitaly-proto v1.37.0/go.mod h1:zNjk/86bjwLVJ4NcvInBcXcLdptdRFQ28sYrdFbrFgY=
gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c h1:xo48LcGsTCasKcJpQDBCCuZU+aP8uGaboUVvD7Lgm6g=
gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c/go.mod h1:rYhLgfrbEcyfinG+R3EvKu6bZSsmwQqcXzLfHWSfUKM=
go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
diff --git a/internal/service/commit/list_commits_by_ref_name.go b/internal/service/commit/list_commits_by_ref_name.go
new file mode 100644
index 000000000..f8a79fd03
--- /dev/null
+++ b/internal/service/commit/list_commits_by_ref_name.go
@@ -0,0 +1,48 @@
+package commit
+
+import (
+ "gitlab.com/gitlab-org/gitaly-proto/go/gitalypb"
+ "gitlab.com/gitlab-org/gitaly/internal/git/catfile"
+ gitlog "gitlab.com/gitlab-org/gitaly/internal/git/log"
+ "gitlab.com/gitlab-org/gitaly/internal/helper"
+ "gitlab.com/gitlab-org/gitaly/internal/helper/chunk"
+)
+
+func (s *server) ListCommitsByRefName(in *gitalypb.ListCommitsByRefNameRequest, stream gitalypb.CommitService_ListCommitsByRefNameServer) error {
+ ctx := stream.Context()
+
+ c, err := catfile.New(ctx, in.Repository)
+ if err != nil {
+ return helper.ErrInternal(err)
+ }
+
+ sender := chunk.New(&commitsByRefNameSender{stream: stream})
+
+ for _, refName := range in.RefNames {
+ commit, err := gitlog.GetCommitCatfile(c, string(refName))
+ if catfile.IsNotFound(err) {
+ continue
+ }
+ if err != nil {
+ return helper.ErrInternal(err)
+ }
+
+ if err := sender.Send(commit); err != nil {
+ return helper.ErrInternal(err)
+ }
+ }
+
+ return sender.Flush()
+}
+
+type commitsByRefNameSender struct {
+ response *gitalypb.ListCommitsByRefNameResponse
+ stream gitalypb.CommitService_ListCommitsByRefNameServer
+}
+
+func (c *commitsByRefNameSender) Append(it chunk.Item) {
+ c.response.Commits = append(c.response.Commits, it.(*gitalypb.GitCommit))
+}
+
+func (c *commitsByRefNameSender) Send() error { return c.stream.Send(c.response) }
+func (c *commitsByRefNameSender) Reset() { c.response = &gitalypb.ListCommitsByRefNameResponse{} }
diff --git a/internal/service/commit/list_commits_by_ref_name_test.go b/internal/service/commit/list_commits_by_ref_name_test.go
new file mode 100644
index 000000000..b8161bc99
--- /dev/null
+++ b/internal/service/commit/list_commits_by_ref_name_test.go
@@ -0,0 +1,222 @@
+package commit
+
+import (
+ "io"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+ "gitlab.com/gitlab-org/gitaly-proto/go/gitalypb"
+ "gitlab.com/gitlab-org/gitaly/internal/testhelper"
+)
+
+func TestSuccessfulListCommitsByRefNameRequest(t *testing.T) {
+ server, serverSocketPath := startTestServices(t)
+ defer server.Stop()
+
+ client, conn := newCommitServiceClient(t, serverSocketPath)
+ defer conn.Close()
+
+ testRepo, _, cleanupFn := testhelper.NewTestRepo(t)
+ defer cleanupFn()
+
+ testCases := []struct {
+ desc string
+ request *gitalypb.ListCommitsByRefNameRequest
+ expectedIds []string
+ }{
+ {
+ desc: "find one commit",
+ request: &gitalypb.ListCommitsByRefNameRequest{
+ RefNames: [][]byte{[]byte("refs/heads/master")},
+ },
+ expectedIds: []string{"1e292f8fedd741b75372e19097c76d327140c312"},
+ },
+ {
+ desc: "find one commit without refs/heads/ prefix",
+ request: &gitalypb.ListCommitsByRefNameRequest{
+ RefNames: [][]byte{[]byte("master")},
+ },
+ expectedIds: []string{"1e292f8fedd741b75372e19097c76d327140c312"},
+ },
+ {
+ desc: "find HEAD commit",
+ request: &gitalypb.ListCommitsByRefNameRequest{
+ RefNames: [][]byte{[]byte("HEAD")},
+ },
+ expectedIds: []string{"1e292f8fedd741b75372e19097c76d327140c312"},
+ },
+ {
+ desc: "find one commit with UTF8 characters",
+ request: &gitalypb.ListCommitsByRefNameRequest{
+ RefNames: [][]byte{[]byte("refs/heads/ʕ•ᴥ•ʔ")},
+ },
+ expectedIds: []string{"e63f41fe459e62e1228fcef60d7189127aeba95a"},
+ },
+ {
+ desc: "find one commit with non UTF8 characters",
+ request: &gitalypb.ListCommitsByRefNameRequest{
+ RefNames: [][]byte{[]byte("refs/heads/Ääh-test-utf-8")},
+ },
+ expectedIds: []string{"7975be0116940bf2ad4321f79d02a55c5f7779aa"},
+ },
+ {
+ desc: "find multiple commits",
+ request: &gitalypb.ListCommitsByRefNameRequest{
+ RefNames: [][]byte{
+ []byte("refs/heads/master"),
+ []byte("refs/heads/add-pdf-file"),
+ },
+ },
+ expectedIds: []string{
+ "1e292f8fedd741b75372e19097c76d327140c312",
+ "e774ebd33ca5de8e6ef1e633fd887bb52b9d0a7a",
+ },
+ },
+ {
+ desc: "unknown ref names",
+ request: &gitalypb.ListCommitsByRefNameRequest{
+ RefNames: [][]byte{
+ []byte("refs/heads/does-not-exist-1"),
+ []byte("refs/heads/does-not-exist-2"),
+ },
+ },
+ expectedIds: []string{},
+ },
+ {
+ desc: "find partial commits",
+ request: &gitalypb.ListCommitsByRefNameRequest{
+ RefNames: [][]byte{
+ []byte("refs/heads/master"),
+ []byte("refs/heads/does-not-exist-1"),
+ []byte("refs/heads/add-pdf-file"),
+ },
+ },
+ expectedIds: []string{
+ "1e292f8fedd741b75372e19097c76d327140c312",
+ "e774ebd33ca5de8e6ef1e633fd887bb52b9d0a7a",
+ },
+ },
+ {
+ desc: "no query",
+ request: &gitalypb.ListCommitsByRefNameRequest{
+ RefNames: [][]byte{},
+ },
+ expectedIds: []string{},
+ },
+ {
+ desc: "empty query",
+ request: &gitalypb.ListCommitsByRefNameRequest{
+ RefNames: [][]byte{[]byte("")},
+ },
+ expectedIds: []string{},
+ },
+ {
+ desc: "find empty commit",
+ request: &gitalypb.ListCommitsByRefNameRequest{
+ RefNames: [][]byte{[]byte("refs/heads/1942eed5cc108b19c7405106e81fa96125d0be22")},
+ },
+ expectedIds: []string{"1942eed5cc108b19c7405106e81fa96125d0be22"},
+ },
+ {
+ desc: "invalid ref names",
+ request: &gitalypb.ListCommitsByRefNameRequest{
+ RefNames: [][]byte{
+ []byte("refs/does-not-exist-1"),
+ []byte("does-not-exist-2"),
+ },
+ },
+ expectedIds: []string{},
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.desc, func(t *testing.T) {
+ request := testCase.request
+ request.Repository = testRepo
+
+ ctx, cancel := testhelper.Context()
+ defer cancel()
+
+ c, err := client.ListCommitsByRefName(ctx, request)
+ require.NoError(t, err)
+
+ receivedCommits := consumeGetByRefNameResponse(t, c)
+ require.Len(t, receivedCommits, len(testCase.expectedIds))
+
+ for i, receivedCommit := range receivedCommits {
+ require.Equal(t, testCase.expectedIds[i], receivedCommit.Id, "mismatched commit")
+ }
+ })
+ }
+}
+
+func consumeGetByRefNameResponse(t *testing.T, c gitalypb.CommitService_ListCommitsByRefNameClient) []*gitalypb.GitCommit {
+ receivedCommits := []*gitalypb.GitCommit{}
+ for {
+ resp, err := c.Recv()
+ if err == io.EOF {
+ break
+ }
+ require.NoError(t, err)
+
+ receivedCommits = append(receivedCommits, resp.GetCommits()...)
+ }
+
+ return receivedCommits
+}
+
+var repositoryRefNames = map[string]string{
+ "bb5206fee213d983da88c47f9cf4cc6caf9c66dc": "refs/heads/feature_conflict",
+ "0031876facac3f2b2702a0e53a26e89939a42209": "refs/heads/few-commits",
+ "06041ab2037429d243a38abb55957818dd9f948d": "refs/heads/file-mode-change",
+ "48f0be4bd10c1decee6fae52f9ae6d10f77b60f4": "refs/heads/fix",
+ "ce369011c189f62c815f5971d096b26759bab0d1": "refs/heads/flat-path",
+ "d25b6d94034242f3930dfcfeb6d8d9aac3583992": "refs/heads/flat-path-2",
+ "e56497bb5f03a90a51293fc6d516788730953899": "refs/heads/flatten-dirs",
+ "ab2c9622c02288a2bbaaf35d96088cfdff31d9d9": "refs/heads/gitaly-diff-stuff",
+ "0999bb770f8dc92ab5581cc0b474b3e31a96bf5c": "refs/heads/gitaly-non-utf8-commit",
+ "94bb47ca1297b7b3731ff2a36923640991e9236f": "refs/heads/gitaly-rename-test",
+ "cb19058ecc02d01f8e4290b7e79cafd16a8839b6": "refs/heads/gitaly-stuff",
+ "e63f41fe459e62e1228fcef60d7189127aeba95a": "refs/heads/gitaly-test-ref",
+ "c809470461118b7bcab850f6e9a7ca97ac42f8ea": "refs/heads/gitaly-windows-1251",
+ "5937ac0a7beb003549fc5fd26fc247adbce4a52e": "refs/heads/improve/awesome",
+ "7df99c9ad5b8c9bfc5ae4fb7a91cc87adcce02ef": "refs/heads/jv-conflict-1",
+ "bd493d44ae3c4dd84ce89cb75be78c4708cbd548": "refs/heads/jv-conflict-2",
+ "d23bddc916b96c98ff192e198b1adee0f6871085": "refs/heads/many_files",
+ "0ed8c6c6752e8c6ea63e7b92a517bf5ac1209c80": "refs/heads/markdown",
+ "6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9": "refs/tags/v1.0.0",
+ "8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b": "refs/tags/v1.1.0",
+}
+
+func TestSuccessfulListCommitsByRefNameLargeRequest(t *testing.T) {
+ server, serverSocketPath := startTestServices(t)
+ defer server.Stop()
+
+ client, conn := newCommitServiceClient(t, serverSocketPath)
+ defer conn.Close()
+
+ testRepo, _, cleanupFn := testhelper.NewTestRepo(t)
+ defer cleanupFn()
+
+ refNames := [][]byte{}
+ for _, refName := range repositoryRefNames {
+ refNames = append(refNames, []byte(refName))
+ }
+ req := &gitalypb.ListCommitsByRefNameRequest{
+ RefNames: refNames,
+ Repository: testRepo,
+ }
+
+ ctx, cancel := testhelper.Context()
+ defer cancel()
+
+ c, err := client.ListCommitsByRefName(ctx, req)
+ require.NoError(t, err)
+
+ actualCommits := consumeGetByRefNameResponse(t, c)
+
+ for _, actual := range actualCommits {
+ _, ok := repositoryRefNames[actual.Id]
+ require.True(t, ok, "commit ID must be present in the input list: %s", actual.Id)
+ }
+}