diff options
author | John Cai <jcai@gitlab.com> | 2022-11-09 23:28:43 +0300 |
---|---|---|
committer | John Cai <jcai@gitlab.com> | 2022-11-13 05:02:57 +0300 |
commit | 0f6eaf33d1d78938d28187a48c0d85ebe5b02cbd (patch) | |
tree | b5c06fc9b1bc0e64da7b9c5babc49b8971940d01 | |
parent | ce1d4471e2b14dd2c2c2458237518bf2dab99234 (diff) |
Rename lstree to tree package
15 files changed, 284 insertions, 35 deletions
diff --git a/cmd/gitaly-git2go/submodule_test.go b/cmd/gitaly-git2go/submodule_test.go index c05bc0af5..e653f2d13 100644 --- a/cmd/gitaly-git2go/submodule_test.go +++ b/cmd/gitaly-git2go/submodule_test.go @@ -11,7 +11,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/git" "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/tree" "gitlab.com/gitlab-org/gitaly/v15/internal/git2go" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg" @@ -119,7 +119,7 @@ func TestSubmodule(t *testing.T) { fmt.Sprintf("%s^{tree}:", response.CommitID), tc.command.Submodule, ) - parser := lstree.NewParser(bytes.NewReader(entry), git.ObjectHashSHA1) + parser := tree.NewParser(bytes.NewReader(entry), git.ObjectHashSHA1) parsedEntry, err := parser.NextEntry() require.NoError(t, err) require.Equal(t, tc.command.Submodule, parsedEntry.Path) diff --git a/internal/git/gitpipe/ls_tree.go b/internal/git/gitpipe/ls_tree.go index 38c15a8c7..b0a4b7ccf 100644 --- a/internal/git/gitpipe/ls_tree.go +++ b/internal/git/gitpipe/ls_tree.go @@ -9,13 +9,13 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/git" "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/tree" ) // lsTreeConfig is configuration for the LsTree pipeline step. type lsTreeConfig struct { recursive bool - typeFilter func(*lstree.Entry) bool + typeFilter func(*tree.Entry) bool skipResult func(*RevisionResult) (bool, error) } @@ -32,7 +32,7 @@ func LsTreeWithRecursive() LsTreeOption { // LsTreeWithBlobFilter configures LsTree to only pass through blob objects. func LsTreeWithBlobFilter() LsTreeOption { return func(cfg *lsTreeConfig) { - cfg.typeFilter = func(e *lstree.Entry) bool { return e.Type == lstree.Blob } + cfg.typeFilter = func(e *tree.Entry) bool { return e.Type == tree.Blob } } } @@ -97,7 +97,7 @@ func LsTree( return } - parser := lstree.NewParser(cmd, objectHash) + parser := tree.NewParser(cmd, objectHash) for { entry, err := parser.NextEntry() if err != nil { diff --git a/internal/git/lstree/entries.go b/internal/git/tree/entries.go index 89167d9b4..5411caf2e 100644 --- a/internal/git/lstree/entries.go +++ b/internal/git/tree/entries.go @@ -1,4 +1,4 @@ -package lstree +package tree import "gitlab.com/gitlab-org/gitaly/v15/internal/git" diff --git a/internal/git/lstree/list_entries.go b/internal/git/tree/list_entries.go index 24156c7a7..d722130eb 100644 --- a/internal/git/lstree/list_entries.go +++ b/internal/git/tree/list_entries.go @@ -1,4 +1,4 @@ -package lstree +package tree import ( "bytes" diff --git a/internal/git/lstree/list_entries_test.go b/internal/git/tree/list_entries_test.go index 2c3ef8256..b11c89114 100644 --- a/internal/git/lstree/list_entries_test.go +++ b/internal/git/tree/list_entries_test.go @@ -1,4 +1,4 @@ -package lstree +package tree import ( "testing" diff --git a/internal/git/lstree/parser.go b/internal/git/tree/parser.go index a8618288c..fbeadd401 100644 --- a/internal/git/lstree/parser.go +++ b/internal/git/tree/parser.go @@ -1,4 +1,4 @@ -package lstree +package tree import ( "bufio" diff --git a/internal/git/lstree/parser_test.go b/internal/git/tree/parser_test.go index af4d540d7..1bfb94fa5 100644 --- a/internal/git/lstree/parser_test.go +++ b/internal/git/tree/parser_test.go @@ -1,4 +1,4 @@ -package lstree +package tree import ( "bytes" diff --git a/internal/git/lstree/testhelper_test.go b/internal/git/tree/testhelper_test.go index 619a98800..0e242ba8b 100644 --- a/internal/git/lstree/testhelper_test.go +++ b/internal/git/tree/testhelper_test.go @@ -1,4 +1,4 @@ -package lstree +package tree import ( "testing" diff --git a/internal/git/tree/write.go b/internal/git/tree/write.go new file mode 100644 index 000000000..c898a861b --- /dev/null +++ b/internal/git/tree/write.go @@ -0,0 +1,60 @@ +package tree + +import ( + "bytes" + "context" + "fmt" + + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" +) + +// Write writes a new tree object to the given path. This function does not verify whether OIDs +// referred to by tree entries actually exist in the repository. +func Write(ctx context.Context, repo *localrepo.Repo, entries []*Entry) (git.ObjectID, error) { + var tree bytes.Buffer + for _, entry := range entries { + var entryType string + switch entry.Type { + case Tree: + entryType = "tree" + case Blob: + entryType = "blob" + case Submodule: + entryType = "commit" + } + + oid := entry.ObjectID + + formattedEntry := fmt.Sprintf("%s %s %s\t%s\000", string(entry.Mode), entryType, oid.String(), entry.Path) + if _, err := tree.WriteString(formattedEntry); err != nil { + return "", err + } + } + + options := []git.Option{ + git.Flag{Name: "-z"}, + git.Flag{Name: "--missing"}, + } + + var stdout, stderr bytes.Buffer + if err := repo.ExecAndWait(ctx, + git.SubCmd{ + Name: "mktree", + Flags: options, + }, + git.WithStdout(&stdout), + git.WithStderr(&stderr), + git.WithStdin(&tree), + ); err != nil { + return "", err + } + + treeOID, err := git.ObjectHashSHA1.FromHex(text.ChompBytes(stdout.Bytes())) + if err != nil { + return "", err + } + + return treeOID, nil +} diff --git a/internal/git/tree/write_test.go b/internal/git/tree/write_test.go new file mode 100644 index 000000000..a87ee17c2 --- /dev/null +++ b/internal/git/tree/write_test.go @@ -0,0 +1,188 @@ +package tree + +import ( + "bytes" + "strings" + "testing" + + "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" + "gitlab.com/gitlab-org/gitaly/v15/internal/helper/text" + "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper" +) + +func TestWriteTree(t *testing.T) { + cfg, repo, repoPath := setupRepo(t) + ctx := testhelper.Context(t) + + differentContentBlobID, err := repo.WriteBlob(ctx, "file", bytes.NewBufferString("different content")) + require.NoError(t, err) + + blobID, err := repo.WriteBlob(ctx, "file", bytes.NewBufferString("foobar\n")) + require.NoError(t, err) + + treeID, err := Write(ctx, repo, []*Entry{ + { + ObjectID: blobID, + Mode: []byte("100644"), + Path: "file", + Type: Blob, + }, + }) + require.NoError(t, err) + + for _, tc := range []struct { + desc string + entries []*Entry + expectedEntries []*Entry + }{ + { + desc: "entry with blob OID", + entries: []*Entry{ + { + ObjectID: blobID, + Mode: []byte("100644"), + Path: "file", + Type: Blob, + }, + }, + expectedEntries: []*Entry{ + { + ObjectID: blobID, + Mode: []byte("100644"), + Path: "file", + Type: Blob, + }, + }, + }, + { + desc: "entry with tree OID", + entries: []*Entry{ + { + ObjectID: treeID, + Mode: []byte("040000"), + Path: "dir", + Type: Tree, + }, + }, + expectedEntries: []*Entry{ + { + ObjectID: blobID, + Mode: []byte("100644"), + Path: "dir/file", + Type: Blob, + }, + }, + }, + { + desc: "mixed tree and blob entries", + entries: []*Entry{ + { + ObjectID: treeID, + Mode: []byte("040000"), + Path: "dir", + Type: Tree, + }, + { + ObjectID: blobID, + Mode: []byte("100644"), + Path: "file1", + Type: Blob, + }, + { + ObjectID: differentContentBlobID, + Mode: []byte("100644"), + Path: "file2", + Type: Blob, + }, + }, + expectedEntries: []*Entry{ + { + ObjectID: blobID, + Mode: []byte("100644"), + Path: "dir/file", + Type: Blob, + }, + { + ObjectID: blobID, + Mode: []byte("100644"), + Path: "file1", + Type: Blob, + }, + { + ObjectID: differentContentBlobID, + Mode: []byte("100644"), + Path: "file2", + Type: Blob, + }, + }, + }, + { + desc: "two entries with nonexistant objects", + entries: []*Entry{ + { + ObjectID: git.ObjectID(strings.Repeat("1", git.ObjectHashSHA1.Hash().Size()*2)), + Mode: []byte("100644"), + Path: "file", + Type: Blob, + }, + { + ObjectID: git.ObjectHashSHA1.ZeroOID, + Mode: []byte("100644"), + Path: "file", + Type: Blob, + }, + }, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + oid, err := Write(ctx, repo, tc.entries) + require.NoError(t, err) + + if tc.expectedEntries == nil { + return + } + + output := text.ChompBytes(gittest.Exec(t, cfg, "-C", repoPath, "ls-tree", "-r", string(oid))) + + if len(output) > 0 { + var actualEntries []Entry + for _, line := range bytes.Split([]byte(output), []byte("\n")) { + // Format: <mode> SP <type> SP <object> TAB <file> + tabSplit := bytes.Split(line, []byte("\t")) + require.Len(t, tabSplit, 2) + + spaceSplit := bytes.Split(tabSplit[0], []byte(" ")) + require.Len(t, spaceSplit, 3) + + path := string(tabSplit[1]) + + objectID, err := git.ObjectHashSHA1.FromHex(string(spaceSplit[2])) + require.NoError(t, err) + + var objectType ObjectType + switch string(spaceSplit[1]) { + case "blob": + objectType = Blob + case "tree": + objectType = Tree + case "commit": + objectType = Submodule + default: + t.Errorf("unknowr type %s", spaceSplit[1]) + } + + actualEntries = append(actualEntries, Entry{ + ObjectID: objectID, + Mode: spaceSplit[0], + Path: path, + Type: objectType, + }) + } + + require.Equal(t, tc.expectedEntries, actualEntries) + } + }) + } +} diff --git a/internal/gitaly/service/commit/list_files.go b/internal/gitaly/service/commit/list_files.go index 9a1da2197..75e47f17f 100644 --- a/internal/gitaly/service/commit/list_files.go +++ b/internal/gitaly/service/commit/list_files.go @@ -6,7 +6,7 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus" log "github.com/sirupsen/logrus" "gitlab.com/gitlab-org/gitaly/v15/internal/git" - "gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/tree" "gitlab.com/gitlab-org/gitaly/v15/internal/helper" "gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk" "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" @@ -81,7 +81,7 @@ func (s *server) listFiles(repo git.RepositoryExecutor, revision string, stream sender := chunk.New(&listFilesSender{stream: stream}) - for parser := lstree.NewParser(cmd, git.ObjectHashSHA1); ; { + for parser := tree.NewParser(cmd, git.ObjectHashSHA1); ; { entry, err := parser.NextEntry() if err == io.EOF { break @@ -90,7 +90,7 @@ func (s *server) listFiles(repo git.RepositoryExecutor, revision string, stream return err } - if entry.Type != lstree.Blob { + if entry.Type != tree.Blob { continue } diff --git a/internal/gitaly/service/commit/list_last_commits_for_tree.go b/internal/gitaly/service/commit/list_last_commits_for_tree.go index 7e1c35b83..0843c0ee2 100644 --- a/internal/gitaly/service/commit/list_last_commits_for_tree.go +++ b/internal/gitaly/service/commit/list_last_commits_for_tree.go @@ -8,7 +8,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/command" "gitlab.com/gitlab-org/gitaly/v15/internal/git" "gitlab.com/gitlab-org/gitaly/v15/internal/git/log" - "gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/tree" "gitlab.com/gitlab-org/gitaly/v15/internal/helper" "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" ) @@ -50,7 +50,7 @@ func (s *server) listLastCommitsForTree(in *gitalypb.ListLastCommitsForTreeReque offset := int(in.GetOffset()) if offset >= len(entries) { offset = 0 - entries = lstree.Entries{} + entries = tree.Entries{} } limit := offset + int(in.GetLimit()) @@ -86,8 +86,8 @@ func (s *server) listLastCommitsForTree(in *gitalypb.ListLastCommitsForTreeReque return sendCommitsForTree(batch, stream) } -func getLSTreeEntries(parser *lstree.Parser) (lstree.Entries, error) { - entries := lstree.Entries{} +func getLSTreeEntries(parser *tree.Parser) (tree.Entries, error) { + entries := tree.Entries{} for { entry, err := parser.NextEntry() @@ -107,7 +107,7 @@ func getLSTreeEntries(parser *lstree.Parser) (lstree.Entries, error) { return entries, nil } -func (s *server) newLSTreeParser(in *gitalypb.ListLastCommitsForTreeRequest, stream gitalypb.CommitService_ListLastCommitsForTreeServer) (*command.Command, *lstree.Parser, error) { +func (s *server) newLSTreeParser(in *gitalypb.ListLastCommitsForTreeRequest, stream gitalypb.CommitService_ListLastCommitsForTreeServer) (*command.Command, *tree.Parser, error) { path := string(in.GetPath()) if path == "" || path == "/" { path = "." @@ -123,7 +123,7 @@ func (s *server) newLSTreeParser(in *gitalypb.ListLastCommitsForTreeRequest, str return nil, nil, err } - return cmd, lstree.NewParser(cmd, git.ObjectHashSHA1), nil + return cmd, tree.NewParser(cmd, git.ObjectHashSHA1), nil } func sendCommitsForTree(batch []*gitalypb.ListLastCommitsForTreeResponse_CommitForTree, stream gitalypb.CommitService_ListLastCommitsForTreeServer) error { diff --git a/internal/gitaly/service/commit/tree_entries.go b/internal/gitaly/service/commit/tree_entries.go index 5549631a0..183e4de73 100644 --- a/internal/gitaly/service/commit/tree_entries.go +++ b/internal/gitaly/service/commit/tree_entries.go @@ -13,7 +13,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/git" "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/tree" "gitlab.com/gitlab-org/gitaly/v15/internal/helper/chunk" "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" @@ -109,19 +109,19 @@ func (s *server) sendTreeEntries( return err } - treeEntries, err := lstree.ListEntries(ctx, repo, git.Revision(revision), &lstree.ListEntriesConfig{ + treeEntries, err := tree.ListEntries(ctx, repo, git.Revision(revision), &tree.ListEntriesConfig{ Recursive: recursive, RelativePath: path, }) if err != nil { // Design wart: we do not return an error if the request does not // point to a tree object, but just return nothing. - if errors.Is(err, lstree.ErrNotTreeish) { + if errors.Is(err, tree.ErrNotTreeish) { return nil } // Same if we try to list tree entries of a revision which doesn't exist. - if errors.Is(err, lstree.ErrNotExist) { + if errors.Is(err, tree.ErrNotExist) { return nil } @@ -244,16 +244,16 @@ func sortTrees(entries []*gitalypb.TreeEntry, sortBy gitalypb.GetTreeEntriesRequ } // This is used to match the sorting order given by getLSTreeEntries -func toLsTreeEnum(input gitalypb.TreeEntry_EntryType) (lstree.ObjectType, error) { +func toLsTreeEnum(input gitalypb.TreeEntry_EntryType) (tree.ObjectType, error) { switch input { case gitalypb.TreeEntry_TREE: - return lstree.Tree, nil + return tree.Tree, nil case gitalypb.TreeEntry_COMMIT: - return lstree.Submodule, nil + return tree.Submodule, nil case gitalypb.TreeEntry_BLOB: - return lstree.Blob, nil + return tree.Blob, nil default: - return -1, lstree.ErrParse + return -1, tree.ErrParse } } diff --git a/internal/gitaly/service/repository/license.go b/internal/gitaly/service/repository/license.go index 2eceece15..1cfe652a6 100644 --- a/internal/gitaly/service/repository/license.go +++ b/internal/gitaly/service/repository/license.go @@ -15,7 +15,8 @@ import ( "github.com/go-enry/go-license-detector/v4/licensedb/filer" "gitlab.com/gitlab-org/gitaly/v15/internal/git" "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" - "gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/tree" + gittree "gitlab.com/gitlab-org/gitaly/v15/internal/git/tree" "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/rubyserver" "gitlab.com/gitlab-org/gitaly/v15/internal/helper" "gitlab.com/gitlab-org/gitaly/v15/internal/metadata/featureflag" @@ -195,7 +196,7 @@ func (f *gitFiler) ReadDir(string) ([]filer.File, error) { return nil, err } - tree := lstree.NewParser(cmd, git.ObjectHashSHA1) + tree := tree.NewParser(cmd, git.ObjectHashSHA1) var files []filer.File for { @@ -209,7 +210,7 @@ func (f *gitFiler) ReadDir(string) ([]filer.File, error) { // Given that we're doing a recursive listing, we skip over all types which aren't // blobs. - if entry.Type != lstree.Blob { + if entry.Type != gittree.Blob { continue } diff --git a/internal/gitaly/service/repository/search_files.go b/internal/gitaly/service/repository/search_files.go index a0511ccb3..04eaad006 100644 --- a/internal/gitaly/service/repository/search_files.go +++ b/internal/gitaly/service/repository/search_files.go @@ -9,7 +9,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v15/internal/command" "gitlab.com/gitlab-org/gitaly/v15/internal/git" - "gitlab.com/gitlab-org/gitaly/v15/internal/git/lstree" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/tree" "gitlab.com/gitlab-org/gitaly/v15/internal/helper" "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" "gitlab.com/gitlab-org/gitaly/v15/streamio" @@ -172,7 +172,7 @@ func validateSearchFilesRequest(req searchFilesRequest) error { func parseLsTree(cmd *command.Command, filter *regexp.Regexp, offset int, limit int) ([][]byte, error) { var files [][]byte var index int - parser := lstree.NewParser(cmd, git.ObjectHashSHA1) + parser := tree.NewParser(cmd, git.ObjectHashSHA1) for { path, err := parser.NextEntryPath() |