Skip to content

Latest commit

Β 

History

323 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
nanogit - Git reimagined for the cloud – in Go

GitHub Release License CI Go Reference codecov

πŸ“š Read the full documentation at grafana.github.io/nanogit

What is 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

When should I use it?

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

When should I not use it?

nanogit is deliberately narrow. Reach for the git CLI or go-git instead when you need:

  • Local development workflows β€” working trees, the index, .git directories, 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 check against 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.

How is it different from go-git?

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.

Is it production-ready?

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.

Try it in 5 minutes

Install the library (requires Go 1.26+):

go get github.com/grafana/nanogit@latest

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

Try the CLI

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

See the CLI documentation for all commands and platform-specific downloads.

Documentation

Comprehensive documentation is available at grafana.github.io/nanogit:

Testing your integration

nanogit ships the tooling to test code that depends on it:

  • Unit tests β€” generated mocks for the Client and StagedWriter interfaces, with working examples
  • Integration tests β€” the gittest package 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.

Contributing

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.

License

This project is licensed under the Apache License 2.0.

Security

If you find a security vulnerability, please report it according to our security policy.

Support

About

Lightweight, HTTPS-only Git client library for Go, built for cloud-native and multitenant services

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

48 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages