diff options
author | John Cai <jcai@gitlab.com> | 2023-04-03 19:03:11 +0300 |
---|---|---|
committer | John Cai <jcai@gitlab.com> | 2023-04-03 19:03:11 +0300 |
commit | f19c582cfb3e3203b8785034c6257e7057885048 (patch) | |
tree | e830648b5c2e427c6c18e4d096c46fb831e3fe1f | |
parent | 399be8ceba112584174ac0014f6eae6c31002fde (diff) |
operations: Replace UserUpdateSubmodule implementation with tree helpersjc/add-tree-modification-helpers-optimized
Now that we have helpers for modifying tree entries, replace our
existing git plumbing implementation with the TreeEntry Modify() helper.
-rw-r--r-- | internal/gitaly/service/operations/submodules.go | 105 |
1 files changed, 32 insertions, 73 deletions
diff --git a/internal/gitaly/service/operations/submodules.go b/internal/gitaly/service/operations/submodules.go index 7a96194ef..31e7072a5 100644 --- a/internal/gitaly/service/operations/submodules.go +++ b/internal/gitaly/service/operations/submodules.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "path/filepath" "regexp" "strings" @@ -60,88 +59,48 @@ func validateUserUpdateSubmoduleRequest(req *gitalypb.UserUpdateSubmoduleRequest } func (s *Server) updateSubmodule(ctx context.Context, quarantineRepo *localrepo.Repo, req *gitalypb.UserUpdateSubmoduleRequest) (string, error) { - path := filepath.Dir(string(req.GetSubmodule())) - base := filepath.Base(string(req.GetSubmodule())) - replaceWith := git.ObjectID(req.GetCommitSha()) - - var submoduleFound bool - - // First find the tree containing the submodule to be updated. - // Write a new tree object abc with the updated submodule. Then, write a new - // tree with the new tree abcabc. Continue iterating up the tree, - // writing a new tree object each time. - for { - entries, err := quarantineRepo.ListEntries( - ctx, - - git.Revision("refs/heads/"+string(req.GetBranch())), - &localrepo.ListEntriesConfig{ - RelativePath: path, - }) - if err != nil { - if strings.Contains(err.Error(), "invalid object name") { - return "", fmt.Errorf("submodule: %s", git2go.LegacyErrPrefixInvalidSubmodulePath) - } - - return "", fmt.Errorf("error reading tree: %w", err) - } + fullTree, err := quarantineRepo.GetFullTree(ctx, git.NewReferenceNameFromBranchName(string(req.GetBranch())).Revision()) + if err != nil { + return "", fmt.Errorf("getting tree: %w", err) + } - var newEntries []*localrepo.TreeEntry - var newTreeID git.ObjectID + if err := fullTree.Modify( + ctx, + string(req.GetSubmodule()), + func(t *localrepo.TreeEntry) error { + replaceWith := git.ObjectID(req.GetCommitSha()) - for _, entry := range entries { - // If the entry's path does not match, then we simply - // want to retain this tree entry. - if entry.Path != base { - newEntries = append(newEntries, entry) - continue + if t.Type != localrepo.Submodule { + return fmt.Errorf("submodule: %s", git2go.LegacyErrPrefixInvalidSubmodulePath) } - // If we are at the submodule we want to replace, check - // if it's already at the value we want to replace, or - // if it's not a submodule. - if filepath.Join(path, entry.Path) == string(req.GetSubmodule()) { - if string(entry.OID) == req.GetCommitSha() { - return "", - //nolint:stylecheck - fmt.Errorf( - "The submodule %s is already at %s", - req.GetSubmodule(), - replaceWith, - ) - } - - if entry.Type != localrepo.Submodule { - return "", fmt.Errorf("submodule: %s", git2go.LegacyErrPrefixInvalidSubmodulePath) - } + if replaceWith == t.OID { + //nolint:stylecheck + return fmt.Errorf( + "The submodule %s is already at %s", + req.GetSubmodule(), + replaceWith, + ) } - // Otherwise, create a new tree entry - submoduleFound = true + t.OID = replaceWith - newEntries = append(newEntries, &localrepo.TreeEntry{ - Mode: entry.Mode, - Path: entry.Path, - OID: replaceWith, - }) - } - - newTreeID, err = quarantineRepo.WriteTree(ctx, newEntries) - if err != nil { - return "", fmt.Errorf("write tree: %w", err) - } - replaceWith = newTreeID - - if path == "." { - break + return nil + }, + ); err != nil { + if err == localrepo.ErrEntryNotFound { + return "", fmt.Errorf("submodule: %s", git2go.LegacyErrPrefixInvalidSubmodulePath) } - base = filepath.Base(path) - path = filepath.Dir(path) + return "", err } - if !submoduleFound { - return "", fmt.Errorf("submodule: %s", git2go.LegacyErrPrefixInvalidSubmodulePath) + treeID, err := quarantineRepo.WriteTreeRecursively( + ctx, + &fullTree, + ) + if err != nil { + return "", err } currentBranchCommit, err := quarantineRepo.ResolveRevision(ctx, git.Revision(req.GetBranch())) @@ -163,7 +122,7 @@ func (s *Server) updateSubmodule(ctx context.Context, quarantineRepo *localrepo. CommitterEmail: string(req.GetUser().GetEmail()), CommitterDate: authorDate, Message: string(req.GetCommitMessage()), - TreeID: replaceWith, + TreeID: treeID, }) if err != nil { return "", fmt.Errorf("creating commit %w", err) |