aboutsummaryrefslogtreecommitdiff
path: root/objectstore
diff options
context:
space:
mode:
authorGravatar Runxi Yu2026-02-21 16:49:01 +0800
committerGravatar Runxi Yu2026-02-21 16:49:01 +0800
commitd31ca0f64be56cdc79d2da076b34d87eb7d161a2 (patch)
tree7df7460fb42b9fb7e639c0aca390e17248df909f /objectstore
parentrepository: Add current repo traversal (diff)
signatureNo signature
objectstore/packed: Add test for mismatched verify-pick -v size
Diffstat (limited to 'objectstore')
-rw-r--r--objectstore/packed/read_test.go78
1 files changed, 78 insertions, 0 deletions
diff --git a/objectstore/packed/read_test.go b/objectstore/packed/read_test.go
index 9a7f2e4a..ef0157da 100644
--- a/objectstore/packed/read_test.go
+++ b/objectstore/packed/read_test.go
@@ -3,7 +3,10 @@ package packed_test
import (
"bytes"
"errors"
+ "fmt"
"os"
+ "path/filepath"
+ "strconv"
"strings"
"testing"
@@ -150,3 +153,78 @@ func TestPackedStoreInvalidAlgorithm(t *testing.T) {
t.Fatalf("packed.New invalid algorithm error = %v", err)
}
}
+
+func TestPackedStoreReadHeaderUsesResolvedObjectSizeForDelta(t *testing.T) {
+ t.Parallel()
+ testgit.ForEachAlgorithm(t, func(t *testing.T, algo objectid.Algorithm) { //nolint:thelper
+ testRepo := testgit.NewRepo(t, testgit.RepoOptions{ObjectFormat: algo, Bare: true})
+
+ var parent objectid.ObjectID
+ for i := range 96 {
+ content := strings.Repeat("common-line-"+strconv.Itoa(i%7)+"\n", 384) + fmt.Sprintf("tail-%03d\n", i)
+ _, treeID := testRepo.MakeSingleFileTree(t, "file.txt", []byte(content))
+ if i == 0 {
+ parent = testRepo.CommitTree(t, treeID, "delta-header-size-0")
+ continue
+ }
+ parent = testRepo.CommitTree(t, treeID, fmt.Sprintf("delta-header-size-%03d", i), parent)
+ }
+ testRepo.UpdateRef(t, "refs/heads/main", parent)
+ testRepo.Repack(t, "-a", "-d", "-f", "--window=128", "--depth=128")
+
+ deltaID, wantResolvedSize := findDeltaObjectWithResolvedSizeMismatch(t, testRepo, algo)
+ store := openPackedStore(t, testRepo.Dir(), algo)
+
+ _, gotSize, err := store.ReadHeader(deltaID)
+ if err != nil {
+ t.Fatalf("ReadHeader(%s): %v", deltaID, err)
+ }
+ if gotSize != wantResolvedSize {
+ t.Fatalf("ReadHeader(%s) size = %d, want resolved size %d", deltaID, gotSize, wantResolvedSize)
+ }
+ })
+}
+
+func findDeltaObjectWithResolvedSizeMismatch(t *testing.T, testRepo *testgit.TestRepo, algo objectid.Algorithm) (objectid.ObjectID, int64) {
+ t.Helper()
+
+ idxFiles, err := filepath.Glob(filepath.Join(testRepo.Dir(), "objects", "pack", "*.idx"))
+ if err != nil {
+ t.Fatalf("Glob idx: %v", err)
+ }
+ if len(idxFiles) == 0 {
+ t.Fatalf("no idx files found")
+ }
+
+ verifyOut := testRepo.Run(t, "verify-pack", "-v", idxFiles[0])
+ for _, line := range strings.Split(strings.TrimSpace(verifyOut), "\n") {
+ fields := strings.Fields(line)
+ if len(fields) < 7 {
+ continue
+ }
+
+ idHex := fields[0]
+ deltaStreamSize, err := strconv.ParseInt(fields[2], 10, 64)
+ if err != nil {
+ continue
+ }
+
+ resolvedSizeStr := testRepo.Run(t, "cat-file", "-s", idHex)
+ resolvedSize, err := strconv.ParseInt(strings.TrimSpace(resolvedSizeStr), 10, 64)
+ if err != nil {
+ t.Fatalf("parse cat-file size for %s: %v", idHex, err)
+ }
+ if deltaStreamSize == resolvedSize {
+ continue
+ }
+
+ id, err := objectid.ParseHex(algo, idHex)
+ if err != nil {
+ t.Fatalf("ParseHex(%s): %v", idHex, err)
+ }
+ return id, resolvedSize
+ }
+
+ t.Fatalf("did not find a delta object with mismatched stream/resolved size")
+ return objectid.ObjectID{}, 0
+}