shithub: furgit

ref: 3ce59c3248dec0eb0f918c42f37f53bc2ac20425
dir: /internal/testgit/repo_pack_objects_is_thin.go/

View raw version
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
}