Resolve committed module identity from Git objects

This commit is contained in:
2026-10-10 14:20:09 +00:00
parent 7eebbbbfc3
commit 54cc6baf95
13 changed files with 478 additions and 158 deletions

View File

@@ -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) {