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>2023-04-06 08:07:56 +0300
committerPatrick Steinhardt <psteinhardt@gitlab.com>2023-04-06 08:07:56 +0300
commitc31b9fed97bb01a1790496386ceab8e31e76b1d8 (patch)
tree71785e0af340e09df89bc4a57eac9915ab76ecdd
parentf1702db8051171a04fc4f7ea3da41c40fcce8ab6 (diff)
parent6e29ccf1eaad4312980a68bd30fb9d5395d94837 (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>
-rw-r--r--cmd/gitaly-hooks/hooks_test.go38
-rw-r--r--internal/git/hooks_options.go58
-rw-r--r--internal/git/hooks_payload.go5
-rw-r--r--internal/git/hooks_payload_test.go51
-rw-r--r--internal/git/housekeeping/worktrees_test.go22
-rw-r--r--internal/git/localrepo/repo.go2
-rw-r--r--internal/git/object_id.go12
-rw-r--r--internal/git/object_id_test.go7
-rw-r--r--internal/git/updateref/update_with_hooks.go4
-rw-r--r--internal/git/updateref/update_with_hooks_test.go15
-rw-r--r--internal/gitaly/hook/postreceive_test.go35
-rw-r--r--internal/gitaly/hook/prereceive_test.go35
-rw-r--r--internal/gitaly/hook/referencetransaction.go17
-rw-r--r--internal/gitaly/hook/transactions_test.go15
-rw-r--r--internal/gitaly/hook/update.go9
-rw-r--r--internal/gitaly/hook/update_test.go77
-rw-r--r--internal/gitaly/linguist/linguist.go2
-rw-r--r--internal/gitaly/service/hook/post_receive_test.go2
-rw-r--r--internal/gitaly/service/hook/pre_receive_test.go4
-rw-r--r--internal/gitaly/service/hook/reference_transaction_test.go1
-rw-r--r--internal/gitaly/service/hook/update_test.go1
-rw-r--r--internal/gitaly/service/remote/find_remote_root_ref.go2
-rw-r--r--internal/gitaly/service/repository/create_repository_test.go5
-rw-r--r--internal/gitaly/service/repository/fetch_bundle.go7
-rw-r--r--internal/gitaly/service/smarthttp/receive_pack_test.go1
-rw-r--r--internal/gitaly/service/ssh/receive_pack_test.go9
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))