diff options
author | Patrick Steinhardt <psteinhardt@gitlab.com> | 2023-04-06 08:07:56 +0300 |
---|---|---|
committer | Patrick Steinhardt <psteinhardt@gitlab.com> | 2023-04-06 08:07:56 +0300 |
commit | c31b9fed97bb01a1790496386ceab8e31e76b1d8 (patch) | |
tree | 71785e0af340e09df89bc4a57eac9915ab76ecdd | |
parent | f1702db8051171a04fc4f7ea3da41c40fcce8ab6 (diff) | |
parent | 6e29ccf1eaad4312980a68bd30fb9d5395d94837 (diff) |
Merge branch 'pks-git-hooks-object-format' into 'master'
git: Enable support for SHA256 object format in hooks
See merge request https://gitlab.com/gitlab-org/gitaly/-/merge_requests/5597
Merged-by: Patrick Steinhardt <psteinhardt@gitlab.com>
Approved-by: karthik nayak <knayak@gitlab.com>
Approved-by: Will Chandler <wchandler@gitlab.com>
26 files changed, 297 insertions, 139 deletions
diff --git a/cmd/gitaly-hooks/hooks_test.go b/cmd/gitaly-hooks/hooks_test.go index b200793e2..b807b2c0c 100644 --- a/cmd/gitaly-hooks/hooks_test.go +++ b/cmd/gitaly-hooks/hooks_test.go @@ -68,12 +68,17 @@ func featureFlags(ctx context.Context) map[featureflag.FeatureFlag]bool { // envForHooks generates a set of environment variables for gitaly hooks func envForHooks(tb testing.TB, ctx context.Context, cfg config.Cfg, repo *gitalypb.Repository, glHookValues glHookValues, proxyValues proxyValues, gitPushOptions ...string) []string { - payload, err := git.NewHooksPayload(cfg, repo, nil, &git.UserDetails{ - UserID: glHookValues.GLID, - Username: glHookValues.GLUsername, - Protocol: glHookValues.GLProtocol, - RemoteIP: glHookValues.RemoteIP, - }, git.AllHooks, featureFlags(ctx)).Env() + payload, err := git.NewHooksPayload( + cfg, + repo, + gittest.DefaultObjectHash, + nil, + &git.UserDetails{ + UserID: glHookValues.GLID, + Username: glHookValues.GLUsername, + Protocol: glHookValues.GLProtocol, + RemoteIP: glHookValues.RemoteIP, + }, git.AllHooks, featureFlags(ctx)).Env() require.NoError(tb, err) env := append(command.AllowedEnvironment(os.Environ()), []string{ @@ -427,6 +432,7 @@ func TestHooksPostReceiveFailed(t *testing.T) { hooksPayload, err := git.NewHooksPayload( cfg, repo, + gittest.DefaultObjectHash, &txinfo.Transaction{ ID: 1, Node: "node", @@ -660,7 +666,15 @@ func TestRequestedHooks(t *testing.T) { testcfg.BuildGitalyHooks(t, cfg) testcfg.BuildGitalySSH(t, cfg) - payload, err := git.NewHooksPayload(cfg, &gitalypb.Repository{}, nil, nil, git.AllHooks&^hook, nil).Env() + payload, err := git.NewHooksPayload( + cfg, + &gitalypb.Repository{}, + gittest.DefaultObjectHash, + nil, + nil, + git.AllHooks&^hook, + nil, + ).Env() require.NoError(t, err) cmd := exec.Command(cfg.BinaryPath("gitaly-hooks")) @@ -674,7 +688,15 @@ func TestRequestedHooks(t *testing.T) { testcfg.BuildGitalyHooks(t, cfg) testcfg.BuildGitalySSH(t, cfg) - payload, err := git.NewHooksPayload(cfg, &gitalypb.Repository{}, nil, nil, hook, nil).Env() + payload, err := git.NewHooksPayload( + cfg, + &gitalypb.Repository{}, + gittest.DefaultObjectHash, + nil, + nil, + hook, + nil, + ).Env() require.NoError(t, err) cmd := exec.Command(cfg.BinaryPath("gitaly-hooks")) diff --git a/internal/git/hooks_options.go b/internal/git/hooks_options.go index d70f9a05d..8c9dcde26 100644 --- a/internal/git/hooks_options.go +++ b/internal/git/hooks_options.go @@ -92,6 +92,32 @@ func WithPackObjectsHookEnv(repo *gitalypb.Repository, protocol string) CmdOpt { } } +// ReceivePackRequest abstracts away the different requests that end up +// spawning git-receive-pack. +type ReceivePackRequest interface { + GetGlId() string + GetGlUsername() string + GetGlRepository() string + GetRepository() *gitalypb.Repository +} + +// WithReceivePackHooks returns an option that populates the safe command with the environment +// variables necessary to properly execute the pre-receive, update and post-receive hooks for +// git-receive-pack(1). +func WithReceivePackHooks(req ReceivePackRequest, protocol string) CmdOpt { + return func(ctx context.Context, cfg config.Cfg, gitCmdFactory CommandFactory, cc *cmdCfg) error { + if err := cc.configureHooks(ctx, req.GetRepository(), cfg, gitCmdFactory, &UserDetails{ + UserID: req.GetGlId(), + Username: req.GetGlUsername(), + Protocol: protocol, + }, ReceivePackHooks); err != nil { + return err + } + + return nil + } +} + // configureHooks updates the command configuration to include all environment // variables required by the reference transaction hook and any other needed // options to successfully execute hooks. @@ -107,6 +133,11 @@ func (cc *cmdCfg) configureHooks( return errors.New("hooks already configured") } + objectHash, err := DetectObjectHash(ctx, gitCmdFactory, repo) + if err != nil { + return fmt.Errorf("detecting object hash: %w", err) + } + var transaction *txinfo.Transaction if tx, err := txinfo.TransactionFromContext(ctx); err == nil { transaction = &tx @@ -117,6 +148,7 @@ func (cc *cmdCfg) configureHooks( payload, err := NewHooksPayload( cfg, repo, + objectHash, transaction, userDetails, requestedHooks, @@ -137,29 +169,3 @@ func (cc *cmdCfg) configureHooks( return nil } - -// ReceivePackRequest abstracts away the different requests that end up -// spawning git-receive-pack. -type ReceivePackRequest interface { - GetGlId() string - GetGlUsername() string - GetGlRepository() string - GetRepository() *gitalypb.Repository -} - -// WithReceivePackHooks returns an option that populates the safe command with the environment -// variables necessary to properly execute the pre-receive, update and post-receive hooks for -// git-receive-pack(1). -func WithReceivePackHooks(req ReceivePackRequest, protocol string) CmdOpt { - return func(ctx context.Context, cfg config.Cfg, gitCmdFactory CommandFactory, cc *cmdCfg) error { - if err := cc.configureHooks(ctx, req.GetRepository(), cfg, gitCmdFactory, &UserDetails{ - UserID: req.GetGlId(), - Username: req.GetGlUsername(), - Protocol: protocol, - }, ReceivePackHooks); err != nil { - return err - } - - return nil - } -} diff --git a/internal/git/hooks_payload.go b/internal/git/hooks_payload.go index 04c7828cc..2bb37f382 100644 --- a/internal/git/hooks_payload.go +++ b/internal/git/hooks_payload.go @@ -67,6 +67,9 @@ type HooksPayload struct { // Repo is the repository in which the hook is running. Repo *gitalypb.Repository `json:"-"` + // ObjectFormat is the object format used by the repository. Some hooks use it in order to + // verify object IDs part of their input. + ObjectFormat string `json:"object_format"` // RuntimeDir is the path to Gitaly's runtime directory. RuntimeDir string `json:"runtime_dir"` @@ -113,6 +116,7 @@ type jsonHooksPayload struct { func NewHooksPayload( cfg config.Cfg, repo *gitalypb.Repository, + objectHash ObjectHash, tx *txinfo.Transaction, userDetails *UserDetails, requestedHooks Hook, @@ -128,6 +132,7 @@ func NewHooksPayload( return HooksPayload{ Repo: repo, + ObjectFormat: objectHash.Format, RuntimeDir: cfg.RuntimeDir, InternalSocket: cfg.InternalSocketPath(), InternalSocketToken: cfg.Auth.Token, diff --git a/internal/git/hooks_payload_test.go b/internal/git/hooks_payload_test.go index 44c8af754..f7806e469 100644 --- a/internal/git/hooks_payload_test.go +++ b/internal/git/hooks_payload_test.go @@ -30,15 +30,30 @@ func TestHooksPayload(t *testing.T) { } t.Run("envvar has proper name", func(t *testing.T) { - env, err := git.NewHooksPayload(cfg, repo, nil, nil, git.AllHooks, nil).Env() + env, err := git.NewHooksPayload( + cfg, + repo, + gittest.DefaultObjectHash, + nil, + nil, + git.AllHooks, + nil, + ).Env() require.NoError(t, err) require.True(t, strings.HasPrefix(env, git.EnvHooksPayload+"=")) }) t.Run("roundtrip succeeds", func(t *testing.T) { - env, err := git.NewHooksPayload(cfg, repo, nil, nil, git.PreReceiveHook, map[featureflag.FeatureFlag]bool{ - {Name: "flag_key"}: true, - }).Env() + env, err := git.NewHooksPayload( + cfg, + repo, + gittest.DefaultObjectHash, + nil, + nil, + git.PreReceiveHook, + map[featureflag.FeatureFlag]bool{ + {Name: "flag_key"}: true, + }).Env() require.NoError(t, err) payload, err := git.HooksPayloadFromEnv([]string{ @@ -51,6 +66,7 @@ func TestHooksPayload(t *testing.T) { require.Equal(t, git.HooksPayload{ Repo: repo, + ObjectFormat: gittest.DefaultObjectHash.Format, RuntimeDir: cfg.RuntimeDir, InternalSocket: cfg.InternalSocketPath(), RequestedHooks: git.PreReceiveHook, @@ -64,7 +80,15 @@ func TestHooksPayload(t *testing.T) { }) t.Run("roundtrip with transaction succeeds", func(t *testing.T) { - env, err := git.NewHooksPayload(cfg, repo, &tx, nil, git.UpdateHook, nil).Env() + env, err := git.NewHooksPayload( + cfg, + repo, + gittest.DefaultObjectHash, + &tx, + nil, + git.UpdateHook, + nil, + ).Env() require.NoError(t, err) payload, err := git.HooksPayloadFromEnv([]string{env}) @@ -72,6 +96,7 @@ func TestHooksPayload(t *testing.T) { require.Equal(t, git.HooksPayload{ Repo: repo, + ObjectFormat: gittest.DefaultObjectHash.Format, RuntimeDir: cfg.RuntimeDir, InternalSocket: cfg.InternalSocketPath(), Transaction: &tx, @@ -91,11 +116,16 @@ func TestHooksPayload(t *testing.T) { }) t.Run("receive hooks payload", func(t *testing.T) { - env, err := git.NewHooksPayload(cfg, repo, nil, &git.UserDetails{ - UserID: "1234", - Username: "user", - Protocol: "ssh", - }, git.PostReceiveHook, nil).Env() + env, err := git.NewHooksPayload( + cfg, + repo, + gittest.DefaultObjectHash, + nil, + &git.UserDetails{ + UserID: "1234", + Username: "user", + Protocol: "ssh", + }, git.PostReceiveHook, nil).Env() require.NoError(t, err) payload, err := git.HooksPayloadFromEnv([]string{ @@ -108,6 +138,7 @@ func TestHooksPayload(t *testing.T) { require.Equal(t, git.HooksPayload{ Repo: repo, + ObjectFormat: gittest.DefaultObjectHash.Format, RuntimeDir: cfg.RuntimeDir, InternalSocket: cfg.InternalSocketPath(), InternalSocketToken: cfg.Auth.Token, diff --git a/internal/git/housekeeping/worktrees_test.go b/internal/git/housekeeping/worktrees_test.go index eccc3cd1c..96694973e 100644 --- a/internal/git/housekeeping/worktrees_test.go +++ b/internal/git/housekeeping/worktrees_test.go @@ -27,24 +27,28 @@ func TestCleanupDisconnectedWorktrees_doesNothingWithoutWorktrees(t *testing.T) gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch(git.DefaultBranch)) worktreePath := filepath.Join(testhelper.TempDir(t), "worktree") - failingGitCmdFactory := gittest.NewInterceptingCommandFactory(t, ctx, cfg, func(git.ExecutionEnvironment) string { - return `#!/usr/bin/env bash - exit 15 - ` - }) + countingGitCmdFactory := gittest.NewCountingCommandFactory(t, cfg) - repo := localrepo.New(config.NewLocator(cfg), failingGitCmdFactory, nil, repoProto) + repo := localrepo.New(config.NewLocator(cfg), countingGitCmdFactory, nil, repoProto) // If this command did spawn git-worktree(1) we'd see an error. It doesn't though because it // detects that there aren't any worktrees at all. require.NoError(t, cleanDisconnectedWorktrees(ctx, repo)) + require.EqualValues(t, 0, countingGitCmdFactory.CommandCount("worktree")) + // Create a worktree, but remove the actual worktree path so that it will be disconnected. gittest.AddWorktree(t, cfg, repoPath, worktreePath) + require.NoError(t, os.RemoveAll(worktreePath)) // We have now added a worktree now, so it should detect that there are worktrees and thus - // spawn the Git command. We thus expect the error code we inject via the failing Git - // command factory. - require.EqualError(t, cleanDisconnectedWorktrees(ctx, repo), "exit status 15") + // spawn the Git command. + require.NoError(t, cleanDisconnectedWorktrees(ctx, repo)) + require.EqualValues(t, 1, countingGitCmdFactory.CommandCount("worktree")) + + // Trigger the cleanup again. As we have just deleted the worktree, we should not see + // another execution of git-worktree(1). + require.NoError(t, cleanDisconnectedWorktrees(ctx, repo)) + require.EqualValues(t, 1, countingGitCmdFactory.CommandCount("worktree")) } func TestRemoveWorktree(t *testing.T) { diff --git a/internal/git/localrepo/repo.go b/internal/git/localrepo/repo.go index 6892388e6..1fd7764cd 100644 --- a/internal/git/localrepo/repo.go +++ b/internal/git/localrepo/repo.go @@ -116,7 +116,7 @@ func (repo *Repo) StorageTempDir() (string, error) { // ObjectHash detects the object hash used by this particular repository. func (repo *Repo) ObjectHash(ctx context.Context) (git.ObjectHash, error) { repo.detectObjectHashOnce.Do(func() { - repo.objectHash, repo.objectHashErr = git.DetectObjectHash(ctx, repo) + repo.objectHash, repo.objectHashErr = git.DetectObjectHash(ctx, repo.gitCmdFactory, repo) }) return repo.objectHash, repo.objectHashErr } diff --git a/internal/git/object_id.go b/internal/git/object_id.go index 69bb58b8b..fa4ecf4a9 100644 --- a/internal/git/object_id.go +++ b/internal/git/object_id.go @@ -9,6 +9,7 @@ import ( "fmt" "hash" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/repository" "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" "gitlab.com/gitlab-org/gitaly/v15/internal/structerr" "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" @@ -97,15 +98,20 @@ func ObjectHashByProto(format gitalypb.ObjectFormat) (ObjectHash, error) { } // DetectObjectHash detects the object-hash used by the given repository. -func DetectObjectHash(ctx context.Context, repoExecutor RepositoryExecutor) (ObjectHash, error) { +func DetectObjectHash(ctx context.Context, gitCmdFactory CommandFactory, repository repository.GitRepo) (ObjectHash, error) { var stdout, stderr bytes.Buffer - if err := repoExecutor.ExecAndWait(ctx, Command{ + revParseCmd, err := gitCmdFactory.New(ctx, repository, Command{ Name: "rev-parse", Flags: []Option{ Flag{"--show-object-format"}, }, - }, WithStdout(&stdout), WithStderr(&stderr)); err != nil { + }, WithStdout(&stdout), WithStderr(&stderr)) + if err != nil { + return ObjectHash{}, fmt.Errorf("spawning rev-parse: %w", err) + } + + if err := revParseCmd.Wait(); err != nil { return ObjectHash{}, structerr.New("reading object format: %w", err).WithMetadata("stderr", stderr.String()) } diff --git a/internal/git/object_id_test.go b/internal/git/object_id_test.go index 7d462fe63..6392085b7 100644 --- a/internal/git/object_id_test.go +++ b/internal/git/object_id_test.go @@ -11,7 +11,6 @@ import ( "github.com/stretchr/testify/require" "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/localrepo" "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" "gitlab.com/gitlab-org/gitaly/v15/internal/structerr" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" @@ -93,8 +92,11 @@ func TestObjectHashByProto(t *testing.T) { } func TestDetectObjectHash(t *testing.T) { + t.Parallel() + cfg := testcfg.Build(t) ctx := testhelper.Context(t) + gitCmdFactory := gittest.NewCommandFactory(t, cfg) for _, tc := range []struct { desc string @@ -189,9 +191,8 @@ func TestDetectObjectHash(t *testing.T) { } { t.Run(tc.desc, func(t *testing.T) { repoProto := tc.setup(t) - repo := localrepo.NewTestRepo(t, cfg, repoProto) - hash, err := git.DetectObjectHash(ctx, repo) + hash, err := git.DetectObjectHash(ctx, gitCmdFactory, repoProto) if tc.expectedErr != nil { require.Error(t, err) require.Contains(t, err.Error(), tc.expectedErr.Error()) diff --git a/internal/git/updateref/update_with_hooks.go b/internal/git/updateref/update_with_hooks.go index 1d78f0e97..11182250f 100644 --- a/internal/git/updateref/update_with_hooks.go +++ b/internal/git/updateref/update_with_hooks.go @@ -195,7 +195,7 @@ func (u *UpdaterWithHooks) UpdateReference( quarantinedRepo = quarantineDir.QuarantinedRepo() } - hooksPayload, err := git.NewHooksPayload(u.cfg, quarantinedRepo, transaction, &receiveHooksPayload, git.ReceivePackHooks, featureflag.FromContext(ctx)).Env() + hooksPayload, err := git.NewHooksPayload(u.cfg, quarantinedRepo, objectHash, transaction, &receiveHooksPayload, git.ReceivePackHooks, featureflag.FromContext(ctx)).Env() if err != nil { return fmt.Errorf("constructing hooks payload: %w", err) } @@ -217,7 +217,7 @@ func (u *UpdaterWithHooks) UpdateReference( // We only need to update the hooks payload to the unquarantined repo in case we // had a quarantine environment. Otherwise, the initial hooks payload is for the // real repository anyway. - hooksPayload, err = git.NewHooksPayload(u.cfg, repoProto, transaction, &receiveHooksPayload, git.ReceivePackHooks, featureflag.FromContext(ctx)).Env() + hooksPayload, err = git.NewHooksPayload(u.cfg, repoProto, objectHash, transaction, &receiveHooksPayload, git.ReceivePackHooks, featureflag.FromContext(ctx)).Env() if err != nil { return fmt.Errorf("constructing quarantined hooks payload: %w", err) } diff --git a/internal/git/updateref/update_with_hooks_test.go b/internal/git/updateref/update_with_hooks_test.go index aa34632a2..9f3bd438c 100644 --- a/internal/git/updateref/update_with_hooks_test.go +++ b/internal/git/updateref/update_with_hooks_test.go @@ -109,11 +109,16 @@ func TestUpdaterWithHooks_UpdateReference(t *testing.T) { requirePayload := func(t *testing.T, env []string) { require.Len(t, env, 1) - expectedPayload := git.NewHooksPayload(cfg, repo, nil, &git.UserDetails{ - UserID: gittest.TestUser.GlId, - Username: gittest.TestUser.GlUsername, - Protocol: "web", - }, git.ReceivePackHooks, featureflag.FromContext(ctx)) + expectedPayload := git.NewHooksPayload( + cfg, + repo, + gittest.DefaultObjectHash, + nil, + &git.UserDetails{ + UserID: gittest.TestUser.GlId, + Username: gittest.TestUser.GlUsername, + Protocol: "web", + }, git.ReceivePackHooks, featureflag.FromContext(ctx)) actualPayload, err := git.HooksPayloadFromEnv(env) require.NoError(t, err) diff --git a/internal/gitaly/hook/postreceive_test.go b/internal/gitaly/hook/postreceive_test.go index 6e62405a4..21f1f4db2 100644 --- a/internal/gitaly/hook/postreceive_test.go +++ b/internal/gitaly/hook/postreceive_test.go @@ -87,12 +87,21 @@ func TestPostReceive_customHook(t *testing.T) { Protocol: "web", } - payload, err := git.NewHooksPayload(cfg, repo, nil, receiveHooksPayload, git.PostReceiveHook, featureflag.FromContext(ctx)).Env() + payload, err := git.NewHooksPayload( + cfg, + repo, + gittest.DefaultObjectHash, + nil, + receiveHooksPayload, + git.PostReceiveHook, + featureflag.FromContext(ctx), + ).Env() require.NoError(t, err) primaryPayload, err := git.NewHooksPayload( cfg, repo, + gittest.DefaultObjectHash, &txinfo.Transaction{ ID: 1234, Node: "primary", Primary: true, }, @@ -105,6 +114,7 @@ func TestPostReceive_customHook(t *testing.T) { secondaryPayload, err := git.NewHooksPayload( cfg, repo, + gittest.DefaultObjectHash, &txinfo.Transaction{ ID: 1234, Node: "secondary", Primary: false, }, @@ -249,11 +259,16 @@ func TestPostReceive_gitlab(t *testing.T) { SkipCreationViaService: true, }) - payload, err := git.NewHooksPayload(cfg, repo, nil, &git.UserDetails{ - UserID: "1234", - Username: "user", - Protocol: "web", - }, git.PostReceiveHook, nil).Env() + payload, err := git.NewHooksPayload( + cfg, + repo, + gittest.DefaultObjectHash, + nil, + &git.UserDetails{ + UserID: "1234", + Username: "user", + Protocol: "web", + }, git.PostReceiveHook, nil).Env() require.NoError(t, err) standardEnv := []string{payload} @@ -390,7 +405,11 @@ func TestPostReceive_quarantine(t *testing.T) { repoProto: false, } { t.Run(fmt.Sprintf("quarantined: %v", isQuarantined), func(t *testing.T) { - env, err := git.NewHooksPayload(cfg, repo, nil, + env, err := git.NewHooksPayload( + cfg, + repo, + gittest.DefaultObjectHash, + nil, &git.UserDetails{ UserID: "1234", Username: "user", @@ -402,7 +421,7 @@ func TestPostReceive_quarantine(t *testing.T) { require.NoError(t, err) stdin := strings.NewReader(fmt.Sprintf("%s %s refs/heads/master", - git.ObjectHashSHA1.ZeroOID, git.ObjectHashSHA1.ZeroOID)) + gittest.DefaultObjectHash.ZeroOID, gittest.DefaultObjectHash.ZeroOID)) var stdout, stderr bytes.Buffer require.NoError(t, hookManager.PostReceiveHook(ctx, repo, nil, diff --git a/internal/gitaly/hook/prereceive_test.go b/internal/gitaly/hook/prereceive_test.go index 4092cbe50..168ba5aaf 100644 --- a/internal/gitaly/hook/prereceive_test.go +++ b/internal/gitaly/hook/prereceive_test.go @@ -46,12 +46,21 @@ func TestPrereceive_customHooks(t *testing.T) { Protocol: "web", } - payload, err := git.NewHooksPayload(cfg, repo, nil, receiveHooksPayload, git.PreReceiveHook, featureflag.FromContext(ctx)).Env() + payload, err := git.NewHooksPayload( + cfg, + repo, + gittest.DefaultObjectHash, + nil, + receiveHooksPayload, + git.PreReceiveHook, + featureflag.FromContext(ctx), + ).Env() require.NoError(t, err) primaryPayload, err := git.NewHooksPayload( cfg, repo, + gittest.DefaultObjectHash, &txinfo.Transaction{ ID: 1234, Node: "primary", Primary: true, }, @@ -64,6 +73,7 @@ func TestPrereceive_customHooks(t *testing.T) { secondaryPayload, err := git.NewHooksPayload( cfg, repo, + gittest.DefaultObjectHash, &txinfo.Transaction{ ID: 1234, Node: "secondary", Primary: false, }, @@ -207,7 +217,11 @@ func TestPrereceive_quarantine(t *testing.T) { repoProto: false, } { t.Run(fmt.Sprintf("quarantined: %v", isQuarantined), func(t *testing.T) { - env, err := git.NewHooksPayload(cfg, repo, nil, + env, err := git.NewHooksPayload( + cfg, + repo, + gittest.DefaultObjectHash, + nil, &git.UserDetails{ UserID: "1234", Username: "user", @@ -219,7 +233,7 @@ func TestPrereceive_quarantine(t *testing.T) { require.NoError(t, err) stdin := strings.NewReader(fmt.Sprintf("%s %s refs/heads/master", - git.ObjectHashSHA1.ZeroOID, git.ObjectHashSHA1.ZeroOID)) + gittest.DefaultObjectHash.ZeroOID, gittest.DefaultObjectHash.ZeroOID)) var stdout, stderr bytes.Buffer require.NoError(t, hookManager.PreReceiveHook(ctx, repo, nil, @@ -265,11 +279,16 @@ func TestPrereceive_gitlab(t *testing.T) { SkipCreationViaService: true, }) - payload, err := git.NewHooksPayload(cfg, repo, nil, &git.UserDetails{ - UserID: "1234", - Username: "user", - Protocol: "web", - }, git.PreReceiveHook, nil).Env() + payload, err := git.NewHooksPayload( + cfg, + repo, + gittest.DefaultObjectHash, + nil, + &git.UserDetails{ + UserID: "1234", + Username: "user", + Protocol: "web", + }, git.PreReceiveHook, nil).Env() require.NoError(t, err) standardEnv := []string{payload} diff --git a/internal/gitaly/hook/referencetransaction.go b/internal/gitaly/hook/referencetransaction.go index a63ece62b..1ab5c9fd2 100644 --- a/internal/gitaly/hook/referencetransaction.go +++ b/internal/gitaly/hook/referencetransaction.go @@ -12,10 +12,6 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting" ) -// forceDeletionPrefix is the prefix of a queued reference transaction which deletes a -// reference without checking its current value. -var forceDeletionPrefix = fmt.Sprintf("%[1]s %[1]s ", git.ObjectHashSHA1.ZeroOID.String()) - //nolint:revive // This is unintentionally missing documentation. func (m *GitLabHookManager) ReferenceTransactionHook(ctx context.Context, state ReferenceTransactionState, env []string, stdin io.Reader) error { payload, err := git.HooksPayloadFromEnv(env) @@ -23,6 +19,11 @@ func (m *GitLabHookManager) ReferenceTransactionHook(ctx context.Context, state return fmt.Errorf("extracting hooks payload: %w", err) } + objectHash, err := git.ObjectHashByFormat(payload.ObjectFormat) + if err != nil { + return fmt.Errorf("looking up object hash: %w", err) + } + changes, err := io.ReadAll(stdin) if err != nil { return fmt.Errorf("reading stdin from request: %w", err) @@ -62,7 +63,7 @@ func (m *GitLabHookManager) ReferenceTransactionHook(ctx context.Context, state // The workaround is thus clear: we simply do not cast a vote on any reference transaction // which consists only of force-deletions -- the vote will instead only happen on the loose // backend transaction, which contains the full record of all refs which are to be updated. - if isForceDeletionsOnly(bytes.NewReader(changes)) { + if isForceDeletionsOnly(objectHash, bytes.NewReader(changes)) { return nil } @@ -76,7 +77,11 @@ func (m *GitLabHookManager) ReferenceTransactionHook(ctx context.Context, state } // isForceDeletionsOnly determines whether the given changes only consist of force-deletions. -func isForceDeletionsOnly(changes io.Reader) bool { +func isForceDeletionsOnly(objectHash git.ObjectHash, changes io.Reader) bool { + // forceDeletionPrefix is the prefix of a queued reference transaction which deletes a + // reference without checking its current value. + forceDeletionPrefix := fmt.Sprintf("%[1]s %[1]s ", objectHash.ZeroOID) + scanner := bufio.NewScanner(changes) for scanner.Scan() { diff --git a/internal/gitaly/hook/transactions_test.go b/internal/gitaly/hook/transactions_test.go index 76dedac2e..ff12b7f31 100644 --- a/internal/gitaly/hook/transactions_test.go +++ b/internal/gitaly/hook/transactions_test.go @@ -41,6 +41,7 @@ func TestHookManager_stopCalled(t *testing.T) { hooksPayload, err := git.NewHooksPayload( cfg, repo, + gittest.DefaultObjectHash, &expectedTx, &git.UserDetails{ UserID: "1234", @@ -61,7 +62,7 @@ func TestHookManager_stopCalled(t *testing.T) { return hookManager.PreReceiveHook(ctx, repo, nil, []string{hooksPayload}, strings.NewReader("changes"), io.Discard, io.Discard) } updateFunc := func(t *testing.T) error { - return hookManager.UpdateHook(ctx, repo, "ref", git.ObjectHashSHA1.ZeroOID.String(), git.ObjectHashSHA1.ZeroOID.String(), []string{hooksPayload}, io.Discard, io.Discard) + return hookManager.UpdateHook(ctx, repo, "ref", gittest.DefaultObjectHash.ZeroOID.String(), gittest.DefaultObjectHash.ZeroOID.String(), []string{hooksPayload}, io.Discard, io.Discard) } postReceiveFunc := func(t *testing.T) error { return hookManager.PostReceiveHook(ctx, repo, nil, []string{hooksPayload}, strings.NewReader("changes"), io.Discard, io.Discard) @@ -126,9 +127,10 @@ func TestHookManager_contextCancellationCancelsVote(t *testing.T) { ctx, cancel := context.WithCancel(testhelper.Context(t)) cfg := testcfg.Build(t) - repo, _ := gittest.CreateRepository(t, ctx, cfg, gittest.CreateRepositoryConfig{ + repo, repoPath := gittest.CreateRepository(t, ctx, cfg, gittest.CreateRepositoryConfig{ SkipCreationViaService: true, }) + commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("master")) mockTxMgr := transaction.MockManager{ VoteFn: func(ctx context.Context, _ txinfo.Transaction, _ voting.Vote, _ voting.Phase) error { @@ -144,6 +146,7 @@ func TestHookManager_contextCancellationCancelsVote(t *testing.T) { hooksPayload, err := git.NewHooksPayload( cfg, repo, + gittest.DefaultObjectHash, &txinfo.Transaction{ ID: 1234, Node: "primary", Primary: true, }, @@ -153,7 +156,7 @@ func TestHookManager_contextCancellationCancelsVote(t *testing.T) { ).Env() require.NoError(t, err) - changes := fmt.Sprintf("%s %s refs/heads/master", strings.Repeat("1", 40), git.ObjectHashSHA1.ZeroOID) + changes := fmt.Sprintf("%s %s refs/heads/master", commitID, gittest.DefaultObjectHash.ZeroOID) cancel() @@ -162,8 +165,8 @@ func TestHookManager_contextCancellationCancelsVote(t *testing.T) { } func TestIsForceDeletionsOnly(t *testing.T) { - anyOID := strings.Repeat("1", 40) - zeroOID := git.ObjectHashSHA1.ZeroOID.String() + anyOID := strings.Repeat("1", gittest.DefaultObjectHash.EncodedLen()) + zeroOID := gittest.DefaultObjectHash.ZeroOID.String() forceDeletion := fmt.Sprintf("%s %s refs/heads/force-delete", zeroOID, zeroOID) forceUpdate := fmt.Sprintf("%s %s refs/heads/force-update", zeroOID, anyOID) @@ -206,7 +209,7 @@ func TestIsForceDeletionsOnly(t *testing.T) { }, } { t.Run(tc.desc, func(t *testing.T) { - actual := isForceDeletionsOnly(strings.NewReader(tc.changes)) + actual := isForceDeletionsOnly(gittest.DefaultObjectHash, strings.NewReader(tc.changes)) require.Equal(t, tc.expected, actual) }) } diff --git a/internal/gitaly/hook/update.go b/internal/gitaly/hook/update.go index 5abcb7760..a4a48fb42 100644 --- a/internal/gitaly/hook/update.go +++ b/internal/gitaly/hook/update.go @@ -36,13 +36,18 @@ func (m *GitLabHookManager) UpdateHook(ctx context.Context, repo *gitalypb.Repos } func (m *GitLabHookManager) updateHook(ctx context.Context, payload git.HooksPayload, repo *gitalypb.Repository, ref, oldValue, newValue string, env []string, stdout, stderr io.Writer) error { + objectHash, err := git.ObjectHashByFormat(payload.ObjectFormat) + if err != nil { + return fmt.Errorf("looking up object hash: %w", err) + } + if ref == "" { return structerr.NewInternal("hook got no reference") } - if err := git.ObjectHashSHA1.ValidateHex(oldValue); err != nil { + if err := objectHash.ValidateHex(oldValue); err != nil { return structerr.NewInternal("hook got invalid old value: %w", err) } - if err := git.ObjectHashSHA1.ValidateHex(newValue); err != nil { + if err := objectHash.ValidateHex(newValue); err != nil { return structerr.NewInternal("hook got invalid new value: %w", err) } if payload.UserDetails == nil { diff --git a/internal/gitaly/hook/update_test.go b/internal/gitaly/hook/update_test.go index d34cb632c..57d7d8c10 100644 --- a/internal/gitaly/hook/update_test.go +++ b/internal/gitaly/hook/update_test.go @@ -29,6 +29,8 @@ func TestUpdate_customHooks(t *testing.T) { repo, repoPath := gittest.CreateRepository(t, ctx, cfg, gittest.CreateRepositoryConfig{ SkipCreationViaService: true, }) + commitA := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("a")) + commitB := gittest.WriteCommit(t, cfg, repoPath, gittest.WithMessage("b")) gitCmdFactory := gittest.NewCommandFactory(t, cfg) locator := config.NewLocator(cfg) @@ -43,12 +45,21 @@ func TestUpdate_customHooks(t *testing.T) { Protocol: "web", } - payload, err := git.NewHooksPayload(cfg, repo, nil, receiveHooksPayload, git.UpdateHook, featureflag.FromContext(ctx)).Env() + payload, err := git.NewHooksPayload( + cfg, + repo, + gittest.DefaultObjectHash, + nil, + receiveHooksPayload, + git.UpdateHook, + featureflag.FromContext(ctx), + ).Env() require.NoError(t, err) primaryPayload, err := git.NewHooksPayload( cfg, repo, + gittest.DefaultObjectHash, &txinfo.Transaction{ ID: 1234, Node: "primary", Primary: true, }, @@ -61,6 +72,7 @@ func TestUpdate_customHooks(t *testing.T) { secondaryPayload, err := git.NewHooksPayload( cfg, repo, + gittest.DefaultObjectHash, &txinfo.Transaction{ ID: 1234, Node: "secondary", Primary: false, }, @@ -70,16 +82,13 @@ func TestUpdate_customHooks(t *testing.T) { ).Env() require.NoError(t, err) - hash1 := strings.Repeat("1", 40) - hash2 := strings.Repeat("2", 40) - testCases := []struct { desc string env []string hook string reference string - oldHash string - newHash string + oldHash git.ObjectID + newHash git.ObjectID expectedErr string expectedStdout string expectedStderr string @@ -88,8 +97,8 @@ func TestUpdate_customHooks(t *testing.T) { desc: "hook receives environment variables", env: []string{payload}, reference: "refs/heads/master", - oldHash: hash1, - newHash: hash2, + oldHash: commitA, + newHash: commitB, hook: "#!/bin/sh\nenv | grep -v -e '^SHLVL=' -e '^_=' | sort\n", expectedStdout: strings.Join(getExpectedEnv(t, ctx, locator, gitCmdFactory, repo), "\n") + "\n", }, @@ -97,17 +106,17 @@ func TestUpdate_customHooks(t *testing.T) { desc: "hook receives arguments", env: []string{payload}, reference: "refs/heads/master", - oldHash: hash1, - newHash: hash2, + oldHash: commitA, + newHash: commitB, hook: "#!/bin/sh\nprintf '%s\\n' \"$@\"\n", - expectedStdout: fmt.Sprintf("refs/heads/master\n%s\n%s\n", hash1, hash2), + expectedStdout: fmt.Sprintf("refs/heads/master\n%s\n%s\n", commitA, commitB), }, { desc: "stdout and stderr are passed through", env: []string{payload}, reference: "refs/heads/master", - oldHash: hash1, - newHash: hash2, + oldHash: commitA, + newHash: commitB, hook: "#!/bin/sh\necho foo >&1\necho bar >&2\n", expectedStdout: "foo\n", expectedStderr: "bar\n", @@ -116,16 +125,16 @@ func TestUpdate_customHooks(t *testing.T) { desc: "standard input is empty", env: []string{payload}, reference: "refs/heads/master", - oldHash: hash1, - newHash: hash2, + oldHash: commitA, + newHash: commitB, hook: "#!/bin/sh\ncat\n", }, { desc: "invalid script causes failure", env: []string{payload}, reference: "refs/heads/master", - oldHash: hash1, - newHash: hash2, + oldHash: commitA, + newHash: commitB, hook: "", expectedErr: "exec format error", }, @@ -133,8 +142,8 @@ func TestUpdate_customHooks(t *testing.T) { desc: "errors are passed through", env: []string{payload}, reference: "refs/heads/master", - oldHash: hash1, - newHash: hash2, + oldHash: commitA, + newHash: commitB, hook: "#!/bin/sh\nexit 123\n", expectedErr: "exit status 123", }, @@ -142,8 +151,8 @@ func TestUpdate_customHooks(t *testing.T) { desc: "errors are passed through with stderr and stdout", env: []string{payload}, reference: "refs/heads/master", - oldHash: hash1, - newHash: hash2, + oldHash: commitA, + newHash: commitB, hook: "#!/bin/sh\necho foo >&1\necho bar >&2\nexit 123\n", expectedStdout: "foo\n", expectedStderr: "bar\n", @@ -153,8 +162,8 @@ func TestUpdate_customHooks(t *testing.T) { desc: "hook is executed on primary", env: []string{primaryPayload}, reference: "refs/heads/master", - oldHash: hash1, - newHash: hash2, + oldHash: commitA, + newHash: commitB, hook: "#!/bin/sh\necho foo\n", expectedStdout: "foo\n", }, @@ -162,29 +171,29 @@ func TestUpdate_customHooks(t *testing.T) { desc: "hook is not executed on secondary", env: []string{secondaryPayload}, reference: "refs/heads/master", - oldHash: hash1, - newHash: hash2, + oldHash: commitA, + newHash: commitB, hook: "#!/bin/sh\necho foo\n", }, { desc: "hook fails with missing reference", env: []string{payload}, - oldHash: hash1, - newHash: hash2, + oldHash: commitA, + newHash: commitB, expectedErr: "hook got no reference", }, { desc: "hook fails with missing old value", env: []string{payload}, reference: "refs/heads/master", - newHash: hash2, + newHash: commitB, expectedErr: "hook got invalid old value", }, { desc: "hook fails with missing new value", env: []string{payload}, reference: "refs/heads/master", - oldHash: hash1, + oldHash: commitA, expectedErr: "hook got invalid new value", }, } @@ -194,7 +203,7 @@ func TestUpdate_customHooks(t *testing.T) { gittest.WriteCustomHook(t, repoPath, "update", []byte(tc.hook)) var stdout, stderr bytes.Buffer - err = hookManager.UpdateHook(ctx, repo, tc.reference, tc.oldHash, tc.newHash, tc.env, &stdout, &stderr) + err = hookManager.UpdateHook(ctx, repo, tc.reference, tc.oldHash.String(), tc.newHash.String(), tc.env, &stdout, &stderr) if tc.expectedErr != "" { require.Contains(t, err.Error(), tc.expectedErr) @@ -238,7 +247,11 @@ func TestUpdate_quarantine(t *testing.T) { repoProto: false, } { t.Run(fmt.Sprintf("quarantined: %v", isQuarantined), func(t *testing.T) { - env, err := git.NewHooksPayload(cfg, repo, nil, + env, err := git.NewHooksPayload( + cfg, + repo, + gittest.DefaultObjectHash, + nil, &git.UserDetails{ UserID: "1234", Username: "user", @@ -251,7 +264,7 @@ func TestUpdate_quarantine(t *testing.T) { var stdout, stderr bytes.Buffer require.NoError(t, hookManager.UpdateHook(ctx, repo, "refs/heads/master", - git.ObjectHashSHA1.ZeroOID.String(), git.ObjectHashSHA1.ZeroOID.String(), []string{env}, &stdout, &stderr)) + gittest.DefaultObjectHash.ZeroOID.String(), gittest.DefaultObjectHash.ZeroOID.String(), []string{env}, &stdout, &stderr)) if isQuarantined { require.Equal(t, "allyourbasearebelongtous", stdout.String()) diff --git a/internal/gitaly/linguist/linguist.go b/internal/gitaly/linguist/linguist.go index 4b227d427..3fa7b5d4b 100644 --- a/internal/gitaly/linguist/linguist.go +++ b/internal/gitaly/linguist/linguist.go @@ -101,7 +101,7 @@ func (inst *Instance) Stats(ctx context.Context, commitID string) (ByteCountPerL // Stats are cached for one commit, so get the git-diff-tree(1) // between that commit and the one we're calculating stats for. - hash, err := git.DetectObjectHash(ctx, inst.repo) + hash, err := inst.repo.ObjectHash(ctx) if err != nil { return nil, fmt.Errorf("linguist: detect object hash: %w", err) } diff --git a/internal/gitaly/service/hook/post_receive_test.go b/internal/gitaly/service/hook/post_receive_test.go index 2bea73a50..14fe64a2e 100644 --- a/internal/gitaly/service/hook/post_receive_test.go +++ b/internal/gitaly/service/hook/post_receive_test.go @@ -107,6 +107,7 @@ func TestHooksMissingStdin(t *testing.T) { hooksPayload, err := git.NewHooksPayload( cfg, repo, + gittest.DefaultObjectHash, &txinfo.Transaction{ ID: 1234, Node: "node-1", @@ -244,6 +245,7 @@ To create a merge request for okay, visit: hooksPayload, err := git.NewHooksPayload( cfg, repo, + gittest.DefaultObjectHash, nil, &git.UserDetails{ UserID: "key_id", diff --git a/internal/gitaly/service/hook/pre_receive_test.go b/internal/gitaly/service/hook/pre_receive_test.go index 14a0289cc..a5754c854 100644 --- a/internal/gitaly/service/hook/pre_receive_test.go +++ b/internal/gitaly/service/hook/pre_receive_test.go @@ -150,6 +150,7 @@ func TestPreReceiveHook_GitlabAPIAccess(t *testing.T) { hooksPayload, err := git.NewHooksPayload( cfg, repo, + gittest.DefaultObjectHash, nil, &git.UserDetails{ UserID: glID, @@ -272,6 +273,7 @@ func TestPreReceive_APIErrors(t *testing.T) { hooksPayload, err := git.NewHooksPayload( cfg, repo, + gittest.DefaultObjectHash, nil, &git.UserDetails{ UserID: "key-123", @@ -347,6 +349,7 @@ exit %d hooksPayload, err := git.NewHooksPayload( cfg, repo, + gittest.DefaultObjectHash, nil, &git.UserDetails{ UserID: "key-123", @@ -476,6 +479,7 @@ func TestPreReceiveHook_Primary(t *testing.T) { hooksPayload, err := git.NewHooksPayload( cfg, testRepo, + gittest.DefaultObjectHash, &txinfo.Transaction{ ID: 1234, Node: "node-1", diff --git a/internal/gitaly/service/hook/reference_transaction_test.go b/internal/gitaly/service/hook/reference_transaction_test.go index 3f54ccb87..33e6cd778 100644 --- a/internal/gitaly/service/hook/reference_transaction_test.go +++ b/internal/gitaly/service/hook/reference_transaction_test.go @@ -168,6 +168,7 @@ func TestReferenceTransactionHook(t *testing.T) { hooksPayload, err := git.NewHooksPayload( cfg, repo, + gittest.DefaultObjectHash, &txinfo.Transaction{ BackchannelID: backchannelID, ID: 1234, diff --git a/internal/gitaly/service/hook/update_test.go b/internal/gitaly/service/hook/update_test.go index 7d50c8970..71b0cbec0 100644 --- a/internal/gitaly/service/hook/update_test.go +++ b/internal/gitaly/service/hook/update_test.go @@ -43,6 +43,7 @@ func TestUpdate_CustomHooks(t *testing.T) { hooksPayload, err := git.NewHooksPayload( cfg, repo, + gittest.DefaultObjectHash, nil, &git.UserDetails{ UserID: "key-123", diff --git a/internal/gitaly/service/remote/find_remote_root_ref.go b/internal/gitaly/service/remote/find_remote_root_ref.go index 990dc63b3..40fdb2e32 100644 --- a/internal/gitaly/service/remote/find_remote_root_ref.go +++ b/internal/gitaly/service/remote/find_remote_root_ref.go @@ -51,7 +51,7 @@ func (s *server) findRemoteRootRefCmd(ctx context.Context, request *gitalypb.Fin Action: "show", Args: []string{"inmemory"}, }, - git.WithRefTxHook(request.Repository), + git.WithDisabledHooks(), git.WithConfigEnv(config...), ) } diff --git a/internal/gitaly/service/repository/create_repository_test.go b/internal/gitaly/service/repository/create_repository_test.go index 7602c759a..126de1e57 100644 --- a/internal/gitaly/service/repository/create_repository_test.go +++ b/internal/gitaly/service/repository/create_repository_test.go @@ -10,7 +10,6 @@ import ( "github.com/stretchr/testify/require" "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/localrepo" "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config/auth" "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction" @@ -135,6 +134,7 @@ func TestCreateRepository_withObjectFormat(t *testing.T) { cfg, client := setupRepositoryServiceWithoutRepo(t) ctx := testhelper.Context(t) + gitCmdFactory := gittest.NewCommandFactory(t, cfg) for _, tc := range []struct { desc string @@ -186,8 +186,7 @@ func TestCreateRepository_withObjectFormat(t *testing.T) { // If the repository was created we can check whether the object format of // the created repository matches our expectations. - repo := localrepo.NewTestRepo(t, cfg, repoProto) - objectHash, err := git.DetectObjectHash(ctx, repo) + objectHash, err := git.DetectObjectHash(ctx, gitCmdFactory, gittest.RewrittenRepository(t, ctx, cfg, repoProto)) require.NoError(t, err) require.Equal(t, tc.expectedObjectHash.Format, objectHash.Format) }) diff --git a/internal/gitaly/service/repository/fetch_bundle.go b/internal/gitaly/service/repository/fetch_bundle.go index 9d53c82ea..bf0dd7a6d 100644 --- a/internal/gitaly/service/repository/fetch_bundle.go +++ b/internal/gitaly/service/repository/fetch_bundle.go @@ -42,7 +42,14 @@ func (s *server) FetchBundle(stream gitalypb.RepositoryService_FetchBundleServer }) ctx := stream.Context() + repo := s.localrepo(firstRequest.GetRepository()) + + // Verify that the repository actually exists. + if _, err := repo.Path(); err != nil { + return err + } + updateHead := firstRequest.GetUpdateHead() tmpDir, err := tempdir.New(ctx, repo.GetStorageName(), s.locator) diff --git a/internal/gitaly/service/smarthttp/receive_pack_test.go b/internal/gitaly/service/smarthttp/receive_pack_test.go index 4276116d4..c10fdfa81 100644 --- a/internal/gitaly/service/smarthttp/receive_pack_test.go +++ b/internal/gitaly/service/smarthttp/receive_pack_test.go @@ -120,6 +120,7 @@ func TestPostReceivePack_successful(t *testing.T) { payload.FeatureFlagsWithValue = nil require.Equal(t, git.HooksPayload{ + ObjectFormat: gittest.DefaultObjectHash.Format, RuntimeDir: cfg.RuntimeDir, InternalSocket: cfg.InternalSocketPath(), InternalSocketToken: cfg.Auth.Token, diff --git a/internal/gitaly/service/ssh/receive_pack_test.go b/internal/gitaly/service/ssh/receive_pack_test.go index 8d3e7fbbe..56b836e4a 100644 --- a/internal/gitaly/service/ssh/receive_pack_test.go +++ b/internal/gitaly/service/ssh/receive_pack_test.go @@ -1,5 +1,3 @@ -//go:build !gitaly_test_sha256 - package ssh import ( @@ -197,6 +195,7 @@ func TestReceivePack_success(t *testing.T) { payload.FeatureFlagsWithValue = nil require.Equal(t, git.HooksPayload{ + ObjectFormat: gittest.DefaultObjectHash.Format, RuntimeDir: cfg.RuntimeDir, InternalSocket: cfg.InternalSocketPath(), InternalSocketToken: cfg.Auth.Token, @@ -626,9 +625,9 @@ func TestReceivePack_transactional(t *testing.T) { for i, command := range tc.commands { // Only the first pktline contains capabilities. if i == 0 { - gittest.WritePktlineString(t, &request, fmt.Sprintf("%s %s %s\000 %s", - command.oldOID, command.newOID, command.ref, - "report-status side-band-64k agent=git/2.12.0")) + gittest.WritePktlinef(t, &request, "%s %s %s\000 report-status side-band-64k object-format=%s agent=git/2.12.0", + command.oldOID, command.newOID, command.ref, gittest.DefaultObjectHash.Format, + ) } else { gittest.WritePktlineString(t, &request, fmt.Sprintf("%s %s %s", command.oldOID, command.newOID, command.ref)) |