Commit 690a0542e1

690a0542e1b8d60d377bbdd3ddbfc17260a098d3

parent: 9df917e73a

Verified · cmc

cmc <hello@cleberg.net> · 2026-09-28 21:39 UTC

gitutil: FsckConnectivity

Ref #259

Layout: unified · split

internal/gitutil/fsck_test.go added +31
@@ -0,0 +1,31 @@
1package gitutil
2
3import (
4 "os"
5 "os/exec"
6 "path/filepath"
7 "strings"
8 "testing"
9)
10
11func TestFsckConnectivityFindsAMissingObject(t *testing.T) {
12 dir := t.TempDir()
13 git(t, dir, "init", "-q", "-b", "main")
14 write(t, dir, "a.txt", "a\n")
15 git(t, dir, "add", "a.txt")
16 git(t, dir, "commit", "-q", "-m", "one")
17 if err := FsckConnectivity(dir); err != nil {
18 t.Fatalf("intact repository: %v", err)
19 }
20 out, err := exec.Command("git", "-C", dir, "rev-parse", "HEAD:a.txt").Output()
21 if err != nil {
22 t.Fatal(err)
23 }
24 blob := strings.TrimSpace(string(out))
25 if err := os.Remove(filepath.Join(dir, ".git", "objects", blob[:2], blob[2:])); err != nil {
26 t.Fatal(err)
27 }
28 if err := FsckConnectivity(dir); err == nil {
29 t.Fatal("a repository missing a blob passed")
30 }
31}
internal/gitutil/merge.go +11
@@ -66,6 +66,17 @@ func PruneNow(dir string) error {
6666 return nil
6767}
6868
69// FsckConnectivity checks that every object reachable from the
70// repository's refs is present, without reading blob contents. A backup
71// verify runs it on each archived repository (#259).
72func FsckConnectivity(dir string) error {
73 cmd := exec.Command(toolpath.Look("git"), "-C", dir, "fsck", "--connectivity-only", "--no-progress", "--no-dangling")
74 if out, err := cmd.CombinedOutput(); err != nil {
75 return fmt.Errorf("fsck --connectivity-only: %v\n%s", err, out)
76 }
77 return nil
78}
79
6980// RevListRange returns commits in old..new, newest first.
7081func RevListRange(dir, old, new string) ([]string, error) {
7182 cmd := exec.Command(toolpath.Look("git"), "-C", dir, "rev-list", "--end-of-options", new, "^"+old)