diff options
author | Justin Tobler <jtobler@gitlab.com> | 2023-06-05 19:45:23 +0300 |
---|---|---|
committer | Justin Tobler <jtobler@gitlab.com> | 2023-06-06 20:13:52 +0300 |
commit | ff193868ed2c4c5e2c19a34902e5af3b29ed86b4 (patch) | |
tree | 0b473b17d0d7827e6bbe11c8acf5f7a35ce23938 | |
parent | a69cf20ceb11365f64d663a8d6028ceb1b79a09c (diff) |
repository: Disable `fsck` during replication
The `ReplicateRepository()` RPC uses `git-fetch(1)` to retrieve objects
from preexisting internal repositories. Currently the `fetch` also
performs consistency checks on the newly retrieved objects. This is
problematic because preexisting objects should alway be able to be
replicated regardless of the consistency check. This change sets
`fetch.fsckObjects` to `false` for the performed `fetch` to disable
`fsck` consistency checks.
-rw-r--r-- | internal/gitaly/service/repository/replicate.go | 4 | ||||
-rw-r--r-- | internal/gitaly/service/repository/replicate_test.go | 39 |
2 files changed, 42 insertions, 1 deletions
diff --git a/internal/gitaly/service/repository/replicate.go b/internal/gitaly/service/repository/replicate.go index 7b2e998a0..74d13cf6b 100644 --- a/internal/gitaly/service/repository/replicate.go +++ b/internal/gitaly/service/repository/replicate.go @@ -238,6 +238,10 @@ func fetchInternalRemote( Stderr: &stderr, CommandOptions: []git.CmdOpt{ git.WithConfig(git.ConfigPair{Key: "fetch.negotiationAlgorithm", Value: "skipping"}), + // Disable the consistency checks of objects fetched into the replicated repository. + // These fetched objects come from preexisting internal sources, thus it would be + // problematic for the fetch to fail consistency checks due to altered requirements. + git.WithConfig(git.ConfigPair{Key: "fetch.fsckObjects", Value: "false"}), }, }, ); err != nil { diff --git a/internal/gitaly/service/repository/replicate_test.go b/internal/gitaly/service/repository/replicate_test.go index da9ea00b8..e76bad015 100644 --- a/internal/gitaly/service/repository/replicate_test.go +++ b/internal/gitaly/service/repository/replicate_test.go @@ -338,6 +338,43 @@ func TestReplicateRepository(t *testing.T) { } }, }, + { + desc: "fsck disabled for fetch", + setup: func(t *testing.T) setupData { + // To validate that fsck is disabled, `git-fetch(1)` must be used to replicate + // objects in the source repository. If the target repository already exists prior + // to replication, snapshot replication is skipped ensuring all necessary objects in + // the source repository are replicated to the target via `git-fetch(1)`. + source, sourcePath, target, _ := setupSourceAndTarget(t, true) + + // Write a tree into the source repository that's known-broken. For this object to + // be fetched into the target repository `fsck` must be disabled. + treeID := gittest.WriteTree(t, cfg, sourcePath, []gittest.TreeEntry{ + {Content: "content", Path: "dup", Mode: "100644"}, + {Content: "content", Path: "dup", Mode: "100644"}, + }) + + commitID := gittest.WriteCommit(t, cfg, sourcePath, + gittest.WithParents(), + gittest.WithBranch("main"), + gittest.WithTree(treeID), + ) + + // Verify that the broken tree is indeed in the source repository and that it is + // reported as broken by git-fsck(1). + var stderr bytes.Buffer + fsckCmd := gittest.NewCommand(t, cfg, "-C", sourcePath, "fsck") + fsckCmd.Stderr = &stderr + require.Error(t, fsckCmd.Run()) + require.Equal(t, fmt.Sprintf("error in tree %s: duplicateEntries: contains duplicate file entries\n", treeID), stderr.String()) + + return setupData{ + source: source, + target: target, + expectedObjects: []string{treeID.String(), commitID.String()}, + } + }, + }, } { tc := tc t.Run(tc.desc, func(t *testing.T) { @@ -367,7 +404,7 @@ func TestReplicateRepository(t *testing.T) { targetPath := filepath.Join(cfg.Storages[1].Path, gittest.GetReplicaPath(t, ctx, cfg, setup.target)) // Verify target repository connectivity. - gittest.Exec(t, cfg, "-C", targetPath, "fsck") + gittest.Exec(t, cfg, "-C", targetPath, "rev-list", "--objects", "--all") // Verify Git config matches. require.Equal(t, |