π Read the full documentation at grafana.github.io/nanogit
nanogit is a lightweight Git client library for Go, built for services that read from and write to Git repositories over HTTPS β with no local clone, no .git directory, and no git binary. It speaks the Git Smart HTTP Protocol v2 directly, so it works with GitHub, GitLab, Bitbucket, Gitea, and any other server that supports protocol v2.
Grafana built nanogit to power Git Sync, which syncs dashboards with tenants' own Git repositories from inside Grafana's multitenant backend β a workload where cloning every repository to disk is not an option. Read the full story in Why nanogit exists.
- Stateless β reads and writes Git objects directly over HTTPS; nothing is persisted locally, so there is no per-repository state to store, clean up, or keep consistent across replicas
- Works with any protocol v2 server β one code path for GitHub, GitLab, Bitbucket, Gitea, and self-hosted servers; token-based auth, no SSH key management
- Essential operations β refs, blobs, trees, commits, diffs, staged writes, and shallow clones with glob-based path filtering
- Memory-efficient β streaming packfile processing and configurable memory/disk/auto writing modes for bulk operations
- Fast β orders of magnitude faster and leaner than a full Git implementation for common server-side operations (benchmarks below)
- Commit signing β sign commits with GPG, SSH, or S/MIME keys
- Pluggable β object storage (caching) and retry policies are injected via context, with sensible defaults
Use nanogit when your code runs server-side and talks to Git over HTTPS:
- GitOps and as-code services β sync configuration, dashboards, or manifests between your application and users' repositories
- Bots and automation β commit generated files, open changes, or mirror content without shelling out to
git - Multitenant platforms β operate on thousands of repositories without maintaining a checkout per tenant
- Serverless and containers β environments with little or no persistent disk
- CI tooling β fetch only the subpaths you need from large repositories using path-filtered, shallow clones
nanogit is deliberately narrow. Reach for the git CLI or go-git instead when you need:
- Local development workflows β working trees, the index,
.gitdirectories, or repositories on disk - Full Git functionality β merges, rebases, blame, hooks, or Git configuration management
- Other transports β SSH,
git://, or local file access; nanogit is HTTPS-only - Protocol v1 or "dumb" HTTP servers β nanogit requires Smart HTTP protocol v2 and does not fall back. Notably, Azure DevOps / Azure Repos only speaks v1 and is not supported. Run
nanogit checkagainst a new provider before integrating - Signature verification β nanogit can sign commits but does not verify signatures
- Fine-grained file permissions β all files are written with mode 0644
See Why Git Protocol v2 Only? for the rationale behind the strictest of these constraints.
go-git is a mature, full-featured Git implementation. nanogit trades that breadth for a small, stateless core optimized for cloud services:
| Feature | nanogit | go-git |
|---|---|---|
| Protocol | HTTPS only (Smart HTTP v2) | All protocols |
| Storage | Stateless; pluggable object storage and writing modes | Local disk operations |
| Cloning | Shallow, with glob-based path filtering | Full repository clones |
| Scope | Essential operations only | Full Git functionality |
| Use case | Cloud services, multitenant backends | General purpose |
| Resource usage | Minimal footprint | Full Git features |
Because it never materializes a full repository, nanogit is dramatically faster and lighter for typical server-side operations. From the benchmark suite comparing both libraries across repository sizes:
| Scenario | Speed | Memory usage |
|---|---|---|
| CreateFile (XL repo) | 306x faster | 186x less |
| UpdateFile (XL repo) | 291x faster | 178x less |
| DeleteFile (XL repo) | 302x faster | 175x less |
| BulkCreateFiles (1000 files, medium repo) | 607x faster | 11x less |
| CompareCommits (XL repo) | 60x faster | 96x less |
| GetFlatTree (XL repo) | 258x faster | 160x less |
See the latest performance report and the performance analysis for methodology and full results.
Yes. nanogit is the Git engine behind Git Sync in grafana/grafana, reading and writing dashboards across tenants' repositories in production, and the default Git driver in grafana-bench. See who uses nanogit.
Releases follow semantic versioning: the v1 API is stable, and breaking changes only land in major versions. The project is actively developed by Grafana Labs.
Install the library (requires Go 1.26+):
go get github.com/grafana/nanogit@latestRead a file from a repository, then commit and push a new one β no clone involved:
package main
import (
"context"
"fmt"
"os"
"time"
"github.com/grafana/nanogit"
"github.com/grafana/nanogit/options"
)
func main() {
if err := run(context.Background()); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
func run(ctx context.Context) error {
// Any repository you can reach over HTTPS. Use a scratch repo to try the write path.
client, err := nanogit.NewHTTPClient(
"https://github.com/you/scratch-repo.git",
options.WithBasicAuth("git", os.Getenv("GIT_TOKEN")),
)
if err != nil {
return err
}
// Read a file straight from the server.
ref, err := client.GetRef(ctx, "refs/heads/main")
if err != nil {
return err
}
commit, err := client.GetCommit(ctx, ref.Hash)
if err != nil {
return err
}
blob, err := client.GetBlobByPath(ctx, commit.Tree, "README.md")
if err != nil {
return err
}
fmt.Printf("README.md at %s is %d bytes\n", ref.Hash, len(blob.Content))
// Stage a file, commit it, and push β entirely over HTTPS.
writer, err := client.NewStagedWriter(ctx, ref)
if err != nil {
return err
}
if _, err := writer.CreateBlob(ctx, "hello/from-nanogit.txt", []byte("pushed without a checkout\n")); err != nil {
return err
}
author := nanogit.Author{Name: "You", Email: "you@example.com", Time: time.Now()}
committer := nanogit.Committer{Name: "You", Email: "you@example.com", Time: time.Now()}
if _, err := writer.Commit(ctx, "Add from-nanogit.txt", author, committer); err != nil {
return err
}
return writer.Push(ctx)
}From here, the Quick Start guide covers cloning with path filtering, writing modes, retries, and authentication options.
nanogit ships a small CLI β primarily a testing and demonstration tool for the library. Install it with Go or grab a pre-built binary:
go install github.com/grafana/nanogit/cli/cmd/nanogit@latest
# Is this server compatible with nanogit?
nanogit check https://github.com/grafana/nanogit.git
# List refs, inspect trees, read and write files
nanogit ls-remote https://github.com/grafana/nanogit.git
nanogit cat-file https://github.com/grafana/nanogit.git main README.mdSee the CLI documentation for all commands and platform-specific downloads.
Comprehensive documentation is available at grafana.github.io/nanogit:
- Quick Start β reading, writing, cloning, retries, and authentication
- Server Compatibility β verify a Git server works with nanogit in four CLI commands
- Architecture β design principles, storage backends, retry mechanism, and performance
- Why nanogit exists β the Git Sync story and who uses nanogit
- API Reference (GoDoc) β complete API documentation
- Changelog β version history and release notes
nanogit ships the tooling to test code that depends on it:
- Unit tests β generated mocks for the
ClientandStagedWriterinterfaces, with working examples - Integration tests β the
gittestpackage spins up a real containerized Gitea server via Testcontainers:go get github.com/grafana/nanogit/gittest@latest
See the Testing Guide for patterns and best practices.
We welcome contributions! Please see the Contributing Guide for how to submit pull requests, report issues, and set up your development environment. This project follows the Grafana Code of Conduct.
This project is licensed under the Apache License 2.0.
If you find a security vulnerability, please report it according to our security policy.
- GitHub Issues: Create an issue
- Community: Grafana Community Forums
