Work in memory¶
The same API drives a real checkout or a repository that exists only in RAM. The
in-memory backend uses go-git's memfs and memory.Storage — nothing touches disk.
Why you'd want it¶
- No cleanup. There are no temporary directories to create, track, or delete — and none left behind when a process dies mid-run.
- Speed. All I/O stays in memory, which is markedly faster for small and medium repositories.
- Security. Nothing sensitive is written to shared disk. That matters on CI runners and multi-tenant hosts, where a temp directory may outlive your job or be readable by others.
Typical uses: temporary analysis, code generation, and CI pipelines where filesystem artefacts are undesirable.
Choosing a backend¶
// explicitly in memory
gitRepo, worktree, err := r.OpenInMemory(url, "main")
// explicitly on disk
gitRepo, worktree, err := r.OpenLocal(path, "main")
// caller decides by value
gitRepo, worktree, err := r.Open(repo.InMemoryRepo, url, "main",
repo.WithShallowClone(1),
repo.WithSingleBranch("main"),
)
Open takes a RepoType so a program can select the backend from configuration or a
flag without branching. SourceIs reports which one is in use.
Clone options¶
| Option | Effect |
|---|---|
WithShallowClone(depth int) |
Fetch only the last depth commits |
WithSingleBranch(branch string) |
Limit the fetch to one branch |
WithNoTags() |
Skip fetching tags |
WithRecurseSubmodules() |
Initialise submodules after cloning |
These matter more in memory than on disk, because everything you fetch stays resident.
Mind the memory ceiling
A large repository — especially one with heavy binary history — can consume all
available RAM. Past a few hundred megabytes, prefer a local shallow clone
(WithShallowClone(1)) over an in-memory one.
In-memory repositories make excellent test fixtures¶
Because it is a real repository, code under test runs against real git behaviour — no mock to drift from reality — while staying hermetic and fast:
r, _ := repo.NewRepo(repo.Settings{FS: afero.NewMemMapFs()})
_, _, err := r.OpenInMemory(url, "main")
fs, _ := r.WorkFS()
_ = afero.WriteFile(fs, "main.go", []byte("package main"), 0o644)
_ = r.AddAll()
_, _ = r.Commit("initial", nil)
Combined with the worktree filesystem, an afero-based "commit-on-save" routine runs verbatim over an in-memory repository — the same code path as production. See testing for when to prefer this over a mock.