diff options
author | Toon Claes <toon@gitlab.com> | 2021-09-20 16:34:39 +0300 |
---|---|---|
committer | Toon Claes <toon@gitlab.com> | 2021-09-20 16:34:39 +0300 |
commit | e6374eaf67addb939516b5ad5d242418a6f2b688 (patch) | |
tree | 4ab62ddbbdb03ece33130155c70abc913794b8d1 | |
parent | d6c4f13dbff2729dffe834641d7e35cd6bbac5dc (diff) | |
parent | 5ee4c58353f9d4be9b73ae32ecb5273f0dc80cfe (diff) |
Merge branch 'extract_default_branch_2' into 'master'
Implement GetDefaultBranch in localrepo attempt 2
See merge request gitlab-org/gitaly!3872
-rw-r--r-- | internal/git/localrepo/refs.go | 79 | ||||
-rw-r--r-- | internal/git/localrepo/refs_test.go | 84 | ||||
-rw-r--r-- | internal/gitaly/service/commit/commits_by_message.go | 5 | ||||
-rw-r--r-- | internal/gitaly/service/commit/find_all_commits.go | 1 | ||||
-rw-r--r-- | internal/gitaly/service/commit/find_all_commits_test.go | 1 | ||||
-rw-r--r-- | internal/gitaly/service/commit/find_commits.go | 4 | ||||
-rw-r--r-- | internal/gitaly/service/commit/languages.go | 5 | ||||
-rw-r--r-- | internal/gitaly/service/commit/list_files.go | 4 | ||||
-rw-r--r-- | internal/gitaly/service/commit/list_files_test.go | 12 | ||||
-rw-r--r-- | internal/gitaly/service/commit/server.go | 3 | ||||
-rw-r--r-- | internal/gitaly/service/operations/apply_patch.go | 7 | ||||
-rw-r--r-- | internal/gitaly/service/ref/refs.go | 101 | ||||
-rw-r--r-- | internal/gitaly/service/ref/refs_test.go | 111 | ||||
-rw-r--r-- | internal/gitaly/service/remote/fetch_internal_remote.go | 4 | ||||
-rw-r--r-- | internal/gitaly/service/remote/update_remote_mirror.go | 5 |
15 files changed, 192 insertions, 234 deletions
diff --git a/internal/git/localrepo/refs.go b/internal/git/localrepo/refs.go index ac9c69fd1..0ebe4aa91 100644 --- a/internal/git/localrepo/refs.go +++ b/internal/git/localrepo/refs.go @@ -266,3 +266,82 @@ func (repo *Repo) GetRemoteReferences(ctx context.Context, remote string, opts . return refs, nil } + +// GetDefaultBranch determines the default branch name +func (repo *Repo) GetDefaultBranch(ctx context.Context) (git.ReferenceName, error) { + branches, err := repo.GetBranches(ctx) + if err != nil { + return "", err + } + switch len(branches) { + case 0: + return "", nil + case 1: + return branches[0].Name, nil + } + + headReference, err := repo.headReference(ctx) + if err != nil { + return "", err + } + + // Ideally we would only use HEAD to determine the default branch, but + // gitlab-rails depends on the branch being determined like this. + var defaultRef, legacyDefaultRef git.ReferenceName + for _, branch := range branches { + if len(headReference) != 0 && headReference == branch.Name { + return branch.Name, nil + } + + if string(git.DefaultRef) == branch.Name.String() { + defaultRef = branch.Name + } + + if string(git.LegacyDefaultRef) == branch.Name.String() { + legacyDefaultRef = branch.Name + } + } + + if len(defaultRef) != 0 { + return defaultRef, nil + } + + if len(legacyDefaultRef) != 0 { + return legacyDefaultRef, nil + } + + // If all else fails, return the first branch name + return branches[0].Name, nil +} + +func (repo *Repo) headReference(ctx context.Context) (git.ReferenceName, error) { + var headRef []byte + + cmd, err := repo.Exec(ctx, git.SubCmd{ + Name: "rev-parse", + Flags: []git.Option{git.Flag{Name: "--symbolic-full-name"}}, + Args: []string{"HEAD"}, + }) + if err != nil { + return "", err + } + + scanner := bufio.NewScanner(cmd) + scanner.Scan() + if err := scanner.Err(); err != nil { + return "", err + } + headRef = scanner.Bytes() + + if err := cmd.Wait(); err != nil { + // If the ref pointed at by HEAD doesn't exist, the rev-parse fails + // returning the string `"HEAD"`, so we return `nil` without error. + if bytes.Equal(headRef, []byte("HEAD")) { + return "", nil + } + + return "", err + } + + return git.ReferenceName(headRef), nil +} diff --git a/internal/git/localrepo/refs_test.go b/internal/git/localrepo/refs_test.go index a99384e42..ebfde348d 100644 --- a/internal/git/localrepo/refs_test.go +++ b/internal/git/localrepo/refs_test.go @@ -454,3 +454,87 @@ 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/gitaly/service/commit/commits_by_message.go b/internal/gitaly/service/commit/commits_by_message.go index 63a8898c9..6353cf0ee 100644 --- a/internal/gitaly/service/commit/commits_by_message.go +++ b/internal/gitaly/service/commit/commits_by_message.go @@ -53,12 +53,11 @@ func (s *server) commitsByMessage(in *gitalypb.CommitsByMessageRequest, stream g revision := in.GetRevision() if len(revision) == 0 { - var err error - - revision, err = defaultBranchName(ctx, repo) + defaultBranch, err := repo.GetDefaultBranch(ctx) if err != nil { return err } + revision = []byte(defaultBranch) } var paths []string diff --git a/internal/gitaly/service/commit/find_all_commits.go b/internal/gitaly/service/commit/find_all_commits.go index 796c7185b..26d13e8dc 100644 --- a/internal/gitaly/service/commit/find_all_commits.go +++ b/internal/gitaly/service/commit/find_all_commits.go @@ -10,6 +10,7 @@ import ( ) // We declare this function in variables so that we can override them in our tests +//nolint:staticcheck // FindBranchNames is deprecated but the tests are difficult to refactor var _findBranchNamesFunc = ref.FindBranchNames func (s *server) FindAllCommits(in *gitalypb.FindAllCommitsRequest, stream gitalypb.CommitService_FindAllCommitsServer) error { diff --git a/internal/gitaly/service/commit/find_all_commits_test.go b/internal/gitaly/service/commit/find_all_commits_test.go index ba7b7ff06..893b33af8 100644 --- a/internal/gitaly/service/commit/find_all_commits_test.go +++ b/internal/gitaly/service/commit/find_all_commits_test.go @@ -16,6 +16,7 @@ import ( func TestSuccessfulFindAllCommitsRequest(t *testing.T) { defer func() { + //nolint:staticcheck // FindBranchNames is deprecated but the tests are difficult to refactor _findBranchNamesFunc = ref.FindBranchNames }() diff --git a/internal/gitaly/service/commit/find_commits.go b/internal/gitaly/service/commit/find_commits.go index 6367aa35d..6f6f63b4d 100644 --- a/internal/gitaly/service/commit/find_commits.go +++ b/internal/gitaly/service/commit/find_commits.go @@ -29,11 +29,11 @@ func (s *server) FindCommits(req *gitalypb.FindCommitsRequest, stream gitalypb.C // Use Gitaly's default branch lookup function because that is already // migrated. if revision := req.Revision; len(revision) == 0 && !req.GetAll() { - var err error - req.Revision, err = defaultBranchName(ctx, repo) + defaultBranch, err := repo.GetDefaultBranch(ctx) if err != nil { return helper.ErrInternal(fmt.Errorf("defaultBranchName: %v", err)) } + req.Revision = []byte(defaultBranch) } // Clients might send empty paths. That is an error for _, path := range req.Paths { diff --git a/internal/gitaly/service/commit/languages.go b/internal/gitaly/service/commit/languages.go index fc65f3aef..b9ef474d4 100644 --- a/internal/gitaly/service/commit/languages.go +++ b/internal/gitaly/service/commit/languages.go @@ -10,7 +10,6 @@ import ( "strings" "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref" "gitlab.com/gitlab-org/gitaly/v14/internal/helper" "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" @@ -27,11 +26,11 @@ func (s *server) CommitLanguages(ctx context.Context, req *gitalypb.CommitLangua revision := string(req.Revision) if revision == "" { - defaultBranch, err := ref.DefaultBranchName(ctx, repo) + defaultBranch, err := repo.GetDefaultBranch(ctx) if err != nil { return nil, err } - revision = string(defaultBranch) + revision = defaultBranch.String() } commitID, err := s.lookupRevision(ctx, repo, revision) diff --git a/internal/gitaly/service/commit/list_files.go b/internal/gitaly/service/commit/list_files.go index 7b1cf8b71..4aa1fd448 100644 --- a/internal/gitaly/service/commit/list_files.go +++ b/internal/gitaly/service/commit/list_files.go @@ -29,7 +29,7 @@ func (s *server) ListFiles(in *gitalypb.ListFilesRequest, stream gitalypb.Commit revision := string(in.GetRevision()) if len(revision) == 0 { - defaultBranch, err := defaultBranchName(stream.Context(), repo) + defaultBranch, err := repo.GetDefaultBranch(stream.Context()) if err != nil { return helper.ErrNotFoundf("revision not found %q", revision) } @@ -38,7 +38,7 @@ func (s *server) ListFiles(in *gitalypb.ListFilesRequest, stream gitalypb.Commit return helper.ErrFailedPreconditionf("repository does not have a default branch") } - revision = string(defaultBranch) + revision = defaultBranch.String() } contained, err := s.localrepo(repo).HasRevision(stream.Context(), git.Revision(revision)) diff --git a/internal/gitaly/service/commit/list_files_test.go b/internal/gitaly/service/commit/list_files_test.go index f07fd7658..e0f69a92b 100644 --- a/internal/gitaly/service/commit/list_files_test.go +++ b/internal/gitaly/service/commit/list_files_test.go @@ -1,14 +1,11 @@ package commit import ( - "context" "io" "testing" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v14/internal/git" "gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref" "gitlab.com/gitlab-org/gitaly/v14/internal/testhelper" "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" "google.golang.org/grpc/codes" @@ -40,14 +37,9 @@ var defaultFiles = [][]byte{ } func TestListFiles_success(t *testing.T) { - defaultBranchName = func(context.Context, git.RepositoryExecutor) ([]byte, error) { - return []byte("test-do-not-touch"), nil - } - defer func() { - defaultBranchName = ref.DefaultBranchName - }() + cfg, repo, repoPath, client := setupCommitServiceWithRepo(t, true) - _, repo, _, client := setupCommitServiceWithRepo(t, true) + gittest.Exec(t, cfg, "-C", repoPath, "symbolic-ref", "HEAD", "refs/heads/test-do-not-touch") tests := []struct { desc string diff --git a/internal/gitaly/service/commit/server.go b/internal/gitaly/service/commit/server.go index 6669091e0..1ada86a09 100644 --- a/internal/gitaly/service/commit/server.go +++ b/internal/gitaly/service/commit/server.go @@ -7,7 +7,6 @@ import ( "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config" "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/linguist" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref" "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/storage" "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" ) @@ -21,8 +20,6 @@ type server struct { catfileCache catfile.Cache } -var defaultBranchName = ref.DefaultBranchName - // NewServer creates a new instance of a grpc CommitServiceServer func NewServer( cfg config.Cfg, diff --git a/internal/gitaly/service/operations/apply_patch.go b/internal/gitaly/service/operations/apply_patch.go index c673ae1be..d0c84d77a 100644 --- a/internal/gitaly/service/operations/apply_patch.go +++ b/internal/gitaly/service/operations/apply_patch.go @@ -11,7 +11,6 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" "gitlab.com/gitlab-org/gitaly/v14/internal/git" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref" "gitlab.com/gitlab-org/gitaly/v14/internal/helper" "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag" @@ -61,15 +60,15 @@ func (s *Server) userApplyPatch(ctx context.Context, header *gitalypb.UserApplyP return fmt.Errorf("resolve target branch: %w", err) } - defaultBranch, err := ref.DefaultBranchName(ctx, repo) + defaultBranch, err := repo.GetDefaultBranch(ctx) if err != nil { return fmt.Errorf("default branch name: %w", err) - } else if defaultBranch == nil { + } else if len(defaultBranch) == 0 { return errNoDefaultBranch } branchCreated = true - parentCommitID, err = repo.ResolveRevision(ctx, git.Revision(defaultBranch)+"^{commit}") + parentCommitID, err = repo.ResolveRevision(ctx, defaultBranch.Revision()+"^{commit}") if err != nil { return fmt.Errorf("resolve default branch commit: %w", err) } diff --git a/internal/gitaly/service/ref/refs.go b/internal/gitaly/service/ref/refs.go index 3a8e15c0f..dc92838b8 100644 --- a/internal/gitaly/service/ref/refs.go +++ b/internal/gitaly/service/ref/refs.go @@ -21,13 +21,6 @@ const ( tagFormat = "%(objectname) %(objecttype) %(refname:lstrip=2)" ) -var ( - // We declare the following functions in variables so that we can override them in our tests - headReference = _headReference - // FindBranchNames is exported to be used in other packages - FindBranchNames = _findBranchNames -) - type findRefsOpts struct { cmdArgs []git.Option delim byte @@ -63,7 +56,10 @@ func (s *server) findRefs(ctx context.Context, writer lines.Sender, repo git.Rep return cmd.Wait() } -func _findBranchNames(ctx context.Context, repo git.RepositoryExecutor) ([][]byte, error) { +// FindBranchNames returns all branch names. +// +// Deprecated: Use localrepo.Repo.GetBranches instead. +func FindBranchNames(ctx context.Context, repo git.RepositoryExecutor) ([][]byte, error) { var names [][]byte cmd, err := repo.Exec(ctx, git.SubCmd{ @@ -91,38 +87,6 @@ func _findBranchNames(ctx context.Context, repo git.RepositoryExecutor) ([][]byt return names, nil } -func _headReference(ctx context.Context, repo git.RepositoryExecutor) ([]byte, error) { - var headRef []byte - - cmd, err := repo.Exec(ctx, git.SubCmd{ - Name: "rev-parse", - Flags: []git.Option{git.Flag{Name: "--symbolic-full-name"}}, - Args: []string{"HEAD"}, - }) - if err != nil { - return nil, err - } - - scanner := bufio.NewScanner(cmd) - scanner.Scan() - if err := scanner.Err(); err != nil { - return nil, err - } - headRef = scanner.Bytes() - - if err := cmd.Wait(); err != nil { - // If the ref pointed at by HEAD doesn't exist, the rev-parse fails - // returning the string `"HEAD"`, so we return `nil` without error. - if bytes.Equal(headRef, []byte("HEAD")) { - return nil, nil - } - - return nil, err - } - - return headRef, nil -} - // SetDefaultBranchRef overwrites the default branch ref for the repository func SetDefaultBranchRef(ctx context.Context, repo git.RepositoryExecutor, ref string, cfg config.Cfg) error { if err := repo.ExecAndWait(ctx, git.SubCmd{ @@ -134,65 +98,16 @@ func SetDefaultBranchRef(ctx context.Context, repo git.RepositoryExecutor, ref s return nil } -// DefaultBranchName looks up the name of the default branch given a repoPath -func DefaultBranchName(ctx context.Context, repo git.RepositoryExecutor) ([]byte, error) { - branches, err := FindBranchNames(ctx, repo) - if err != nil { - return nil, err - } - - // Return empty ref name if there are no branches - if len(branches) == 0 { - return nil, nil - } - - // Return first branch name if there's only one - if len(branches) == 1 { - return branches[0], nil - } - - hasDefaultRef, hasLegacyDefaultRef := false, false - headRef, err := headReference(ctx, repo) - if err != nil { - return nil, err - } - - for _, branch := range branches { - // Return HEAD if it exists and corresponds to a branch - if headRef != nil && bytes.Equal(headRef, branch) { - return headRef, nil - } - - if bytes.Equal(branch, git.DefaultRef) { - hasDefaultRef = true - } - - hasLegacyDefaultRef = hasLegacyDefaultRef || bytes.Equal(branch, git.LegacyDefaultRef) - } - - // Return the default ref if it exists - if hasDefaultRef { - return git.DefaultRef, nil - } - - if hasLegacyDefaultRef { - return git.LegacyDefaultRef, nil - } - - // If all else fails, return the first branch name - return branches[0], nil -} - // FindDefaultBranchName returns the default branch name for the given repository func (s *server) FindDefaultBranchName(ctx context.Context, in *gitalypb.FindDefaultBranchNameRequest) (*gitalypb.FindDefaultBranchNameResponse, error) { repo := s.localrepo(in.GetRepository()) - defaultBranchName, err := DefaultBranchName(ctx, repo) + defaultBranch, err := repo.GetDefaultBranch(ctx) if err != nil { return nil, helper.ErrInternal(err) } - return &gitalypb.FindDefaultBranchNameResponse{Name: defaultBranchName}, nil + return &gitalypb.FindDefaultBranchNameResponse{Name: []byte(defaultBranch)}, nil } func parseSortKey(sortKey gitalypb.FindLocalBranchesRequest_SortBy) string { @@ -256,12 +171,12 @@ func (s *server) findAllBranches(in *gitalypb.FindAllBranchesRequest, stream git patterns := []string{"refs/heads", "refs/remotes"} if in.MergedOnly { - defaultBranchName, err := DefaultBranchName(stream.Context(), repo) + defaultBranch, err := repo.GetDefaultBranch(stream.Context()) if err != nil { return err } - args = append(args, git.Flag{Name: fmt.Sprintf("--merged=%s", string(defaultBranchName))}) + args = append(args, git.Flag{Name: fmt.Sprintf("--merged=%s", defaultBranch.String())}) if len(in.MergedBranches) > 0 { patterns = nil diff --git a/internal/gitaly/service/ref/refs_test.go b/internal/gitaly/service/ref/refs_test.go index d83e0d731..381a368ec 100644 --- a/internal/gitaly/service/ref/refs_test.go +++ b/internal/gitaly/service/ref/refs_test.go @@ -3,10 +3,8 @@ package ref import ( "bufio" "bytes" - "context" "fmt" "io" - "io/ioutil" "strings" "testing" @@ -220,37 +218,6 @@ func TestInvalidRepoFindAllTagNamesRequest(t *testing.T) { } } -func TestHeadReference(t *testing.T) { - cfg, repo, _ := testcfg.BuildWithRepo(t) - - ctx, cancel := testhelper.Context() - defer cancel() - - headRef, err := headReference(ctx, localrepo.NewTestRepo(t, cfg, repo)) - require.NoError(t, err) - - require.Equal(t, git.LegacyDefaultRef, headRef) -} - -func TestHeadReferenceWithNonExistingHead(t *testing.T) { - cfg, repo, repoPath := testcfg.BuildWithRepo(t) - - // Write bad HEAD - require.NoError(t, ioutil.WriteFile(repoPath+"/HEAD", []byte("ref: refs/heads/nonexisting"), 0o644)) - defer func() { - // Restore HEAD - require.NoError(t, ioutil.WriteFile(repoPath+"/HEAD", []byte("ref: refs/heads/master"), 0o644)) - }() - - ctx, cancel := testhelper.Context() - defer cancel() - headRef, err := headReference(ctx, localrepo.NewTestRepo(t, cfg, repo)) - require.NoError(t, err) - if headRef != nil { - t.Fatal("Expected HEAD reference to be nil, got '", string(headRef), "'") - } -} - func TestSetDefaultBranchRef(t *testing.T) { cfg, repoProto, _ := testcfg.BuildWithRepo(t) repo := localrepo.NewTestRepo(t, cfg, repoProto) @@ -279,88 +246,14 @@ func TestSetDefaultBranchRef(t *testing.T) { require.NoError(t, SetDefaultBranchRef(ctx, repo, tc.ref, cfg)) - newRef, err := DefaultBranchName(ctx, repo) + newRef, err := repo.GetDefaultBranch(ctx) require.NoError(t, err) - require.Equal(t, tc.expectedRef, string(newRef)) + require.Equal(t, tc.expectedRef, newRef.String()) }) } } -func TestDefaultBranchName(t *testing.T) { - // We are going to override these functions during this test. Restore them after we're done - defer func() { - FindBranchNames = _findBranchNames - headReference = _headReference - }() - - cfg, repoProto, _ := testcfg.BuildWithRepo(t) - repo := localrepo.NewTestRepo(t, cfg, repoProto) - - testCases := []struct { - desc string - findBranchNames func(context.Context, git.RepositoryExecutor) ([][]byte, error) - headReference func(context.Context, git.RepositoryExecutor) ([]byte, error) - expected []byte - }{ - { - desc: "Get first branch when only one branch exists", - expected: []byte("refs/heads/foo"), - findBranchNames: func(context.Context, git.RepositoryExecutor) ([][]byte, error) { - return [][]byte{[]byte("refs/heads/foo")}, nil - }, - headReference: func(context.Context, git.RepositoryExecutor) ([]byte, error) { return nil, nil }, - }, - { - desc: "Get empy ref if no branches exists", - expected: nil, - findBranchNames: func(context.Context, git.RepositoryExecutor) ([][]byte, error) { - return [][]byte{}, nil - }, - headReference: func(context.Context, git.RepositoryExecutor) ([]byte, error) { return nil, nil }, - }, - { - desc: "Get the name of the head reference when more than one branch exists", - expected: []byte("refs/heads/bar"), - findBranchNames: func(context.Context, git.RepositoryExecutor) ([][]byte, error) { - return [][]byte{[]byte("refs/heads/foo"), []byte("refs/heads/bar")}, nil - }, - headReference: func(context.Context, git.RepositoryExecutor) ([]byte, error) { - return []byte("refs/heads/bar"), nil - }, - }, - { - desc: "Get `ref/heads/master` when several branches exist", - expected: git.LegacyDefaultRef, - findBranchNames: func(context.Context, git.RepositoryExecutor) ([][]byte, error) { - return [][]byte{[]byte("refs/heads/foo"), []byte("refs/heads/master"), []byte("refs/heads/bar")}, nil - }, - headReference: func(context.Context, git.RepositoryExecutor) ([]byte, error) { return nil, nil }, - }, - { - desc: "Get the name of the first branch when several branches exists and no other conditions are met", - expected: []byte("refs/heads/foo"), - findBranchNames: func(context.Context, git.RepositoryExecutor) ([][]byte, error) { - return [][]byte{[]byte("refs/heads/foo"), []byte("refs/heads/bar"), []byte("refs/heads/baz")}, nil - }, - headReference: func(context.Context, git.RepositoryExecutor) ([]byte, error) { return nil, nil }, - }, - } - - for _, testCase := range testCases { - FindBranchNames = testCase.findBranchNames - headReference = testCase.headReference - - ctx, cancel := testhelper.Context() - defer cancel() - defaultBranch, err := DefaultBranchName(ctx, repo) - require.NoError(t, err) - if !bytes.Equal(defaultBranch, testCase.expected) { - t.Fatalf("%s: expected %s, got %s instead", testCase.desc, testCase.expected, defaultBranch) - } - } -} - func TestSuccessfulFindDefaultBranchName(t *testing.T) { cfg, repo, repoPath, client := setupRefService(t) rpcRequest := &gitalypb.FindDefaultBranchNameRequest{Repository: repo} diff --git a/internal/gitaly/service/remote/fetch_internal_remote.go b/internal/gitaly/service/remote/fetch_internal_remote.go index 7eafcf23b..b0eec8fbe 100644 --- a/internal/gitaly/service/remote/fetch_internal_remote.go +++ b/internal/gitaly/service/remote/fetch_internal_remote.go @@ -61,12 +61,12 @@ func FetchInternalRemote( return status.Errorf(codes.Internal, "FetchInternalRemote: remote default branch: %v", err) } - defaultBranch, err := ref.DefaultBranchName(ctx, repo) + defaultBranch, err := repo.GetDefaultBranch(ctx) if err != nil { return status.Errorf(codes.Internal, "FetchInternalRemote: default branch: %v", err) } - if !bytes.Equal(defaultBranch, remoteDefaultBranch) { + if defaultBranch.String() != string(remoteDefaultBranch) { if err := ref.SetDefaultBranchRef(ctx, repo, string(remoteDefaultBranch), cfg); err != nil { return status.Errorf(codes.Internal, "FetchInternalRemote: set default branch: %v", err) } diff --git a/internal/gitaly/service/remote/update_remote_mirror.go b/internal/gitaly/service/remote/update_remote_mirror.go index 8ab8f4ac9..d94ac2065 100644 --- a/internal/gitaly/service/remote/update_remote_mirror.go +++ b/internal/gitaly/service/remote/update_remote_mirror.go @@ -10,7 +10,6 @@ import ( "gitlab.com/gitlab-org/gitaly/v14/internal/git" "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/service/ref" "gitlab.com/gitlab-org/gitaly/v14/internal/helper" "gitlab.com/gitlab-org/gitaly/v14/internal/helper/text" "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" @@ -103,7 +102,7 @@ func (s *server) updateRemoteMirror(stream gitalypb.RemoteService_UpdateRemoteMi return fmt.Errorf("get local references: %w", err) } - defaultBranch, err := ref.DefaultBranchName(ctx, repo) + defaultBranch, err := repo.GetDefaultBranch(ctx) if err != nil { return fmt.Errorf("get default branch: %w", err) } @@ -195,7 +194,7 @@ func (s *server) updateRemoteMirror(stream gitalypb.RemoteService_UpdateRemoteMi } refspecs = append(refspecs, prefix+reference.String()) - if reference == git.ReferenceName(defaultBranch) { + if reference == defaultBranch { // The default branch needs to be pushed in the first batch of refspecs as some features // depend on it existing in the repository. The default branch may not exist in the repo // yet if this is the first mirroring push. |