Resolve committed module identity from Git objects
This commit is contained in:
@@ -123,6 +123,46 @@ func ReadCommitFile(ctx context.Context, repositoryDir, commit, name string) ([]
|
||||
return []byte(content), nil
|
||||
}
|
||||
|
||||
// CommittedPaths resolves individual paths from captured objects. It requests
|
||||
// only metadata and link contents needed for traversal.
|
||||
func CommittedPaths(repositoryDir, commit string) PathResolver {
|
||||
metadata := make(map[string]TreeEntry)
|
||||
return PathResolver{
|
||||
RepositoryDir: repositoryDir,
|
||||
Lookup: func(ctx context.Context, name string) (TreeEntry, bool, error) {
|
||||
if err := ctx.Err(); err != nil {
|
||||
return TreeEntry{}, false, err
|
||||
}
|
||||
if entry, seen := metadata[name]; seen {
|
||||
return entry, entry.ObjectID != "", nil
|
||||
}
|
||||
if !validObjectID(commit) || name == "" || path.IsAbs(name) || path.Clean(name) != name || name == ".." || strings.HasPrefix(name, "../") {
|
||||
return TreeEntry{}, false, fmt.Errorf("invalid committed path identity %q at %q", name, commit)
|
||||
}
|
||||
output, err := readLocalObjects(ctx, repositoryDir, nil, "--literal-pathspecs", "ls-tree", "-z", "--full-tree", commit, "--", name)
|
||||
if err != nil {
|
||||
return TreeEntry{}, false, fmt.Errorf("inspect committed path %q: %w", name, err)
|
||||
}
|
||||
entries, err := parseTreeEntries(output)
|
||||
if err != nil {
|
||||
return TreeEntry{}, false, err
|
||||
}
|
||||
for _, entry := range entries {
|
||||
if entry.Path == name {
|
||||
metadata[name] = entry
|
||||
return entry, true, nil
|
||||
}
|
||||
}
|
||||
metadata[name] = TreeEntry{}
|
||||
return TreeEntry{}, false, nil
|
||||
},
|
||||
ReadLink: func(ctx context.Context, entry TreeEntry) (string, error) {
|
||||
contents, err := ReadBlob(ctx, repositoryDir, entry.ObjectID)
|
||||
return string(contents), err
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ReadTree enumerates all entries in a commit and records blob sizes. Paths
|
||||
// are NUL-delimited by Git so whitespace in a filename is preserved.
|
||||
func ReadTree(ctx context.Context, repositoryDir, commit string) ([]TreeEntry, error) {
|
||||
|
||||
Reference in New Issue
Block a user