From 47e61c3a178511843f13d1188e82cf44b75a551d Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Tue, 26 Jul 2022 11:26:04 +0200 Subject: git: Introduce feature flag for hiding refs in git-upload-pack(1) We have observed an unexpected CPU spike as well as an increase in write operations after 4a789524c (git: Don't advertise internal references via git-upload-pack(1), 2022-07-19) has been deployed, which causes us to stop advertising some internal references to clients which fetch from a repository. It's unexpected that this change increases such a spike, and thus we're being careful for now and introduce a feature flag so that we can ease into the rollout of this change while being able to roll it back with ease. --- internal/git/command_description.go | 4 +- internal/git/command_factory.go | 6 + internal/git/hooks_options_test.go | 4 + internal/gitaly/service/repository/archive_test.go | 9 +- internal/gitaly/service/smarthttp/inforefs_test.go | 123 +++++++++++++++------ .../gitaly/service/smarthttp/upload_pack_test.go | 37 ++++--- internal/gitaly/service/ssh/upload_pack_test.go | 32 ++++-- .../featureflag/ff_upload_pack_hide_refs.go | 9 ++ 8 files changed, 165 insertions(+), 59 deletions(-) create mode 100644 internal/metadata/featureflag/ff_upload_pack_hide_refs.go diff --git a/internal/git/command_description.go b/internal/git/command_description.go index a04746913..b8dd20499 100644 --- a/internal/git/command_description.go +++ b/internal/git/command_description.go @@ -298,12 +298,12 @@ var commandDescriptions = map[string]commandDescription{ }, "upload-pack": { flags: scNoRefUpdates, - opts: append(append([]GlobalOption{ + opts: append([]GlobalOption{ ConfigPair{Key: "uploadpack.allowFilter", Value: "true"}, // Enables the capability to request individual SHA1's from the // remote repo. ConfigPair{Key: "uploadpack.allowAnySHA1InWant", Value: "true"}, - }, hiddenUploadPackRefPrefixes()...), packConfiguration()...), + }, packConfiguration()...), }, "version": { flags: scNoRefUpdates, diff --git a/internal/git/command_factory.go b/internal/git/command_factory.go index 210288dd4..23506f192 100644 --- a/internal/git/command_factory.go +++ b/internal/git/command_factory.go @@ -16,6 +16,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/storage" "gitlab.com/gitlab-org/gitaly/v15/internal/log" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" ) // CommandFactory is designed to create and run git commands in a protected and fully managed manner. @@ -451,6 +452,11 @@ func (cf *ExecCommandFactory) combineArgs(ctx context.Context, gitConfig []confi } combinedGlobals = append(combinedGlobals, commandDescription.opts...) + + if sc.Subcommand() == "upload-pack" && featureflag.UploadPackHideRefs.IsEnabled(ctx) { + combinedGlobals = append(combinedGlobals, hiddenUploadPackRefPrefixes()...) + } + combinedGlobals = append(combinedGlobals, cc.globals...) for _, configPair := range gitConfig { combinedGlobals = append(combinedGlobals, ConfigPair{ diff --git a/internal/git/hooks_options_test.go b/internal/git/hooks_options_test.go index 24ebed76b..384c3c5ed 100644 --- a/internal/git/hooks_options_test.go +++ b/internal/git/hooks_options_test.go @@ -11,6 +11,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/git" "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" "gitlab.com/gitlab-org/gitaly/v15/internal/metadata" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" grpcmetadata "google.golang.org/grpc/metadata" @@ -74,6 +75,9 @@ func TestWithPackObjectsHookEnv(t *testing.T) { ctx = grpcmetadata.AppendToOutgoingContext(ctx, "user_id", userID, "username", username) ctx = metadata.OutgoingToIncoming(ctx) + // We don't care about this feature flag as it doesn't impact behaviour of the system under + // test. + ctx = featureflag.IncomingCtxWithFeatureFlag(ctx, featureflag.UploadPackHideRefs, true) cmd, err := gittest.NewCommandFactory(t, cfg, git.WithSkipHooks()).New(ctx, repo, subCmd, opt) require.NoError(t, err) diff --git a/internal/gitaly/service/repository/archive_test.go b/internal/gitaly/service/repository/archive_test.go index 5f18f8679..e897af1cf 100644 --- a/internal/gitaly/service/repository/archive_test.go +++ b/internal/gitaly/service/repository/archive_test.go @@ -5,6 +5,7 @@ package repository import ( "archive/zip" "bytes" + "context" "fmt" "io" "os" @@ -19,6 +20,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" "gitlab.com/gitlab-org/gitaly/v15/internal/gitlab" "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver" @@ -165,10 +167,13 @@ func TestGetArchive_success(t *testing.T) { } } -func TestGetArchive_includeLfsBlobs(t *testing.T) { +func TestGetArchiveIncludeLfsBlobs(t *testing.T) { t.Parallel() + testhelper.NewFeatureSets(featureflag.UploadPackHideRefs).Run(t, testGetArchiveIncludeLfsBlobs) +} - ctx := testhelper.Context(t) +func testGetArchiveIncludeLfsBlobs(t *testing.T, ctx context.Context) { + t.Parallel() defaultOptions := gitlab.TestServerOptions{ SecretToken: secretToken, diff --git a/internal/gitaly/service/smarthttp/inforefs_test.go b/internal/gitaly/service/smarthttp/inforefs_test.go index 9b371bf7f..f722cc14b 100644 --- a/internal/gitaly/service/smarthttp/inforefs_test.go +++ b/internal/gitaly/service/smarthttp/inforefs_test.go @@ -37,10 +37,14 @@ import ( func TestInfoRefsUploadPack_successful(t *testing.T) { t.Parallel() + testhelper.NewFeatureSets(featureflag.UploadPackHideRefs).Run(t, testInfoRefsUploadPackSuccessful) +} + +func testInfoRefsUploadPackSuccessful(t *testing.T, ctx context.Context) { + t.Parallel() cfg := testcfg.Build(t) cfg.SocketPath = runSmartHTTPServer(t, cfg) - ctx := testhelper.Context(t) repo, repoPath := gittest.CreateRepository(ctx, t, cfg) @@ -62,10 +66,14 @@ func TestInfoRefsUploadPack_successful(t *testing.T) { func TestInfoRefsUploadPack_internalRefs(t *testing.T) { t.Parallel() + testhelper.NewFeatureSets(featureflag.UploadPackHideRefs).Run(t, testInfoRefsUploadPackInternalRefs) +} + +func testInfoRefsUploadPackInternalRefs(t *testing.T, ctx context.Context) { + t.Parallel() cfg := testcfg.Build(t) cfg.SocketPath = runSmartHTTPServer(t, cfg) - ctx := testhelper.Context(t) for _, tc := range []struct { ref string @@ -97,17 +105,37 @@ func TestInfoRefsUploadPack_internalRefs(t *testing.T) { }, { ref: "refs/tmp/1", - expectedAdvertisements: []string{ - "HEAD", - "refs/heads/main\n", - }, + expectedAdvertisements: func() []string { + if featureflag.UploadPackHideRefs.IsDisabled(ctx) { + return []string{ + "HEAD", + "refs/heads/main\n", + "refs/tmp/1\n", + } + } + + return []string{ + "HEAD", + "refs/heads/main\n", + } + }(), }, { ref: "refs/keep-around/1", - expectedAdvertisements: []string{ - "HEAD", - "refs/heads/main\n", - }, + expectedAdvertisements: func() []string { + if featureflag.UploadPackHideRefs.IsDisabled(ctx) { + return []string{ + "HEAD", + "refs/heads/main\n", + "refs/keep-around/1\n", + } + } + + return []string{ + "HEAD", + "refs/heads/main\n", + } + }(), }, } { t.Run(tc.ref, func(t *testing.T) { @@ -130,18 +158,21 @@ func TestInfoRefsUploadPack_internalRefs(t *testing.T) { } } -func TestInfoRefsUploadPack_repositoryDoesntExist(t *testing.T) { +func TestInfoRefsUploadPackRepositoryDoesntExist(t *testing.T) { t.Parallel() + testhelper.NewFeatureSets(featureflag.UploadPackHideRefs).Run(t, testInfoRefsUploadPackRepositoryDoesntExist) +} - cfg := testcfg.Build(t) +func testInfoRefsUploadPackRepositoryDoesntExist(t *testing.T, ctx context.Context) { + t.Parallel() + cfg := testcfg.Build(t) serverSocketPath := runSmartHTTPServer(t, cfg) rpcRequest := &gitalypb.InfoRefsRequest{Repository: &gitalypb.Repository{ StorageName: cfg.Storages[0].Name, RelativePath: "doesnt/exist", }} - ctx := testhelper.Context(t) _, err := makeInfoRefsUploadPackRequest(ctx, t, serverSocketPath, cfg.Auth.Token, rpcRequest) @@ -153,13 +184,16 @@ func TestInfoRefsUploadPack_repositoryDoesntExist(t *testing.T) { testhelper.RequireGrpcError(t, expectedErr, err) } -func TestInfoRefsUploadPack_partialClone(t *testing.T) { +func TestInfoRefsUploadPackPartialClone(t *testing.T) { t.Parallel() + testhelper.NewFeatureSets(featureflag.UploadPackHideRefs).Run(t, testInfoRefsUploadPackPartialClone) +} - cfg := testcfg.Build(t) +func testInfoRefsUploadPackPartialClone(t *testing.T, ctx context.Context) { + t.Parallel() + cfg := testcfg.Build(t) cfg.SocketPath = runSmartHTTPServer(t, cfg) - ctx := testhelper.Context(t) repo, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ Seed: gittest.SeedGitLabTest, @@ -180,13 +214,17 @@ func TestInfoRefsUploadPack_partialClone(t *testing.T) { } } -func TestInfoRefsUploadPack_gitConfigOptions(t *testing.T) { +func TestInfoRefsUploadPackGitConfigOptions(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UploadPackHideRefs).Run(t, testInfoRefsUploadPackGitConfigOptions) +} + +func testInfoRefsUploadPackGitConfigOptions(t *testing.T, ctx context.Context) { t.Parallel() cfg := testcfg.Build(t) cfg.SocketPath = runSmartHTTPServer(t, cfg) - ctx := testhelper.Context(t) repo, repoPath := gittest.CreateRepository(ctx, t, cfg) commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main"), gittest.WithParents()) @@ -204,11 +242,15 @@ func TestInfoRefsUploadPack_gitConfigOptions(t *testing.T) { }) } -func TestInfoRefsUploadPack_gitProtocol(t *testing.T) { +func TestInfoRefsUploadPackGitProtocol(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UploadPackHideRefs).Run(t, testInfoRefsUploadPackGitProtocol) +} + +func testInfoRefsUploadPackGitProtocol(t *testing.T, ctx context.Context) { t.Parallel() cfg := testcfg.Build(t) - ctx := testhelper.Context(t) protocolDetectingFactory := gittest.NewProtocolDetectingCommandFactory(ctx, t, cfg) @@ -262,12 +304,16 @@ func makeInfoRefsUploadPackRequest(ctx context.Context, t *testing.T, serverSock return response, err } -func TestInfoRefsReceivePack_successful(t *testing.T) { +func TestInfoRefsReceivePackSuccessful(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UploadPackHideRefs).Run(t, testInfoRefsReceivePackSuccessful) +} + +func testInfoRefsReceivePackSuccessful(t *testing.T, ctx context.Context) { t.Parallel() cfg := testcfg.Build(t) cfg.SocketPath = runSmartHTTPServer(t, cfg) - ctx := testhelper.Context(t) repo, repoPath := gittest.CreateRepository(ctx, t, cfg) @@ -287,7 +333,12 @@ func TestInfoRefsReceivePack_successful(t *testing.T) { }) } -func TestInfoRefsReceivePack_hiddenRefs(t *testing.T) { +func TestInfoRefsReceivePackHiddenRefs(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UploadPackHideRefs).Run(t, testInfoRefsReceivePackHiddenRefs) +} + +func testInfoRefsReceivePackHiddenRefs(t *testing.T, ctx context.Context) { t.Parallel() cfg := testcfg.Build(t) @@ -295,7 +346,6 @@ func TestInfoRefsReceivePack_hiddenRefs(t *testing.T) { testcfg.BuildGitalyHooks(t, cfg) cfg.SocketPath = runSmartHTTPServer(t, cfg) - ctx := testhelper.Context(t) repoProto, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{ Seed: gittest.SeedGitLabTest, @@ -330,7 +380,12 @@ func TestInfoRefsReceivePack_hiddenRefs(t *testing.T) { require.NotContains(t, string(response), commitID+" .have") } -func TestInfoRefsReceivePack_repoNotFound(t *testing.T) { +func TestInfoRefsReceivePackRepoNotFound(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UploadPackHideRefs).Run(t, testInfoRefsReceivePackRepoNotFound) +} + +func testInfoRefsReceivePackRepoNotFound(t *testing.T, ctx context.Context) { t.Parallel() cfg := testcfg.Build(t) @@ -339,7 +394,6 @@ func TestInfoRefsReceivePack_repoNotFound(t *testing.T) { repo := &gitalypb.Repository{StorageName: cfg.Storages[0].Name, RelativePath: "testdata/scratch/another_repo"} rpcRequest := &gitalypb.InfoRefsRequest{Repository: repo} - ctx := testhelper.Context(t) _, err := makeInfoRefsReceivePackRequest(ctx, t, serverSocketPath, cfg.Auth.Token, rpcRequest) expectedErr := helper.ErrNotFoundf(`GetRepoPath: not a git repository: "` + cfg.Storages[0].Path + "/" + repo.RelativePath + `"`) @@ -350,7 +404,12 @@ func TestInfoRefsReceivePack_repoNotFound(t *testing.T) { testhelper.RequireGrpcError(t, expectedErr, err) } -func TestInfoRefsReceivePack_repoNotSet(t *testing.T) { +func TestInfoRefsReceivePackRepoNotSet(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UploadPackHideRefs).Run(t, testInfoRefsReceivePackRepoNotSet) +} + +func testInfoRefsReceivePackRepoNotSet(t *testing.T, ctx context.Context) { t.Parallel() cfg := testcfg.Build(t) @@ -358,7 +417,6 @@ func TestInfoRefsReceivePack_repoNotSet(t *testing.T) { serverSocketPath := runSmartHTTPServer(t, cfg) rpcRequest := &gitalypb.InfoRefsRequest{} - ctx := testhelper.Context(t) _, err := makeInfoRefsReceivePackRequest(ctx, t, serverSocketPath, cfg.Auth.Token, rpcRequest) testhelper.RequireGrpcCode(t, err, codes.InvalidArgument) } @@ -418,7 +476,12 @@ func (ms *mockStreamer) PutStream(ctx context.Context, repo *gitalypb.Repository return ms.Streamer.PutStream(ctx, repo, req, src) } -func TestInfoRefsUploadPack_cache(t *testing.T) { +func TestInfoRefsUploadPackCache(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UploadPackHideRefs).Run(t, testInfoRefsUploadPackCache) +} + +func testInfoRefsUploadPackCache(t *testing.T, ctx context.Context) { t.Parallel() cfg := testcfg.Build(t) @@ -434,8 +497,6 @@ func TestInfoRefsUploadPack_cache(t *testing.T) { gitalyServer := startSmartHTTPServer(t, cfg, withInfoRefCache(mockInfoRefCache)) cfg.SocketPath = gitalyServer.Address() - ctx := testhelper.Context(t) - repo, repoPath := gittest.CreateRepository(ctx, t, cfg) commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main"), gittest.WithParents()) diff --git a/internal/gitaly/service/smarthttp/upload_pack_test.go b/internal/gitaly/service/smarthttp/upload_pack_test.go index 35843932f..184138c88 100644 --- a/internal/gitaly/service/smarthttp/upload_pack_test.go +++ b/internal/gitaly/service/smarthttp/upload_pack_test.go @@ -20,6 +20,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/git" "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" "gitlab.com/gitlab-org/gitaly/v15/internal/git/pktline" + "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" "gitlab.com/gitlab-org/gitaly/v15/internal/sidechannel" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" @@ -45,15 +46,15 @@ func runTestWithAndWithoutConfigOptions( makeRequest requestMaker, opts ...testcfg.Option, ) { - ctx := testhelper.Context(t) + testhelper.NewFeatureSets(featureflag.UploadPackHideRefs).Run(t, func(t *testing.T, ctx context.Context) { + t.Run("no config options", func(t *testing.T) { tf(t, ctx, makeRequest) }) - t.Run("no config options", func(t *testing.T) { tf(t, ctx, makeRequest) }) - - if len(opts) > 0 { - t.Run("with config options", func(t *testing.T) { - tf(t, ctx, makeRequest, opts...) - }) - } + if len(opts) > 0 { + t.Run("with config options", func(t *testing.T) { + tf(t, ctx, makeRequest, opts...) + }) + } + }) } func TestServer_PostUpload(t *testing.T) { @@ -263,16 +264,18 @@ func testServerPostUploadPackSuppressDeepenExitError(t *testing.T, ctx context.C func TestServer_PostUploadPack_usesPackObjectsHook(t *testing.T) { t.Parallel() - ctx := testhelper.Context(t) - testServerPostUploadPackUsesPackObjectsHook(t, ctx, makePostUploadPackRequest) + testhelper.NewFeatureSets(featureflag.UploadPackHideRefs).Run(t, func(t *testing.T, ctx context.Context) { + testServerPostUploadPackUsesPackObjectsHook(t, ctx, makePostUploadPackRequest) + }) } func TestServer_PostUploadPackWithSidechannel_usesPackObjectsHook(t *testing.T) { t.Parallel() - ctx := testhelper.Context(t) - testServerPostUploadPackUsesPackObjectsHook(t, ctx, makePostUploadPackWithSidechannelRequest) + testhelper.NewFeatureSets(featureflag.UploadPackHideRefs).Run(t, func(t *testing.T, ctx context.Context) { + testServerPostUploadPackUsesPackObjectsHook(t, ctx, makePostUploadPackWithSidechannelRequest) + }) } func testServerPostUploadPackUsesPackObjectsHook(t *testing.T, ctx context.Context, makeRequest requestMaker, opts ...testcfg.Option) { @@ -493,16 +496,18 @@ func testServerPostUploadPackPartialClone(t *testing.T, ctx context.Context, mak func TestServer_PostUploadPack_allowAnySHA1InWant(t *testing.T) { t.Parallel() - ctx := testhelper.Context(t) - testServerPostUploadPackAllowAnySHA1InWant(t, ctx, makePostUploadPackRequest) + testhelper.NewFeatureSets(featureflag.UploadPackHideRefs).Run(t, func(t *testing.T, ctx context.Context) { + testServerPostUploadPackAllowAnySHA1InWant(t, ctx, makePostUploadPackRequest) + }) } func TestServer_PostUploadPackWithSidechannel_allowAnySHA1InWant(t *testing.T) { t.Parallel() - ctx := testhelper.Context(t) - testServerPostUploadPackAllowAnySHA1InWant(t, ctx, makePostUploadPackWithSidechannelRequest) + testhelper.NewFeatureSets(featureflag.UploadPackHideRefs).Run(t, func(t *testing.T, ctx context.Context) { + testServerPostUploadPackAllowAnySHA1InWant(t, ctx, makePostUploadPackWithSidechannelRequest) + }) } func testServerPostUploadPackAllowAnySHA1InWant(t *testing.T, ctx context.Context, makeRequest requestMaker, opts ...testcfg.Option) { diff --git a/internal/gitaly/service/ssh/upload_pack_test.go b/internal/gitaly/service/ssh/upload_pack_test.go index 29c6d98ff..862e04c10 100644 --- a/internal/gitaly/service/ssh/upload_pack_test.go +++ b/internal/gitaly/service/ssh/upload_pack_test.go @@ -137,7 +137,12 @@ func testUploadPackTimeout(t *testing.T, opts ...testcfg.Option) { }) } -func TestUploadPackWithSidechannel_client(t *testing.T) { +func TestUploadPackWithSidechannelClient(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UploadPackHideRefs).Run(t, testUploadPackWithSidechannelClient) +} + +func testUploadPackWithSidechannelClient(t *testing.T, ctx context.Context) { t.Parallel() cfg := testcfg.Build(t) @@ -376,7 +381,7 @@ func TestUploadPackWithSidechannel_client(t *testing.T) { }, } { t.Run(tc.desc, func(t *testing.T) { - ctx, cancel := context.WithCancel(testhelper.Context(t)) + ctx, cancel := context.WithCancel(ctx) ctx, waiter := sidechannel.RegisterSidechannel(ctx, registry, func(clientConn *sidechannel.ClientConn) (returnedErr error) { errCh := make(chan error, 1) @@ -642,10 +647,13 @@ func testUploadPackSuccessful(t *testing.T, sidechannel bool, opts ...testcfg.Op } } -func TestUploadPack_packObjectsHook(t *testing.T) { +func TestUploadPackPackObjectsHook(t *testing.T) { t.Parallel() + testhelper.NewFeatureSets(featureflag.UploadPackHideRefs).Run(t, testUploadPackPackObjectsHook) +} - ctx := testhelper.Context(t) +func testUploadPackPackObjectsHook(t *testing.T, ctx context.Context) { + t.Parallel() cfg := testcfg.Build(t, testcfg.WithPackObjectsCacheEnabled()) @@ -738,10 +746,14 @@ func testUploadPackWithoutSideband(t *testing.T, opts ...testcfg.Option) { require.Contains(t, string(out), "PACK") } -func TestUploadPack_invalidStorage(t *testing.T) { +func TestUploadPackInvalidStorage(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UploadPackHideRefs).Run(t, testUploadPackInvalidStorage) +} + +func testUploadPackInvalidStorage(t *testing.T, ctx context.Context) { t.Parallel() - ctx := testhelper.Context(t) cfg := testcfg.Build(t) cfg.SocketPath = runSSHServer(t, cfg) @@ -773,10 +785,14 @@ func TestUploadPack_invalidStorage(t *testing.T) { } } -func TestUploadPack_gitFailure(t *testing.T) { +func TestUploadPackGitFailure(t *testing.T) { + t.Parallel() + testhelper.NewFeatureSets(featureflag.UploadPackHideRefs).Run(t, testUploadPackGitFailure) +} + +func testUploadPackGitFailure(t *testing.T, ctx context.Context) { t.Parallel() - ctx := testhelper.Context(t) cfg := testcfg.Build(t) cfg.SocketPath = runSSHServer(t, cfg) diff --git a/internal/metadata/featureflag/ff_upload_pack_hide_refs.go b/internal/metadata/featureflag/ff_upload_pack_hide_refs.go new file mode 100644 index 000000000..1e26e33e5 --- /dev/null +++ b/internal/metadata/featureflag/ff_upload_pack_hide_refs.go @@ -0,0 +1,9 @@ +package featureflag + +// UploadPackHideRefs causes git-upload-pack(1) to hide internal references. +var UploadPackHideRefs = NewFeatureFlag( + "upload_pack_hide_refs", + "v15.3.0", + "https://gitlab.com/gitlab-org/gitaly/-/issues/4390", + false, +) -- cgit v1.2.3