CLI tool
gitbutlerapp/grit avatar
gitbutlerapp/grit

grit: a Git engine in Rust, split into a library and a deliberately smaller CLI

Reimplementing Git in Rust. Like a boss.

548 stars41 forksRustMIT

At a glance

What is it?
Grit is a reimplementation of Git in Rust from the GitButler team, and its shape has changed since it started. The Git-compatible command line and the ported Git test harness were removed, leaving a linkable grit-lib and a modern grit client that outputs plain language, JSON or Markdown while keeping on-disk and wire compatibility.
Who is it for?
grit suits a developer who wants to embed Git operations in a Rust program, because grit-lib is a normal library crate with the object model, diff engine, index, refs and merge exposed, and the fact that the crate denies unsafe code says something about how it is meant to be used.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The project changed shape, and the README says so plainly

Grit is a Git engine in idiomatic Rust, made of a linkable grit-lib and a modern grit client called grit-cli built on it, and the project is brought to you by the people at GitButler.

The interesting paragraph is the motivation section, because it describes a project that changed direction rather than one that has always been this way. Grit started as a reimplementation of the whole git command line, aimed at passing Git's own test suite. That carried workarounds, slow paths and every legacy subcommand, so the Git-compatible CLI, which was called grit-git, and the ported test harness have been removed.

What replaced them is a narrower goal. The focus now is grit-lib as a clean, linkable library, and grit-cli as a modern Git client with human, --json and --markdown output. The compatibility promise is stated precisely: both stay compatible with Git where it matters, meaning repositories on disk and the wire protocol.

That is a different project from the one that started, and being told so is better than discovering it. The two artifacts have different audiences. grit-lib is for people embedding Git operations in a program, and grit-cli is for people who want a faster and clearer command line for the common cases. The compatibility promise applies to the data, not to the commands, which is the distinction that matters for anyone porting a script.

There is a ROADMAP.md for the plan, a background link to a post called True Grit, and the homepage is grit-scm.com. The last push was on 2026-10-22 and the release history shows v0.5.12, v0.5.13 and v0.5.14 on consecutive days in October 2026, so the project is being cut at a high rate and is still pre-1.0.

What the CLI covers, and the three output formats

The CLI is described as not a Git-identical CLI but a simpler interface for common developer workflows built on grit-lib, and it is portable to Windows.

The design decision that defines it is that status is the home screen. Running grit with no arguments gives you a status dashboard, and the common path is kept terse:

sh
grit auth   # authenticate into github and store https auth tokens for fetch/push as your user
grit clone https://github.com/user/project
grit        # status dashboard
grit commit "message" # commit changes
grit switch -c topic
grit push
grit pull

The coverage is stated as a list. Local work covers status, add, commit, branch, switch, merge, log and config. The remote basics are remote add, clone, fetch, pull and push. The output is plain language.

Then there is the three format thing, which is the part that makes this usable in a script as well as at a terminal. Alongside the human output there is --json and --markdown, and the readme says the project is built around that. A status dashboard that only renders for a person is a status dashboard that cannot be piped into anything, so the structured outputs are what let you use grit from a script or feed it to another tool without parsing text.

There is also a piece of the CLI that is not about Git at all. grit auth authenticates into GitHub and stores HTTPS auth tokens for fetch and push as your user, which is a convenience for a tool that is otherwise entirely local. On Windows the version also comes with grit manager, which works as an interface to Windows Credential Manager to store those tokens securely, which is a reasonable answer to the fact that a token in a config file is a token in a config file.

The server side is in the same binary. grit upload-pack and grit receive-pack are the server side of fetch and push, used over ssh and by grit-http-server for smart HTTP, so a single binary can act as a server as well as a client.

The crate layout, and the parts of Git that are not in it

The Rust crates table is the clearest picture of the project.

grit-cli is the grit binary, the workflow oriented CLI backed by grit-lib, and it is the crate the install script ships. grit-lib is the core library, and the description lists what is in it: object model, diff engine, index, refs, revision walking, merge, config and more. grit-protocol and grit-http-server provide smart HTTP serving through in-process grit-lib upload-pack and receive-pack. grit-examples is runnable examples of library usage. And grit-test-support is workspace-only helpers for integration tests.

The Cargo workspace lists seven members, with the default members being grit-lib, grit-protocol and grit-cli, so a plain cargo build in the repository root builds the library and the CLI but not the examples.

The features that are deliberately absent are as informative as the ones present. Unused areas, which are archive, the email workflow and foreign VCS bridges, are dropped from active development. That is a substantial list of Git. The email workflow in particular covers send-email and format-patch, the commands that let a commit carry a signed-off-by trailer through a review process, and their absence tells you that Grit is not aimed at projects with a formal patch workflow.

The core semantics live in grit-lib with pluggable ODB and ref backends over time, which is the phrase that matters for anyone planning to use it. The object database and the refs are the two things an alternative implementation has to get exactly right, and the plan is to make the backends pluggable rather than to have one hard-coded storage format.

The behaviour is validated with Rust tests cross-checked against the system git binary, and the performance measurement is against real git on large repository scenarios, with performance described as the top priority. The workspace depends on criterion with the html_reports feature, and the Makefile exposes bench-lib and bench-scenarios targets for the benchmark harness.

The lint configuration is the most opinionated thing in the repository

The Cargo workspace lints are strict in a way that is unusual and worth reading before you contribute.

