ref: 6d72372960241f776e2c667b7debdc4b509e015e
parent: 6a7fc936c4a969aa05b3941feedafe59f4bd2ffd
author: Runxi Yu <me@runxiyu.org>
date: Sat Feb 21 11:37:33 EST 2026
repository: Add current repo traversal
--- a/repository/traversal_test.go
+++ b/repository/traversal_test.go
@@ -1,6 +1,10 @@
package repository_test
import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
"testing"
"codeberg.org/lindenii/furgit/internal/testgit"
@@ -26,54 +30,116 @@
repoHarness.UpdateRef(t, "refs/heads/main", commit2)
repoHarness.SymbolicRef(t, "HEAD", "refs/heads/main")
- repo, err := repository.Open(repoHarness.Dir())
- if err != nil {- t.Fatalf("repository.Open: %v", err)- }
- defer func() { _ = repo.Close() }()+ walkRepositoryFromHead(t, repoHarness.Dir())
+ })
+}
- head, err := repo.ResolveRefFully("HEAD")- if err != nil {- t.Fatalf("ResolveRefFully(HEAD): %v", err)- }
+func TestRepositoryDepthFirstEnumerationCurrentWorktree(t *testing.T) {+ t.Parallel()
- visited := make(map[objectid.ObjectID]bool)
- queue := []objectid.ObjectID{head.ID}- objectsRead := 0
+ worktreeRoot := filepath.Clean("..")+ gitPath := filepath.Join(worktreeRoot, ".git")
- for len(queue) > 0 {- id := queue[0]
- queue = queue[1:]
+ info, err := os.Stat(gitPath)
+ if err != nil {+ t.Fatalf("stat %q: %v", gitPath, err)+ }
- if visited[id] {- continue
- }
- visited[id] = true
+ if info.IsDir() {+ walkRepositoryFromHead(t, gitPath)
+ return
+ }
- stored, err := repo.ReadStored(id)
- if err != nil {- t.Fatalf("ReadStored(%s): %v", id, err)- }
- objectsRead++
+ if !info.Mode().IsRegular() {+ t.Fatalf("%q is neither a directory nor a regular file", gitPath)+ }
- switch obj := stored.Object().(type) {- case *object.Commit:
- queue = append(queue, obj.Tree)
- queue = append(queue, obj.Parents...)
- case *object.Tree:
- for _, entry := range obj.Entries {- queue = append(queue, entry.ID)
- }
- case *object.Tag:
- queue = append(queue, obj.Target)
- case *object.Blob:
- default:
- t.Fatalf("unexpected object type: %T", obj)- }
+ content, err := os.ReadFile(gitPath)
+ if err != nil {+ t.Fatalf("read %q: %v", gitPath, err)+ }
+ line := strings.TrimSpace(string(content))
+ prefix := "gitdir: "
+ if !strings.HasPrefix(line, prefix) {+ t.Fatalf("%q file does not begin with %q", gitPath, prefix)+ }
+
+ gitdirRel := strings.TrimSpace(line[len(prefix):])
+ if gitdirRel == "" {+ t.Fatalf("%q contains empty gitdir path", gitPath)+ }
+ gitdirPath := gitdirRel
+ if !filepath.IsAbs(gitdirPath) {+ gitdirPath = filepath.Join(worktreeRoot, gitdirPath)
+ }
+ commondirPath := filepath.Join(gitdirPath, "commondir")
+ commondirContent, err := os.ReadFile(commondirPath)
+ if err != nil {+ t.Fatalf("read %q: %v", commondirPath, err)+ }
+ repoPath := strings.TrimSpace(string(commondirContent))
+ if repoPath == "" {+ t.Fatalf("%q contains empty repo path", commondirPath)+ }
+ if filepath.IsAbs(repoPath) {+ walkRepositoryFromHead(t, repoPath)
+ return
+ }
+ repoPath = filepath.Join(gitdirPath, repoPath)
+
+ walkRepositoryFromHead(t, repoPath)
+}
+
+func walkRepositoryFromHead(t *testing.T, repoPath string) {+ t.Helper()
+
+ repo, err := repository.Open(repoPath)
+ if err != nil {+ t.Fatalf("repository.Open(%q): %v", repoPath, err)+ }
+ defer func() { _ = repo.Close() }()+
+ head, err := repo.ResolveRefFully("HEAD")+ if err != nil {+ t.Fatalf("ResolveRefFully(HEAD): %v", err)+ }
+
+ visited := make(map[objectid.ObjectID]bool)
+ queue := []objectid.ObjectID{head.ID}+ objectsRead := 0
+
+ for len(queue) > 0 {+ id := queue[0]
+ queue = queue[1:]
+
+ if visited[id] {+ continue
}
+ visited[id] = true
- if objectsRead == 0 {- t.Fatalf("no objects were enumerated from HEAD")+ stored, err := repo.ReadStored(id)
+ if err != nil {+ t.Fatalf("ReadStored(%s): %v", id, err)}
- })
+ objectsRead++
+
+ switch obj := stored.Object().(type) {+ case *object.Commit:
+ queue = append(queue, obj.Tree)
+ queue = append(queue, obj.Parents...)
+ case *object.Tree:
+ for _, entry := range obj.Entries {+ queue = append(queue, entry.ID)
+ }
+ case *object.Tag:
+ queue = append(queue, obj.Target)
+ case *object.Blob:
+ default:
+ t.Fatalf("unexpected object type: %T", obj)+ }
+ }
+
+ if objectsRead == 0 {+ t.Fatalf("no objects were enumerated from HEAD (%s)", fmt.Sprintf("%q", repoPath))+ }
}
--
⑨