aboutsummaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorGravatar Runxi Yu2026-03-06 08:05:51 +0800
committerGravatar Runxi Yu2026-03-06 10:00:35 +0800
commite15054a4f93fc54806e84aa7036e60168e78e823 (patch)
treeb576dcb1d3368324e7ca73ca0fe79dd8865c5524 /internal
parentinternal/intconv: Add Uint32ToUint8 (diff)
signatureNo signature
format/commitgraph: Add initial commit-graph support
Diffstat (limited to 'internal')
-rw-r--r--internal/intconv/intconv.go9
-rw-r--r--internal/testgit/repo_commit_graph_write.go13
-rw-r--r--internal/testgit/repo_from_fixture.go35
-rw-r--r--internal/testgit/repo_new.go24
-rw-r--r--internal/testgit/repo_properties.go5
-rw-r--r--internal/testgit/repo_rev_list.go37
6 files changed, 113 insertions, 10 deletions
diff --git a/internal/intconv/intconv.go b/internal/intconv/intconv.go
index ab9d5c63..08530265 100644
--- a/internal/intconv/intconv.go
+++ b/internal/intconv/intconv.go
@@ -86,3 +86,12 @@ func Uint32ToUint8(v uint32) (uint8, error) {
return uint8(v), nil
}
+
+// Uint32ToInt converts v to int, returning an error if it overflows.
+func Uint32ToInt(v uint32) (int, error) {
+ if uint64(v) > uint64(math.MaxInt) {
+ return 0, fmt.Errorf("intconv: uint32 %d overflows int", v)
+ }
+
+ return int(v), nil
+}
diff --git a/internal/testgit/repo_commit_graph_write.go b/internal/testgit/repo_commit_graph_write.go
new file mode 100644
index 00000000..13221f87
--- /dev/null
+++ b/internal/testgit/repo_commit_graph_write.go
@@ -0,0 +1,13 @@
+package testgit
+
+import "testing"
+
+// CommitGraphWrite runs "git commit-graph write" with args in the repository.
+func (testRepo *TestRepo) CommitGraphWrite(tb testing.TB, args ...string) {
+ tb.Helper()
+
+ cmdArgs := make([]string, 0, len(args)+3)
+ cmdArgs = append(cmdArgs, "commit-graph", "write")
+ cmdArgs = append(cmdArgs, args...)
+ _ = testRepo.Run(tb, cmdArgs...)
+}
diff --git a/internal/testgit/repo_from_fixture.go b/internal/testgit/repo_from_fixture.go
new file mode 100644
index 00000000..887bf9a3
--- /dev/null
+++ b/internal/testgit/repo_from_fixture.go
@@ -0,0 +1,35 @@
+package testgit
+
+import (
+ "io/fs"
+ "os"
+ "testing"
+
+ "codeberg.org/lindenii/furgit/objectid"
+)
+
+// NewRepoFromFixture copies one existing repository fixture into a temp dir.
+func NewRepoFromFixture(tb testing.TB, algo objectid.Algorithm, fixtureDir string) *TestRepo {
+ tb.Helper()
+
+ if algo.Size() == 0 {
+ tb.Fatalf("invalid algorithm: %v", algo)
+ }
+
+ dst := tb.TempDir()
+ srcFS := os.DirFS(fixtureDir)
+ err := copyFS(dst, srcFS)
+ if err != nil {
+ tb.Fatalf("copy fixture %q: %v", fixtureDir, err)
+ }
+
+ return &TestRepo{
+ dir: dst,
+ algo: algo,
+ env: defaultEnv(),
+ }
+}
+
+func copyFS(dst string, src fs.FS) error {
+ return os.CopyFS(dst, src)
+}
diff --git a/internal/testgit/repo_new.go b/internal/testgit/repo_new.go
index 8a71e406..4ae80393 100644
--- a/internal/testgit/repo_new.go
+++ b/internal/testgit/repo_new.go
@@ -32,16 +32,7 @@ func NewRepo(tb testing.TB, opts RepoOptions) *TestRepo {
testRepo := &TestRepo{
dir: dir,
algo: algo,
- env: append(os.Environ(),
- "GIT_CONFIG_GLOBAL=/dev/null",
- "GIT_CONFIG_SYSTEM=/dev/null",
- "GIT_AUTHOR_NAME=Test Author",
- "GIT_AUTHOR_EMAIL=test@example.org",
- "GIT_COMMITTER_NAME=Test Committer",
- "GIT_COMMITTER_EMAIL=committer@example.org",
- "GIT_AUTHOR_DATE=1234567890 +0000",
- "GIT_COMMITTER_DATE=1234567890 +0000",
- ),
+ env: defaultEnv(),
}
args := []string{"init", "--object-format=" + algo.String()}
@@ -58,3 +49,16 @@ func NewRepo(tb testing.TB, opts RepoOptions) *TestRepo {
return testRepo
}
+
+func defaultEnv() []string {
+ return append(os.Environ(),
+ "GIT_CONFIG_GLOBAL=/dev/null",
+ "GIT_CONFIG_SYSTEM=/dev/null",
+ "GIT_AUTHOR_NAME=Test Author",
+ "GIT_AUTHOR_EMAIL=test@example.org",
+ "GIT_COMMITTER_NAME=Test Committer",
+ "GIT_COMMITTER_EMAIL=committer@example.org",
+ "GIT_AUTHOR_DATE=1234567890 +0000",
+ "GIT_COMMITTER_DATE=1234567890 +0000",
+ )
+}
diff --git a/internal/testgit/repo_properties.go b/internal/testgit/repo_properties.go
index 47123ee8..3a489124 100644
--- a/internal/testgit/repo_properties.go
+++ b/internal/testgit/repo_properties.go
@@ -11,3 +11,8 @@ func (testRepo *TestRepo) Dir() string {
func (testRepo *TestRepo) Algorithm() objectid.Algorithm {
return testRepo.algo
}
+
+// Env returns a copy of the environment used for git subprocesses.
+func (testRepo *TestRepo) Env() []string {
+ return append([]string(nil), testRepo.env...)
+}
diff --git a/internal/testgit/repo_rev_list.go b/internal/testgit/repo_rev_list.go
new file mode 100644
index 00000000..d3adf5a0
--- /dev/null
+++ b/internal/testgit/repo_rev_list.go
@@ -0,0 +1,37 @@
+package testgit
+
+import (
+ "strings"
+ "testing"
+
+ "codeberg.org/lindenii/furgit/objectid"
+)
+
+// RevList runs "git rev-list" with args and parses one object ID per line.
+func (testRepo *TestRepo) RevList(tb testing.TB, args ...string) []objectid.ObjectID {
+ tb.Helper()
+
+ cmdArgs := make([]string, 0, len(args)+1)
+ cmdArgs = append(cmdArgs, "rev-list")
+ cmdArgs = append(cmdArgs, args...)
+ out := testRepo.Run(tb, cmdArgs...)
+
+ lines := strings.Split(strings.TrimSpace(out), "\n")
+
+ outIDs := make([]objectid.ObjectID, 0, len(lines))
+ for _, line := range lines {
+ line = strings.TrimSpace(line)
+ if line == "" {
+ continue
+ }
+
+ id, err := objectid.ParseHex(testRepo.algo, line)
+ if err != nil {
+ tb.Fatalf("parse rev-list oid %q: %v", line, err)
+ }
+
+ outIDs = append(outIDs, id)
+ }
+
+ return outIDs
+}