From b00925bf9e483e56e1af2c5ca111f726a18bfbd5 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 12 May 2026 15:28:42 +0000 Subject: [PATCH] git: assert objects stay packed in the layer Guards against a regression where go-git would unpack the fetched packfile into loose objects, which would put the repo's whole decompressed contents in memory. https://claude.ai/code/session_01Jfhuuwb5haNaasc9hs53jw --- cmd/git/build_test.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/cmd/git/build_test.go b/cmd/git/build_test.go index 298e1f5..9b383b4 100644 --- a/cmd/git/build_test.go +++ b/cmd/git/build_test.go @@ -130,13 +130,22 @@ func TestGitLayer(t *testing.T) { } } hasPack := false + objectsDir := path.Join(prefix, ".git", "objects") for name := range got { - if strings.HasPrefix(name, path.Join(prefix, ".git", "objects", "pack")+"/") && strings.HasSuffix(name, ".pack") { + if strings.HasPrefix(name, path.Join(objectsDir, "pack")+"/") && strings.HasSuffix(name, ".pack") { hasPack = true } + // The objects must stay packed: nothing should be unpacked into loose + // objects/<2-hex>/<38-hex>. If that ever happens the whole repo's + // decompressed contents would be sitting in memory. + if rest, ok := strings.CutPrefix(name, objectsDir+"/"); ok { + if dir, _, found := strings.Cut(rest, "/"); found && dir != "pack" && dir != "info" { + t.Errorf("loose object in layer: %s", name) + } + } } if !hasPack { - t.Errorf("layer has no packfile under %s/.git/objects/pack/", prefix) + t.Errorf("layer has no packfile under %s/pack/", objectsDir) } // Worktree files must match a real checkout exactly.