aboutsummaryrefslogtreecommitdiff
path: root/internal/testgit
diff options
context:
space:
mode:
authorGravatar Runxi Yu2026-03-05 18:24:40 +0800
committerGravatar Runxi Yu2026-03-05 19:05:47 +0800
commit57f1818d547f2f1dca38033b4e29f62d89ef80f9 (patch)
tree88d55ac38e2427860bf380c8cce42fcb3bb1e9ee /internal/testgit
parentinternal/compress/zlib: Use flate's compression consumed counter (diff)
signatureNo signature
format/pack/ingest: Init
Diffstat (limited to 'internal/testgit')
-rw-r--r--internal/testgit/repo_pack_objects_is_thin.go75
1 files changed, 75 insertions, 0 deletions
diff --git a/internal/testgit/repo_pack_objects_is_thin.go b/internal/testgit/repo_pack_objects_is_thin.go
new file mode 100644
index 00000000..afc704d1
--- /dev/null
+++ b/internal/testgit/repo_pack_objects_is_thin.go
@@ -0,0 +1,75 @@
+package testgit
+
+import (
+ "os/exec"
+ "strings"
+ "testing"
+)
+
+// PackObjectsIsThin reports whether git emits one thin pack for the given revs.
+//
+// It streams `git pack-objects --stdout --revs --thin` into `git index-pack
+// --stdin` in one scratch bare repository. A failure in index-pack due to
+// unresolved deltas is treated as confirmation that the emitted pack is thin.
+func (testRepo *TestRepo) PackObjectsIsThin(tb testing.TB, revs []string) bool {
+ tb.Helper()
+
+ scratch := NewRepo(tb, RepoOptions{ObjectFormat: testRepo.algo, Bare: true})
+
+ packArgs := []string{"pack-objects", "--stdout", "--revs", "--thin"}
+ //nolint:noctx
+ packCmd := exec.Command("git", packArgs...) //#nosec G204
+ packCmd.Dir = testRepo.dir
+ packCmd.Env = testRepo.env
+ packCmd.Stdin = strings.NewReader(strings.Join(revs, "\n") + "\n")
+ packStderr := &strings.Builder{}
+ packCmd.Stderr = packStderr
+
+ packStdout, err := packCmd.StdoutPipe()
+ if err != nil {
+ tb.Fatalf("git %v stdout pipe: %v", packArgs, err)
+ }
+
+ indexArgs := []string{"index-pack", "--stdin"}
+ //nolint:noctx
+ indexCmd := exec.Command("git", indexArgs...) //#nosec G204
+ indexCmd.Dir = scratch.dir
+ indexCmd.Env = scratch.env
+ indexCmd.Stdin = packStdout
+ indexStderr := &strings.Builder{}
+ indexCmd.Stderr = indexStderr
+
+ err = indexCmd.Start()
+ if err != nil {
+ tb.Fatalf("git %v start failed: %v", indexArgs, err)
+ }
+
+ err = packCmd.Start()
+ if err != nil {
+ _ = indexCmd.Process.Kill()
+ _ = indexCmd.Wait()
+ tb.Fatalf("git %v start failed: %v", packArgs, err)
+ }
+
+ packErr := packCmd.Wait()
+ if packErr != nil {
+ tb.Fatalf("git %v failed: %v\n%s", packArgs, packErr, packStderr.String())
+ }
+
+ indexErr := indexCmd.Wait()
+ if indexErr == nil {
+ return false
+ }
+
+ stderr := strings.ToLower(indexStderr.String())
+ if strings.Contains(stderr, "unresolved") && strings.Contains(stderr, "delta") {
+ return true
+ }
+ if strings.Contains(stderr, "missing") && strings.Contains(stderr, "base") {
+ return true
+ }
+
+ tb.Fatalf("git %v failed unexpectedly: %v\n%s", indexArgs, indexErr, indexStderr.String())
+
+ return false
+}