diff options
author | Patrick Steinhardt <psteinhardt@gitlab.com> | 2022-07-19 09:10:18 +0300 |
---|---|---|
committer | Patrick Steinhardt <psteinhardt@gitlab.com> | 2022-07-21 07:43:48 +0300 |
commit | b67c3828c16a2af7c1a93f2a3f30dadba3089513 (patch) | |
tree | 13fc734f67f04a51c7da248a25116f23aa59cfef | |
parent | 50d310dec66f3b64f21ba0d469b301965890f298 (diff) |
git: Discern different types of internal references
We've got two different types of internal references: those that are
interesting to the user but shouldn't be written to by them, and then
those that are really only required for our own internal housekeeping
and which should neither be readable nor writeable.
Introduce a new `InternalReferenceType` to mark references accordingly.
-rw-r--r-- | internal/git/command_description.go | 15 | ||||
-rw-r--r-- | internal/git/reference.go | 43 | ||||
-rw-r--r-- | internal/gitaly/service/cleanup/internalrefs/cleaner.go | 7 | ||||
-rw-r--r-- | internal/gitaly/service/repository/replicate_test.go | 4 | ||||
-rw-r--r-- | internal/gitaly/service/repository/size.go | 4 |
5 files changed, 57 insertions, 16 deletions
diff --git a/internal/git/command_description.go b/internal/git/command_description.go index 9149ab0db..c6cabb959 100644 --- a/internal/git/command_description.go +++ b/internal/git/command_description.go @@ -375,13 +375,20 @@ func validatePositionalArg(arg string) error { } func hiddenReceivePackRefPrefixes() []GlobalOption { - var cps []GlobalOption + config := make([]GlobalOption, 0, len(InternalRefPrefixes)) - for _, ns := range InternalRefPrefixes { - cps = append(cps, ConfigPair{Key: "receive.hideRefs", Value: ns}) + for refPrefix, refType := range InternalRefPrefixes { + switch refType { + case InternalReferenceTypeReadonly, InternalReferenceTypeHidden: + // We want to hide both read-only and hidden refs in git-receive-pack(1) so + // that we make neither of them writeable. + config = append(config, ConfigPair{Key: "receive.hideRefs", Value: refPrefix}) + default: + panic(fmt.Sprintf("unhandled internal reference type: %v", refType)) + } } - return cps + return config } // fsckConfiguration generates our fsck configuration, including ignored checks. The prefix must diff --git a/internal/git/reference.go b/internal/git/reference.go index c63230b06..225231188 100644 --- a/internal/git/reference.go +++ b/internal/git/reference.go @@ -8,15 +8,44 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/command" ) +// InternalReferenceType is the type of an internal reference. +type InternalReferenceType int + +const ( + // InternalReferenceTypeHidden indicates that a reference should never be advertised or + // writeable. + InternalReferenceTypeHidden = InternalReferenceType(iota + 1) + // InternalReferenceTypeReadonly indicates that a reference should be advertised, but not + // writeable. + InternalReferenceTypeReadonly +) + // InternalRefPrefixes is an array of all reference prefixes which are used internally by GitLab. // These need special treatment in some cases, e.g. to restrict writing to them. -var InternalRefPrefixes = [...]string{ - "refs/environments/", - "refs/keep-around/", - "refs/merge-requests/", - "refs/pipelines/", - "refs/remotes/", - "refs/tmp/", +var InternalRefPrefixes = map[string]InternalReferenceType{ + // Environments may be interesting to the user in case they want to figure out what exact + // reference an environment has been constructed from. + "refs/environments/": InternalReferenceTypeReadonly, + + // Keep-around references are only used internally to keep alive objects, and thus they + // shouldn't be exposed to the user. + "refs/keep-around/": InternalReferenceTypeHidden, + + // Merge request references should be readable by the user so that they can still fetch the + // changes of specific merge requests. + "refs/merge-requests/": InternalReferenceTypeReadonly, + + // Pipelines may be interesting to the user in case they want to figure out what exact + // reference a specific pipeline has been running with. + "refs/pipelines/": InternalReferenceTypeReadonly, + + // Remote references shouldn't typically exist in repositories nowadays anymore, and there + // is no reason to expose them to the user. + "refs/remotes/": InternalReferenceTypeHidden, + + // Temporary references are used internally by Rails for various operations and should not + // be exposed to the user. + "refs/tmp/": InternalReferenceTypeHidden, } // ObjectPoolRefNamespace is the namespace used for the references of the primary pool member part diff --git a/internal/gitaly/service/cleanup/internalrefs/cleaner.go b/internal/gitaly/service/cleanup/internalrefs/cleaner.go index 1c4094bcc..0ef2986c8 100644 --- a/internal/gitaly/service/cleanup/internalrefs/cleaner.go +++ b/internal/gitaly/service/cleanup/internalrefs/cleaner.go @@ -124,10 +124,15 @@ func (c *Cleaner) processEntry(ctx context.Context, oldSHA, newSHA string) error // action). It is consulted once per line in the object map. Git is optimized // for ref -> SHA lookups, but we want the opposite! func buildLookupTable(ctx context.Context, repo git.RepositoryExecutor) (map[string][]git.ReferenceName, error) { + internalRefPrefixes := make([]string, 0, len(git.InternalRefPrefixes)) + for refPrefix := range git.InternalRefPrefixes { + internalRefPrefixes = append(internalRefPrefixes, refPrefix) + } + cmd, err := repo.Exec(ctx, git.SubCmd{ Name: "for-each-ref", Flags: []git.Option{git.ValueFlag{Name: "--format", Value: "%(objectname) %(refname)"}}, - Args: git.InternalRefPrefixes[:], + Args: internalRefPrefixes, }) if err != nil { return nil, err diff --git a/internal/gitaly/service/repository/replicate_test.go b/internal/gitaly/service/repository/replicate_test.go index 1ca8258b0..1908cbbbb 100644 --- a/internal/gitaly/service/repository/replicate_test.go +++ b/internal/gitaly/service/repository/replicate_test.go @@ -129,7 +129,7 @@ func TestReplicateRepository_hiddenRefs(t *testing.T) { // Create a bunch of internal references, regardless of whether we classify them as hidden // or read-only. We should be able to replicate all of them. var expectedRefs []string - for _, refPrefix := range git.InternalRefPrefixes { + for refPrefix := range git.InternalRefPrefixes { commitID := gittest.WriteCommit(t, cfg, sourceRepoPath, gittest.WithParents(), gittest.WithMessage(refPrefix)) gittest.Exec(t, cfg, "-C", sourceRepoPath, "update-ref", refPrefix+"1", commitID.String()) expectedRefs = append(expectedRefs, fmt.Sprintf("%s commit\t%s", commitID, refPrefix+"1")) @@ -168,7 +168,7 @@ func TestReplicateRepository_hiddenRefs(t *testing.T) { require.Equal(t, sourceCommitID, targetCommitID) // Create the internal references now. - for _, refPrefix := range git.InternalRefPrefixes { + for refPrefix := range git.InternalRefPrefixes { commitID := gittest.WriteCommit(t, cfg, sourceRepoPath, gittest.WithParents(), gittest.WithMessage(refPrefix)) gittest.Exec(t, cfg, "-C", sourceRepoPath, "update-ref", refPrefix+"1", commitID.String()) } diff --git a/internal/gitaly/service/repository/size.go b/internal/gitaly/service/repository/size.go index 3eb0f83a5..1879aead9 100644 --- a/internal/gitaly/service/repository/size.go +++ b/internal/gitaly/service/repository/size.go @@ -21,8 +21,8 @@ func (s *server) RepositorySize(ctx context.Context, in *gitalypb.RepositorySize var err error var excludes []string - for _, prefix := range git.InternalRefPrefixes { - excludes = append(excludes, prefix+"*") + for refPrefix := range git.InternalRefPrefixes { + excludes = append(excludes, refPrefix+"*") } path, err := repo.Path() |