main de06cbd

README.md RawHistoryFolder

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).

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 2

↑↓ moveenter openesc close