diff options
author | Patrick Steinhardt <psteinhardt@gitlab.com> | 2021-09-21 12:15:00 +0300 |
---|---|---|
committer | Patrick Steinhardt <psteinhardt@gitlab.com> | 2021-10-06 12:53:40 +0300 |
commit | 033647da4d91bbc830e7ddd8c4ad04ea004cfb64 (patch) | |
tree | 88b8c7b926a7ade3cf167aff1940df5f4687ab19 | |
parent | e2657ce40ad51af2fbab68b75db86b7752ea2e62 (diff) |
remoterepo: Implement `GetDefaultBranch()`
We have an ad-hoc implementation of `GetDefaultBranch()` for remote
repositories in the `FetchInternalRemote()` RPC implementation. Given
that this RPC call simply maps to `localrepo.GetDefaultBranch()`, it
makes sense to pull up the implementation into the remoterepo interface
to make it generally available.
Implement `remoterepo.GetDefaultBranch()` and move tests of this
function from localrepo-specific tests into the shared test suite.
-rw-r--r-- | internal/git/gittest/repository_suite.go | 94 | ||||
-rw-r--r-- | internal/git/localrepo/refs_test.go | 84 | ||||
-rw-r--r-- | internal/git/remoterepo/repository.go | 13 | ||||
-rw-r--r-- | internal/git/remoterepo/repository_test.go | 8 | ||||
-rw-r--r-- | internal/git/repository.go | 2 |
5 files changed, 117 insertions, 84 deletions
diff --git a/internal/git/gittest/repository_suite.go b/internal/git/gittest/repository_suite.go index 7da568cc8..2da7d8af8 100644 --- a/internal/git/gittest/repository_suite.go +++ b/internal/git/gittest/repository_suite.go @@ -25,6 +25,10 @@ func TestRepository(t *testing.T, cfg config.Cfg, getRepository func(testing.TB, desc: "HasBranches", test: testRepositoryHasBranches, }, + { + desc: "GetDefaultBranch", + test: testRepositoryGetDefaultBranch, + }, } { t.Run(tc.desc, func(t *testing.T) { tc.test(t, cfg, getRepository) @@ -107,3 +111,93 @@ func testRepositoryHasBranches(t *testing.T, cfg config.Cfg, getRepository func( require.NoError(t, err) require.True(t, hasBranches) } + +func testRepositoryGetDefaultBranch(t *testing.T, cfg config.Cfg, getRepository func(testing.TB, *gitalypb.Repository) git.Repository) { + const testOID = "1a0b36b3cdad1d2ee32457c102a8c0b7056fa863" + + for _, tc := range []struct { + desc string + repo func(t *testing.T) git.Repository + expectedName git.ReferenceName + }{ + { + desc: "default ref", + repo: func(t *testing.T) git.Repository { + repoProto, repoPath := InitRepo(t, cfg, cfg.Storages[0]) + repo := getRepository(t, repoProto) + oid := WriteCommit(t, cfg, repoPath, WithParents(), WithBranch("apple")) + WriteCommit(t, cfg, repoPath, WithParents(oid), WithBranch("main")) + return repo + }, + expectedName: git.ReferenceName(git.DefaultRef), + }, + { + desc: "legacy default ref", + repo: func(t *testing.T) git.Repository { + repoProto, repoPath := InitRepo(t, cfg, cfg.Storages[0]) + repo := getRepository(t, repoProto) + oid := WriteCommit(t, cfg, repoPath, WithParents(), WithBranch("apple")) + WriteCommit(t, cfg, repoPath, WithParents(oid), WithBranch("master")) + return repo + }, + expectedName: git.ReferenceName(git.LegacyDefaultRef), + }, + { + desc: "no branches", + repo: func(t *testing.T) git.Repository { + repoProto, _ := InitRepo(t, cfg, cfg.Storages[0]) + repo := getRepository(t, repoProto) + return repo + }, + }, + { + desc: "one branch", + repo: func(t *testing.T) git.Repository { + repoProto, repoPath := InitRepo(t, cfg, cfg.Storages[0]) + repo := getRepository(t, repoProto) + WriteCommit(t, cfg, repoPath, WithParents(), WithBranch("apple")) + return repo + }, + expectedName: git.NewReferenceNameFromBranchName("apple"), + }, + { + desc: "no default branches", + repo: func(t *testing.T) git.Repository { + repoProto, repoPath := InitRepo(t, cfg, cfg.Storages[0]) + repo := getRepository(t, repoProto) + oid := WriteCommit(t, cfg, repoPath, WithParents(), WithBranch("apple")) + WriteCommit(t, cfg, repoPath, WithParents(oid), WithBranch("banana")) + return repo + }, + expectedName: git.NewReferenceNameFromBranchName("apple"), + }, + { + desc: "test repo default", + repo: func(t *testing.T) git.Repository { + repoProto, _ := CloneRepo(t, cfg, cfg.Storages[0]) + return getRepository(t, repoProto) + }, + expectedName: git.ReferenceName(git.LegacyDefaultRef), + }, + { + desc: "test repo HEAD set", + repo: func(t *testing.T) git.Repository { + repoProto, repoPath := CloneRepo(t, cfg, cfg.Storages[0]) + repo := getRepository(t, repoProto) + Exec(t, cfg, "-C", repoPath, "update-ref", "refs/heads/feature", testOID) + Exec(t, cfg, "-C", repoPath, "symbolic-ref", "HEAD", "refs/heads/feature") + return repo + }, + expectedName: git.NewReferenceNameFromBranchName("feature"), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + ctx, cancel := testhelper.Context() + defer cancel() + + name, err := tc.repo(t).GetDefaultBranch(ctx) + require.NoError(t, err) + require.Equal(t, tc.expectedName, name) + }) + } +} diff --git a/internal/git/localrepo/refs_test.go b/internal/git/localrepo/refs_test.go index 069073e47..3d3fdcd32 100644 --- a/internal/git/localrepo/refs_test.go +++ b/internal/git/localrepo/refs_test.go @@ -453,87 +453,3 @@ func TestRepo_UpdateRef(t *testing.T) { }) } } - -func TestGetDefaultBranch(t *testing.T) { - const testOID = "1a0b36b3cdad1d2ee32457c102a8c0b7056fa863" - - for _, tc := range []struct { - desc string - repo func(t *testing.T) *Repo - expectedName git.ReferenceName - }{ - { - desc: "default ref", - repo: func(t *testing.T) *Repo { - repo, repoPath := setupRepo(t, true) - oid := gittest.WriteCommit(t, repo.cfg, repoPath, gittest.WithParents(), gittest.WithBranch("apple")) - gittest.WriteCommit(t, repo.cfg, repoPath, gittest.WithParents(oid), gittest.WithBranch("main")) - return repo - }, - expectedName: git.ReferenceName(git.DefaultRef), - }, - { - desc: "legacy default ref", - repo: func(t *testing.T) *Repo { - repo, repoPath := setupRepo(t, true) - oid := gittest.WriteCommit(t, repo.cfg, repoPath, gittest.WithParents(), gittest.WithBranch("apple")) - gittest.WriteCommit(t, repo.cfg, repoPath, gittest.WithParents(oid), gittest.WithBranch("master")) - return repo - }, - expectedName: git.ReferenceName(git.LegacyDefaultRef), - }, - { - desc: "no branches", - repo: func(t *testing.T) *Repo { - repo, _ := setupRepo(t, true) - return repo - }, - }, - { - desc: "one branch", - repo: func(t *testing.T) *Repo { - repo, repoPath := setupRepo(t, true) - gittest.WriteCommit(t, repo.cfg, repoPath, gittest.WithParents(), gittest.WithBranch("apple")) - return repo - }, - expectedName: git.NewReferenceNameFromBranchName("apple"), - }, - { - desc: "no default branches", - repo: func(t *testing.T) *Repo { - repo, repoPath := setupRepo(t, true) - oid := gittest.WriteCommit(t, repo.cfg, repoPath, gittest.WithParents(), gittest.WithBranch("apple")) - gittest.WriteCommit(t, repo.cfg, repoPath, gittest.WithParents(oid), gittest.WithBranch("banana")) - return repo - }, - expectedName: git.NewReferenceNameFromBranchName("apple"), - }, - { - desc: "test repo default", - repo: func(t *testing.T) *Repo { - repo, _ := setupRepo(t, false) - return repo - }, - expectedName: git.ReferenceName(git.LegacyDefaultRef), - }, - { - desc: "test repo HEAD set", - repo: func(t *testing.T) *Repo { - repo, repoPath := setupRepo(t, false) - gittest.Exec(t, repo.cfg, "-C", repoPath, "update-ref", "refs/heads/feature", testOID) - gittest.Exec(t, repo.cfg, "-C", repoPath, "symbolic-ref", "HEAD", "refs/heads/feature") - return repo - }, - expectedName: git.NewReferenceNameFromBranchName("feature"), - }, - } { - t.Run(tc.desc, func(t *testing.T) { - ctx, cancel := testhelper.Context() - defer cancel() - - name, err := tc.repo(t).GetDefaultBranch(ctx) - require.NoError(t, err) - require.Equal(t, tc.expectedName, name) - }) - } -} diff --git a/internal/git/remoterepo/repository.go b/internal/git/remoterepo/repository.go index 69fa197f4..c31248f65 100644 --- a/internal/git/remoterepo/repository.go +++ b/internal/git/remoterepo/repository.go @@ -70,3 +70,16 @@ func (rr *Repo) HasBranches(ctx context.Context) (bool, error) { return resp.Value, nil } + +// GetDefaultBranch returns the default branch for the remote repository. It does so by invoking +// `FindDefaultBranchName()`, which itself is a wrapper around `localrepo.GetDefaultBranch()`. +// Semantics of this function thus match the localrepo semantics. +func (rr *Repo) GetDefaultBranch(ctx context.Context) (git.ReferenceName, error) { + resp, err := gitalypb.NewRefServiceClient(rr.conn).FindDefaultBranchName( + ctx, &gitalypb.FindDefaultBranchNameRequest{Repository: rr.Repository}) + if err != nil { + return "", err + } + + return git.ReferenceName(resp.Name), nil +} diff --git a/internal/git/remoterepo/repository_test.go b/internal/git/remoterepo/repository_test.go index b209ef79d..ddc63fb11 100644 --- a/internal/git/remoterepo/repository_test.go +++ b/internal/git/remoterepo/repository_test.go @@ -10,6 +10,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v14/internal/git/remoterepo" "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service" "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/commit" + "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref" "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/repository" "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" "gitlab.com/gitlab-org/gitaly/v14/internal/metadata" @@ -39,6 +40,13 @@ func TestRepository(t *testing.T) { deps.GetLinguist(), deps.GetCatfileCache(), )) + gitalypb.RegisterRefServiceServer(srv, ref.NewServer( + deps.GetCfg(), + deps.GetLocator(), + deps.GetGitCmdFactory(), + deps.GetTxManager(), + deps.GetCatfileCache(), + )) }) ctx, cancel := testhelper.Context() diff --git a/internal/git/repository.go b/internal/git/repository.go index e5f5b25d5..2bdb6daef 100644 --- a/internal/git/repository.go +++ b/internal/git/repository.go @@ -44,6 +44,8 @@ type Repository interface { ResolveRevision(ctx context.Context, revision Revision) (ObjectID, error) // HasBranches returns whether the repository has branches. HasBranches(ctx context.Context) (bool, error) + // GetDefaultBranch returns the default branch of the repository. + GetDefaultBranch(ctx context.Context) (ReferenceName, error) } // RepositoryExecutor is an interface which allows execution of Git commands in a specific |