aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--repository/traversal_test.go148
1 files changed, 107 insertions, 41 deletions
diff --git a/repository/traversal_test.go b/repository/traversal_test.go
index 61560fde..0e5f5ec4 100644
--- 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 @@ func TestRepositoryDepthFirstEnumerationFromHEAD(t *testing.T) {
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))
+ }
}