Add directory recursion for Add and mirror up/down commands.

Add now recursively walks directories instead of creating a single
"directory" type entry. Extract addEntry helper for reuse. Implement
MirrorUp (sync filesystem state into manifest) and MirrorDown (sync
manifest state to filesystem with untracked file cleanup). Add CLI
mirror command with up/down subcommands.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-23 23:42:58 -07:00
parent b1313c1048
commit b4bfce1291
5 changed files with 639 additions and 41 deletions

View File

@@ -135,17 +135,29 @@ func TestAddDirectory(t *testing.T) {
if err := os.Mkdir(testDir, 0o755); err != nil {
t.Fatalf("creating test dir: %v", err)
}
testFile := filepath.Join(testDir, "inside.txt")
if err := os.WriteFile(testFile, []byte("inside"), 0o644); err != nil {
t.Fatalf("writing file inside dir: %v", err)
}
if err := g.Add([]string{testDir}); err != nil {
t.Fatalf("Add: %v", err)
}
entry := g.manifest.Files[0]
if entry.Type != "directory" {
t.Errorf("expected type directory, got %s", entry.Type)
if len(g.manifest.Files) != 1 {
t.Fatalf("expected 1 file, got %d", len(g.manifest.Files))
}
if entry.Hash != "" {
t.Error("directories should have no hash")
entry := g.manifest.Files[0]
if entry.Type != "file" {
t.Errorf("expected type file, got %s", entry.Type)
}
if entry.Hash == "" {
t.Error("expected non-empty hash")
}
expectedPath := toTildePath(testFile)
if entry.Path != expectedPath {
t.Errorf("expected path %s, got %s", expectedPath, entry.Path)
}
}