unsafe_code is set to forbid at the workspace level. Not warned about, not allowed in a single crate, forbidden across the whole workspace. For a library that parses untrusted repository data, that is a defensible position, and it is enforced by cargo rather than by review.

The clippy lints deny unwrap_used and expect_used, so the code cannot panic on a None or a failed expectation. That is the same concern from the other direction. A Git implementation that is going to be a long-running server component, and grit is built by the team behind GitButler, a desktop application, has a good reason to prefer an error value over a panic on a path where a corrupt object might appear.

The rustdoc lints are just as strict: broken intra-doc links are denied, private intra-doc links are denied, invalid HTML tags are denied, invalid codeblock attributes are denied, and bare URLs are denied. That last one is a documentation style rule rather than a safety rule, but it is applied at the same level, and it means the doc comments are held to a consistent standard.

The dependency list is worth scanning for what it reveals about the implementation. sha1 and sha2 are both present, which is what you would expect of a Git implementation, and there is a comment explaining that hash crates are on every object-id path so they are compiled at native speed in dev and test, with a profile override setting opt-level 3 for the sha1 and sha2 packages in the dev profile. That is a build-time performance decision for the development loop specifically.

The rest of the list is the shape of a serious implementation rather than a toy. There are two diff libraries, similar for character level and imara-diff for unified diff output, and merge3 for three-way merges. There is unicode-width, which is what you need for text display that respects wide characters, and regex, url, toml, base64, hex and crc32fast. filetime and libc are for the filesystem and platform layers, memmap2 and icu_normalizer are for the on-disk and text handling, and ureq is the HTTP client. nix is there for the user and feature bits on Unix, and shell-words for parsing command lines.

The Makefile, and the API surface is treated as a contract

The Makefile is a convenience wrapper around the cargo and test workflows, and its target list is where the project's process shows through.

There is make build for a release build of the CLI and make debug for a debug build, make test to run the Rust unit and integration tests, make clippy to lint all crates where warnings fail CI, make fmt to format all crates, and make doc to build the API docs where rustdoc warnings fail. There are also make gate, described as a pre-integration gate covering fmt, clippy, rustdoc and the workspace tests, and make docs and make docs-check, the latter running the same checks as the Site workflow for content, links, tests and build.

Two targets stand out. make public-api regenerates a file called grit-lib/public-api.txt, and make public-api-check diffs the committed public API snapshot against a fresh run, using a pinned nightly and the cargo-public-api tool. The project is treating the public API of the library as a contract that has to be approved before it changes, and a diff failure in CI is what stops an accidental break.

There is also make coverage, which runs llvm-cov against grit-lib with a per-module coverage floor that ratchets, so coverage cannot quietly fall. And the benchmark targets are bench-lib and bench-scenarios, with a TIER variable and a SMOKE variable, and the scenario host defaulting to the machine's short hostname. The build jobs are taken from nproc, defaulting to 2.

The testing section in the README is short, with the two commands that matter:

sh
cargo test -p grit-lib --lib
cargo test --workspace

The first runs the library unit tests only, and the second runs the whole workspace. There is a TESTING.md with the full strategy, and the repository also has a .cargo/ directory, a rust-toolchain.toml, a Cargo.lock, a .mailmap, a .git-meta file and a scripts/ directory, along with a content/ directory, a data/ directory, a docs/ directory and a site/ directory, which is where the grit-scm.com pages come from, since the Makefile refers to a Next.js dev server in site/.

The WINDOWS_PORT_PLAN.md file at the root and the grit manager command together suggest Windows support was a deliberate focus rather than an afterthought, which is unusual for a Git reimplementation.

Editorial conclusion

grit suits a developer who wants to embed Git operations in a Rust program, because grit-lib is a normal library crate with the object model, diff engine, index, refs and merge exposed, and the fact that the crate denies unsafe code says something about how it is meant to be used. It does not suit you as a drop-in replacement for the git command, because the Git-compatible CLI was removed on purpose, and it does not suit you if you need the parts that are not implemented, since archive, the email workflow and foreign VCS bridges were dropped from active development. Before you depend on it, run the test suite against your own workflow, since the project measures its performance against the system git binary on large repositories rather than making claims of its own.

Frequently asked questions

What is grit and who builds it?

It is a Git engine in idiomatic Rust, made of a linkable grit-lib and a modern grit-cli client built on it, brought to you by the GitButler team. The project is a reimplementation of Git in Rust and its homepage is grit-scm.com.

How do I install the grit CLI?

Run the install script with curl -fsSL https://grit-scm.com/install | sh. There are builds for Mac and Linux on aarch64 and x86_64, with Linux shipping both glibc and statically linked musl binaries, and Windows installing the same grit CLI. To update, run grit update, which re-runs the install script.

Is grit a drop-in replacement for the git command?

No. The Git-compatible CLI and the ported test harness were removed, because the workarounds and slow paths they carried were the problem. The current grit CLI is a simpler opinionated interface, and the compatibility promise is about repositories on disk and the wire protocol rather than about the commands.

What output formats does the grit CLI support?

Plain language output for people, and --json and --markdown for scripts. The CLI covers status, add, commit, branch, switch, merge, log and config locally, plus remote add, clone, fetch, pull and push, and it can also serve repositories through the upload-pack and receive-pack commands over ssh and smart HTTP.

Official sources

  1. gitbutlerapp/grit on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/gitbutlerapp-grit.svg)](https://hysenlabs.com/projects/gitbutlerapp-grit)

Was this useful?