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:
authorJames Fargher <proglottis@gmail.com>2022-05-26 08:35:49 +0300
committerJames Fargher <proglottis@gmail.com>2022-05-26 08:35:49 +0300
commita6c5964bb455f77a0c79898f0b99c4c7df3aee3a (patch)
tree2d93b502416ba19a3ba02b56f1349c4a7bb25c61
parentac989862106589558866e01fc5d77ad7326c99e4 (diff)
parent0773ed8d10cf7c0c951350d9647839b0d1b561cc (diff)
Merge branch 'pks-gitaly-introduce-ignore-gitconfig' into 'master'
gitaly/config: Add option to ignore gitconfig files Closes #4242 See merge request gitlab-org/gitaly!4588
-rw-r--r--.gitlab-ci.yml11
-rw-r--r--config.toml.example8
-rw-r--r--internal/git/command_factory.go8
-rw-r--r--internal/git/command_factory_cgroup_test.go5
-rw-r--r--internal/git/command_factory_test.go32
-rw-r--r--internal/git/command_options_test.go27
-rw-r--r--internal/git/gittest/commit_test.go207
-rw-r--r--internal/git/gittest/testhelper_test.go1
-rw-r--r--internal/gitaly/config/config.go1
-rw-r--r--internal/testhelper/configure.go27
-rw-r--r--internal/testhelper/testcfg/gitaly_builder.go3
-rw-r--r--internal/testhelper/testdata/home/.config/git/config5
-rw-r--r--internal/testhelper/testdata/home/.gitconfig5
13 files changed, 201 insertions, 139 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 6809a65df..c4c75e7e8 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -20,6 +20,9 @@ variables:
PGBOUNCER_VERSION: "1.16.1"
BUNDLE_PATH: "${CI_PROJECT_DIR}/.ruby"
GOPATH: "${CI_PROJECT_DIR}/.go"
+ # Run tests with an intercepted home directory so that we detect cases where
+ # Gitaly picks up the gitconfig even though it ought not to.
+ GITALY_TESTING_INTERCEPT_HOME: "YesPlease"
include:
- template: Workflows/MergeRequest-Pipelines.gitlab-ci.yml
@@ -160,7 +163,7 @@ test:
# But the actual tests should run unprivileged. This assures that we pay
# proper attention to permission bits and that we don't modify the source
# directory.
- - setpriv --reuid=9999 --regid=9999 --clear-groups --no-new-privs env HOME=/dev/null make ${TARGET} SKIP_RSPEC_BUILD=YesPlease $(test "${GIT_VERSION}" = default && echo WITH_BUNDLED_GIT=YesPlease)
+ - setpriv --reuid=9999 --regid=9999 --clear-groups --no-new-privs make ${TARGET} SKIP_RSPEC_BUILD=YesPlease $(test "${GIT_VERSION}" = default && echo WITH_BUNDLED_GIT=YesPlease)
parallel:
matrix:
# The following jobs all test with our default Git version, which is
@@ -185,7 +188,7 @@ test:coverage:
script:
# We need to explicitly build all prerequisites so that we can run tests unprivileged.
- make -j$(nproc) build prepare-tests $(pwd)/_build/tools/gocover-cobertura
- - setpriv --reuid=9999 --regid=9999 --clear-groups --no-new-privs env HOME=/dev/null make cover SKIP_RSPEC_BUILD=YesPlease
+ - setpriv --reuid=9999 --regid=9999 --clear-groups --no-new-privs make cover SKIP_RSPEC_BUILD=YesPlease
artifacts:
reports:
coverage_report:
@@ -227,14 +230,14 @@ test:pgbouncer:
script:
# We need to explicitly build all prerequisites so that we can run tests unprivileged.
- make -j$(nproc) build prepare-tests
- - setpriv --reuid=9999 --regid=9999 --clear-groups --no-new-privs env HOME=/dev/null make test-with-praefect SKIP_RSPEC_BUILD=YesPlease
+ - setpriv --reuid=9999 --regid=9999 --clear-groups --no-new-privs make test-with-praefect SKIP_RSPEC_BUILD=YesPlease
test:nightly:
<<: *test_definition
script:
- go version
- make -j$(nproc) build prepare-tests
- - setpriv --reuid=9999 --regid=9999 --clear-groups --no-new-privs env HOME=/dev/null make ${TARGET} SKIP_RSPEC_BUILD=YesPlease
+ - setpriv --reuid=9999 --regid=9999 --clear-groups --no-new-privs make ${TARGET} SKIP_RSPEC_BUILD=YesPlease
parallel:
matrix:
- GIT_VERSION: [ "master", "next" ]
diff --git a/config.toml.example b/config.toml.example
index ae1b54e1a..9a4753e1e 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -37,6 +37,14 @@ bin_dir = "/home/git/gitaly/_build/bin"
# [git]
# bin_path = "/usr/bin/git"
# catfile_cache_size = 100
+#
+# # Set this setting to `true` to start ignoring gitconfig files installed in
+# # the system. This includes both system-level (e.g. '/etc/gitconffig') and
+# # global-level (e.g. `$HOME/.gitconfig`) files. This setting will become the
+# # default with v16.0. If you intend to override Git configuration you can do
+# # so via `[[git.config]]`. The default value is `false`.
+# ignore_gitconfig = false
+#
# [[git.config]]
# key = fetch.fsckObjects
# value = true
diff --git a/internal/git/command_factory.go b/internal/git/command_factory.go
index 17b2a85de..2f2ded567 100644
--- a/internal/git/command_factory.go
+++ b/internal/git/command_factory.go
@@ -7,7 +7,6 @@ import (
"os"
"os/exec"
"path/filepath"
- "strings"
"sync"
"github.com/prometheus/client_golang/prometheus"
@@ -157,14 +156,11 @@ func setupGitExecutionEnvironments(cfg config.Cfg, factoryCfg execCommandFactory
}
// Prevent the environment from affecting git calls by ignoring the configuration files.
- //
// This should be done always but we have to wait until 15.0 due to backwards compatibility
- // concerns. To fix tests ahead to 15.0, we ignore the global configuration when the package
- // has been built under tests. `go test` uses a `.test` suffix on the test binaries. We use
- // that to check whether to ignore the globals or not.
+ // concerns.
//
// See https://gitlab.com/gitlab-org/gitaly/-/issues/3617.
- if strings.HasSuffix(os.Args[0], ".test") {
+ if cfg.Git.IgnoreGitconfig {
sharedEnvironment = append(sharedEnvironment,
"GIT_CONFIG_GLOBAL=/dev/null",
"GIT_CONFIG_SYSTEM=/dev/null",
diff --git a/internal/git/command_factory_cgroup_test.go b/internal/git/command_factory_cgroup_test.go
index 0ef61fcd3..69c3126bf 100644
--- a/internal/git/command_factory_cgroup_test.go
+++ b/internal/git/command_factory_cgroup_test.go
@@ -40,7 +40,11 @@ func TestNewCommandAddsToCgroup(t *testing.T) {
root := testhelper.TempDir(t)
cfg := config.Cfg{
+ BinDir: filepath.Join(root, "bin.d"),
SocketPath: "/path/to/socket",
+ Git: config.Git{
+ IgnoreGitconfig: true,
+ },
Cgroups: cgroups.Config{
Repositories: cgroups.Repositories{
Count: 1,
@@ -50,7 +54,6 @@ func TestNewCommandAddsToCgroup(t *testing.T) {
Name: "storage-1",
Path: root,
}},
- BinDir: filepath.Join(root, "bin.d"),
}
require.NoError(t, os.MkdirAll(cfg.BinDir, 0o755))
diff --git a/internal/git/command_factory_test.go b/internal/git/command_factory_test.go
index 3c3aec4fb..d709dd130 100644
--- a/internal/git/command_factory_test.go
+++ b/internal/git/command_factory_test.go
@@ -165,9 +165,27 @@ func TestCommandFactory_ExecutionEnvironment(t *testing.T) {
require.Equal(t, expectedExecEnv.EnvironmentVariables, actualExecEnv.EnvironmentVariables)
}
+ t.Run("set in config without ignored gitconfig", func(t *testing.T) {
+ assertExecEnv(t, config.Cfg{
+ Git: config.Git{
+ BinPath: "/path/to/myGit",
+ IgnoreGitconfig: false,
+ },
+ }, git.ExecutionEnvironment{
+ BinaryPath: "/path/to/myGit",
+ EnvironmentVariables: []string{
+ "LANG=en_US.UTF-8",
+ "GIT_TERMINAL_PROMPT=0",
+ },
+ })
+ })
+
t.Run("set in config", func(t *testing.T) {
assertExecEnv(t, config.Cfg{
- Git: config.Git{BinPath: "/path/to/myGit"},
+ Git: config.Git{
+ BinPath: "/path/to/myGit",
+ IgnoreGitconfig: true,
+ },
}, git.ExecutionEnvironment{
BinaryPath: "/path/to/myGit",
EnvironmentVariables: []string{
@@ -183,7 +201,11 @@ func TestCommandFactory_ExecutionEnvironment(t *testing.T) {
t.Run("set using GITALY_TESTING_GIT_BINARY", func(t *testing.T) {
testhelper.ModifyEnvironment(t, "GITALY_TESTING_GIT_BINARY", "/path/to/env_git")
- assertExecEnv(t, config.Cfg{Git: config.Git{}}, git.ExecutionEnvironment{
+ assertExecEnv(t, config.Cfg{
+ Git: config.Git{
+ IgnoreGitconfig: true,
+ },
+ }, git.ExecutionEnvironment{
BinaryPath: "/path/to/env_git",
EnvironmentVariables: []string{
"LANG=en_US.UTF-8",
@@ -283,7 +305,11 @@ func TestCommandFactory_ExecutionEnvironment(t *testing.T) {
resolvedPath, err := exec.LookPath("git")
require.NoError(t, err)
- assertExecEnv(t, config.Cfg{}, git.ExecutionEnvironment{
+ assertExecEnv(t, config.Cfg{
+ Git: config.Git{
+ IgnoreGitconfig: true,
+ },
+ }, git.ExecutionEnvironment{
BinaryPath: resolvedPath,
EnvironmentVariables: []string{
"LANG=en_US.UTF-8",
diff --git a/internal/git/command_options_test.go b/internal/git/command_options_test.go
index 884eeb35d..88f41d2d0 100644
--- a/internal/git/command_options_test.go
+++ b/internal/git/command_options_test.go
@@ -203,7 +203,12 @@ func TestGlobalOption(t *testing.T) {
}
func TestWithConfig(t *testing.T) {
- cfg := config.Cfg{BinDir: testhelper.TempDir(t)}
+ cfg := config.Cfg{
+ BinDir: testhelper.TempDir(t),
+ Git: config.Git{
+ IgnoreGitconfig: true,
+ },
+ }
ctx := testhelper.Context(t)
@@ -274,11 +279,16 @@ func TestWithConfig(t *testing.T) {
}
func TestExecCommandFactoryGitalyConfigOverrides(t *testing.T) {
- cfg := config.Cfg{BinDir: testhelper.TempDir(t)}
-
- cfg.Git.Config = []config.GitConfig{
- {Key: "foo.bar", Value: "from-gitaly-config"},
+ cfg := config.Cfg{
+ BinDir: testhelper.TempDir(t),
+ Git: config.Git{
+ Config: []config.GitConfig{
+ {Key: "foo.bar", Value: "from-gitaly-config"},
+ },
+ IgnoreGitconfig: true,
+ },
}
+
ctx := testhelper.Context(t)
gitCmdFactory := newCommandFactory(t, cfg, WithSkipHooks())
@@ -299,7 +309,12 @@ func TestExecCommandFactoryGitalyConfigOverrides(t *testing.T) {
}
func TestWithConfigEnv(t *testing.T) {
- cfg := config.Cfg{BinDir: testhelper.TempDir(t)}
+ cfg := config.Cfg{
+ BinDir: testhelper.TempDir(t),
+ Git: config.Git{
+ IgnoreGitconfig: true,
+ },
+ }
ctx := testhelper.Context(t)
diff --git a/internal/git/gittest/commit_test.go b/internal/git/gittest/commit_test.go
index dd9da2bc6..452fa8eed 100644
--- a/internal/git/gittest/commit_test.go
+++ b/internal/git/gittest/commit_test.go
@@ -1,35 +1,18 @@
-package gittest_test
+package gittest
import (
+ "strings"
"testing"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitaly/v15/internal/git"
- "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile"
- "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/testhelper"
- "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg"
- "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"
+ "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text"
)
func TestWriteCommit(t *testing.T) {
- cfg, repoProto, repoPath := testcfg.BuildWithRepo(t)
+ cfg, _, repoPath := setup(t)
- repo := localrepo.NewTestRepo(t, cfg, repoProto)
- ctx := testhelper.Context(t)
-
- catfileCache := catfile.NewCache(cfg)
- defer catfileCache.Stop()
-
- objectReader, cancel, err := catfileCache.ObjectReader(ctx, repo)
- require.NoError(t, err)
- defer cancel()
-
- defaultCommitter := &gitalypb.CommitAuthor{
- Name: []byte("Scrooge McDuck"),
- Email: []byte("scrooge@mcduck.com"),
- }
+ defaultCommitter := "Scrooge McDuck <scrooge@mcduck.com> 1572776879 +0100"
defaultParentID := "1a0b36b3cdad1d2ee32457c102a8c0b7056fa863"
revisions := map[git.Revision]git.ObjectID{
@@ -37,115 +20,105 @@ func TestWriteCommit(t *testing.T) {
"refs/heads/master~": "",
}
for revision := range revisions {
- oid, err := repo.ResolveRevision(ctx, revision)
- require.NoError(t, err)
- revisions[revision] = oid
+ oid := Exec(t, cfg, "-C", repoPath, "rev-parse", revision.String())
+ revisions[revision] = git.ObjectID(text.ChompBytes(oid))
}
for _, tc := range []struct {
desc string
- opts []gittest.WriteCommitOption
- expectedCommit *gitalypb.GitCommit
- expectedTreeEntries []gittest.TreeEntry
+ opts []WriteCommitOption
+ expectedCommit string
+ expectedTreeEntries []TreeEntry
expectedRevUpdate git.Revision
}{
{
desc: "no options",
- expectedCommit: &gitalypb.GitCommit{
- Author: defaultCommitter,
- Committer: defaultCommitter,
- Subject: []byte("message"),
- Body: []byte("message"),
- Id: "cab056fb7bfc5a4d024c2c5b9b445b80f212fdcd",
- ParentIds: []string{
- defaultParentID,
- },
- },
+ expectedCommit: strings.Join([]string{
+ "tree 91639b9835ff541f312fd2735f639a50bf35d472",
+ "parent " + defaultParentID,
+ "author " + defaultCommitter,
+ "committer " + defaultCommitter,
+ "",
+ "message",
+ }, "\n"),
},
{
desc: "with commit message",
- opts: []gittest.WriteCommitOption{
- gittest.WithMessage("my custom message\n\nfoobar\n"),
- },
- expectedCommit: &gitalypb.GitCommit{
- Author: defaultCommitter,
- Committer: defaultCommitter,
- Subject: []byte("my custom message"),
- Body: []byte("my custom message\n\nfoobar\n"),
- Id: "7b7e8876f7df27ab99e46678acbf9ae3d29264ba",
- ParentIds: []string{
- defaultParentID,
- },
+ opts: []WriteCommitOption{
+ WithMessage("my custom message\n\nfoobar\n"),
},
+ expectedCommit: strings.Join([]string{
+ "tree 91639b9835ff541f312fd2735f639a50bf35d472",
+ "parent " + defaultParentID,
+ "author " + defaultCommitter,
+ "committer " + defaultCommitter,
+ "",
+ "my custom message",
+ "",
+ "foobar",
+ }, "\n"),
},
{
desc: "with no parents",
- opts: []gittest.WriteCommitOption{
- gittest.WithParents(),
- },
- expectedCommit: &gitalypb.GitCommit{
- Author: defaultCommitter,
- Committer: defaultCommitter,
- Subject: []byte("message"),
- Body: []byte("message"),
- Id: "549090fbeacc6607bc70648d3ba554c355e670c5",
- ParentIds: nil,
+ opts: []WriteCommitOption{
+ WithParents(),
},
+ expectedCommit: strings.Join([]string{
+ "tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904",
+ "author " + defaultCommitter,
+ "committer " + defaultCommitter,
+ "",
+ "message",
+ }, "\n"),
},
{
desc: "with multiple parents",
- opts: []gittest.WriteCommitOption{
- gittest.WithParents(revisions["refs/heads/master"], revisions["refs/heads/master~"]),
- },
- expectedCommit: &gitalypb.GitCommit{
- Author: defaultCommitter,
- Committer: defaultCommitter,
- Subject: []byte("message"),
- Body: []byte("message"),
- Id: "650084693e5ca9c0b05a21fc5ac21ad1805c758b",
- ParentIds: []string{
- revisions["refs/heads/master"].String(),
- revisions["refs/heads/master~"].String(),
- },
+ opts: []WriteCommitOption{
+ WithParents(revisions["refs/heads/master"], revisions["refs/heads/master~"]),
},
+ expectedCommit: strings.Join([]string{
+ "tree 07f8147e8e73aab6c935c296e8cdc5194dee729b",
+ "parent 1e292f8fedd741b75372e19097c76d327140c312",
+ "parent 7975be0116940bf2ad4321f79d02a55c5f7779aa",
+ "author " + defaultCommitter,
+ "committer " + defaultCommitter,
+ "",
+ "message",
+ }, "\n"),
},
{
desc: "with branch",
- opts: []gittest.WriteCommitOption{
- gittest.WithBranch("foo"),
- },
- expectedCommit: &gitalypb.GitCommit{
- Author: defaultCommitter,
- Committer: defaultCommitter,
- Subject: []byte("message"),
- Body: []byte("message"),
- Id: "cab056fb7bfc5a4d024c2c5b9b445b80f212fdcd",
- ParentIds: []string{
- defaultParentID,
- },
+ opts: []WriteCommitOption{
+ WithBranch("foo"),
},
+ expectedCommit: strings.Join([]string{
+ "tree 91639b9835ff541f312fd2735f639a50bf35d472",
+ "parent " + defaultParentID,
+ "author " + defaultCommitter,
+ "committer " + defaultCommitter,
+ "",
+ "message",
+ }, "\n"),
expectedRevUpdate: "refs/heads/foo",
},
{
desc: "with tree entry",
- opts: []gittest.WriteCommitOption{
- gittest.WithTreeEntries(gittest.TreeEntry{
+ opts: []WriteCommitOption{
+ WithTreeEntries(TreeEntry{
Content: "foobar",
Mode: "100644",
Path: "file",
}),
},
- expectedCommit: &gitalypb.GitCommit{
- Author: defaultCommitter,
- Committer: defaultCommitter,
- Subject: []byte("message"),
- Body: []byte("message"),
- Id: "12da4907ed3331f4991ba6817317a3a90801288e",
- ParentIds: []string{
- defaultParentID,
- },
- },
- expectedTreeEntries: []gittest.TreeEntry{
+ expectedCommit: strings.Join([]string{
+ "tree 0a2fde9f84d2642adbfdf7c37560005e2532fd31",
+ "parent " + defaultParentID,
+ "author " + defaultCommitter,
+ "committer " + defaultCommitter,
+ "",
+ "message",
+ }, "\n"),
+ expectedTreeEntries: []TreeEntry{
{
Content: "foobar",
Mode: "100644",
@@ -155,8 +128,8 @@ func TestWriteCommit(t *testing.T) {
},
{
desc: "with tree",
- opts: []gittest.WriteCommitOption{
- gittest.WithTree(gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ opts: []WriteCommitOption{
+ WithTree(WriteTree(t, cfg, repoPath, []TreeEntry{
{
Content: "something",
Mode: "100644",
@@ -164,17 +137,15 @@ func TestWriteCommit(t *testing.T) {
},
})),
},
- expectedCommit: &gitalypb.GitCommit{
- Author: defaultCommitter,
- Committer: defaultCommitter,
- Subject: []byte("message"),
- Body: []byte("message"),
- Id: "fc157fcabd57d95752ade820a791899f9891b984",
- ParentIds: []string{
- defaultParentID,
- },
- },
- expectedTreeEntries: []gittest.TreeEntry{
+ expectedCommit: strings.Join([]string{
+ "tree 52193934b12dbe23bf1d663802d77a04792a79ac",
+ "parent " + defaultParentID,
+ "author " + defaultCommitter,
+ "committer " + defaultCommitter,
+ "",
+ "message",
+ }, "\n"),
+ expectedTreeEntries: []TreeEntry{
{
Content: "something",
Mode: "100644",
@@ -184,21 +155,19 @@ func TestWriteCommit(t *testing.T) {
},
} {
t.Run(tc.desc, func(t *testing.T) {
- oid := gittest.WriteCommit(t, cfg, repoPath, tc.opts...)
+ oid := WriteCommit(t, cfg, repoPath, tc.opts...)
- commit, err := catfile.GetCommit(ctx, objectReader, oid.Revision())
- require.NoError(t, err)
+ commit := Exec(t, cfg, "-C", repoPath, "cat-file", "-p", oid.String())
- gittest.CommitEqual(t, tc.expectedCommit, commit)
+ require.Equal(t, tc.expectedCommit, text.ChompBytes(commit))
if tc.expectedTreeEntries != nil {
- gittest.RequireTree(t, cfg, repoPath, oid.String(), tc.expectedTreeEntries)
+ RequireTree(t, cfg, repoPath, oid.String(), tc.expectedTreeEntries)
}
if tc.expectedRevUpdate != "" {
- updatedOID, err := repo.ResolveRevision(ctx, tc.expectedRevUpdate)
- require.NoError(t, err)
- require.Equal(t, oid, updatedOID)
+ updatedOID := Exec(t, cfg, "-C", repoPath, "rev-parse", tc.expectedRevUpdate.String())
+ require.Equal(t, oid, git.ObjectID(text.ChompBytes(updatedOID)))
}
})
}
diff --git a/internal/git/gittest/testhelper_test.go b/internal/git/gittest/testhelper_test.go
index 0dc03b44b..2eebc49be 100644
--- a/internal/git/gittest/testhelper_test.go
+++ b/internal/git/gittest/testhelper_test.go
@@ -26,6 +26,7 @@ func setup(t testing.TB) (config.Cfg, *gitalypb.Repository, string) {
var cfg config.Cfg
cfg.SocketPath = "it is a stub to bypass Validate method"
+ cfg.Git.IgnoreGitconfig = true
cfg.Storages = []config.Storage{
{
diff --git a/internal/gitaly/config/config.go b/internal/gitaly/config/config.go
index 23fd6d7fa..a7b70842c 100644
--- a/internal/gitaly/config/config.go
+++ b/internal/gitaly/config/config.go
@@ -107,6 +107,7 @@ type Git struct {
BinPath string `toml:"bin_path"`
CatfileCacheSize int `toml:"catfile_cache_size"`
Config []GitConfig `toml:"config"`
+ IgnoreGitconfig bool `toml:"ignore_gitconfig"`
}
// GitConfig contains a key-value pair which is to be passed to git as configuration.
diff --git a/internal/testhelper/configure.go b/internal/testhelper/configure.go
index 77c217a4d..ad5df7ad9 100644
--- a/internal/testhelper/configure.go
+++ b/internal/testhelper/configure.go
@@ -5,6 +5,7 @@ import (
"fmt"
"os"
"path/filepath"
+ "runtime"
"testing"
log "github.com/sirupsen/logrus"
@@ -101,6 +102,32 @@ func configure() (_ func(), returnedErr error) {
}
}
+ // We need to make sure that we're gitconfig-clean: neither Git nor libgit2 should pick up
+ // gitconfig files from anywhere but the repository itself in case they're configured to
+ // ignore them. We set that configuration by default in our tests to have a known-good
+ // environment.
+ //
+ // In order to verify that this really works as expected we optionally intercept the user's
+ // HOME with a custom home directory that contains gitconfig files that cannot be parsed. So
+ // if these were picked up, we'd see errors and thus know that something's going on. We
+ // need to make this opt-in though given that some users require HOME to be set, e.g. for
+ // Bundler. Our CI does run with this setting enabled though.
+ if len(os.Getenv("GITALY_TESTING_INTERCEPT_HOME")) > 0 {
+ _, currentFile, _, ok := runtime.Caller(0)
+ if !ok {
+ return nil, fmt.Errorf("cannot compute intercepted home location")
+ }
+
+ homeDir := filepath.Join(filepath.Dir(currentFile), "testdata", "home")
+ if _, err := os.Stat(homeDir); err != nil {
+ return nil, fmt.Errorf("statting intercepted home location: %w", err)
+ }
+
+ if err := os.Setenv("HOME", homeDir); err != nil {
+ return nil, fmt.Errorf("setting home: %w", err)
+ }
+ }
+
cleanup, err := configureTestDirectory()
if err != nil {
return nil, fmt.Errorf("configuring test directory: %w", err)
diff --git a/internal/testhelper/testcfg/gitaly_builder.go b/internal/testhelper/testcfg/gitaly_builder.go
index 3894ffada..0159525ed 100644
--- a/internal/testhelper/testcfg/gitaly_builder.go
+++ b/internal/testhelper/testcfg/gitaly_builder.go
@@ -143,6 +143,9 @@ func (gc *GitalyCfgBuilder) Build(t testing.TB) config.Cfg {
}
cfg.PackObjectsCache.Enabled = gc.packObjectsCacheEnabled
+ // Ignore the gitconfig so that tests aren't impacted by any configuration the user happens
+ // to have lying around.
+ cfg.Git.IgnoreGitconfig = true
require.NoError(t, cfg.Validate())
diff --git a/internal/testhelper/testdata/home/.config/git/config b/internal/testhelper/testdata/home/.config/git/config
new file mode 100644
index 000000000..aef95e47e
--- /dev/null
+++ b/internal/testhelper/testdata/home/.config/git/config
@@ -0,0 +1,5 @@
+# We're trying to catch any instances of libgit2 or Git that pick up the
+# gitconfig even though they're told not to. If they do pick up this file
+# though, then they would fail to parse it and thus return an error, which we
+# can detect quite easily.
+this is broken on purpose: [
diff --git a/internal/testhelper/testdata/home/.gitconfig b/internal/testhelper/testdata/home/.gitconfig
new file mode 100644
index 000000000..aef95e47e
--- /dev/null
+++ b/internal/testhelper/testdata/home/.gitconfig
@@ -0,0 +1,5 @@
+# We're trying to catch any instances of libgit2 or Git that pick up the
+# gitconfig even though they're told not to. If they do pick up this file
+# though, then they would fail to parse it and thus return an error, which we
+# can detect quite easily.
+this is broken on purpose: [