Read-only mirror. Development happens at git.bnema.dev; issues and pull requests are closed here.
Features
- Refs, loose and packed objects, trees, blobs and commits
- History in
git log order, with git log -- path simplification
- Commit-graph and changed-path Bloom filters for fast history
- Safe for concurrent use; no allocation per commit after warm-up
Status: early development, no stable API.
Usage
import git "bnema.dev/ermite-git"
repo, err := git.Open("/srv/repos/project.git") // bare, or a ".git" directory
if err != nil {
return err // errors.Is(err, git.ErrUnsupported) → use the git binary
}
defer repo.Close()
id, _ := repo.Resolve("main")
commitID, _ := repo.PeelToCommit(id)
var c git.Commit // reuse it
_ = repo.ReadCommit(commitID, &c)
_ = repo.ReadTree(c.Tree, func(e git.Entry) bool {
fmt.Printf("%s %s\n", e.Mode, e.Name) // e.Name is valid during the callback only
return true
})
for c, err := range repo.Walk(ctx, commitID, git.WalkOptions{Path: "pkg/gui", Limit: 50}) {
if err != nil {
return err
}
fmt.Println(c.ID) // c is reused: valid until the next iteration
}
// last commit of each entry of a directory, in one walk
ids, err := repo.LastCommits(ctx, commitID, "pkg", []string{"gui", "commands"})
Call Refresh after the repository changes (push, repack) to see new refs and packs.
Open returns ErrUnsupported for SHA-256, reftable, other extensions.*, shallow, grafts, replace refs, alternates, partial clones, and incremental or stale multi-pack-index.
Known limits: docs/limits.md.
Test
Tests compare with the git binary, 2.45 or newer (skipped without it).
go test -race ./...
ERMITE_GIT_BENCH_REPO=/path/to/repo/.git go test -run TestRealRepository -v # every object vs git cat-file
go test -run '^$' -bench . -benchmem
go test -run '^$' -fuzz FuzzParseCommit -fuzztime 30s
License
MIT. See LICENSE.
source
1<h1 align="center">ermite-git</h1>
2
3<p align="center">
4 <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue?style=flat-square" alt="License: MIT"></a>
5 <a href="https://github.com/bnema/ermite-git/commits/main"><img src="https://badgen.net/github/last-commit/bnema/ermite-git/main?icon=github" alt="Last commit"></a>
6 <a href="https://github.com/bnema/ermite-git/stargazers"><img src="https://badgen.net/github/stars/bnema/ermite-git?icon=github" alt="GitHub stars"></a>
7</p>
8
9<p align="center">A fast, read-only Git repository reader for Go. Standard library only.</p>
10
11> Read-only mirror. Development happens at git.bnema.dev; issues and pull requests are closed here.
12
13---
14
15## Features
16
17- Refs, loose and packed objects, trees, blobs and commits
18- History in `git log` order, with `git log -- path` simplification
19- Commit-graph and changed-path Bloom filters for fast history
20- Safe for concurrent use; no allocation per commit after warm-up
21
22Status: early development, no stable API.
23
24## Usage
25
26```go
27import git "bnema.dev/ermite-git"
28
29repo, err := git.Open("/srv/repos/project.git") // bare, or a ".git" directory
30if err != nil {
31 return err // errors.Is(err, git.ErrUnsupported) → use the git binary
32}
33defer repo.Close()
34
35id, _ := repo.Resolve("main")
36commitID, _ := repo.PeelToCommit(id)
37
38var c git.Commit // reuse it
39_ = repo.ReadCommit(commitID, &c)
40_ = repo.ReadTree(c.Tree, func(e git.Entry) bool {
41 fmt.Printf("%s %s\n", e.Mode, e.Name) // e.Name is valid during the callback only
42 return true
43})
44
45for c, err := range repo.Walk(ctx, commitID, git.WalkOptions{Path: "pkg/gui", Limit: 50}) {
46 if err != nil {
47 return err
48 }
49 fmt.Println(c.ID) // c is reused: valid until the next iteration
50}
51
52// last commit of each entry of a directory, in one walk
53ids, err := repo.LastCommits(ctx, commitID, "pkg", []string{"gui", "commands"})
54```
55
56Call `Refresh` after the repository changes (push, repack) to see new refs and packs.
57
58`Open` returns `ErrUnsupported` for SHA-256, reftable, other `extensions.*`, shallow, grafts, replace refs, alternates, partial clones, and incremental or stale multi-pack-index.
59
60Known limits: [docs/limits.md](docs/limits.md).
61
62## Test
63
64Tests compare with the `git` binary, 2.45 or newer (skipped without it).
65
66```sh
67go test -race ./...
68ERMITE_GIT_BENCH_REPO=/path/to/repo/.git go test -run TestRealRepository -v # every object vs git cat-file
69go test -run '^$' -bench . -benchmem
70go test -run '^$' -fuzz FuzzParseCommit -fuzztime 30s
71```
72
73## License
74
75MIT. See [LICENSE](LICENSE).