puregit 0.0.2

A pure-Rust implementation of git, in the spirit of libgit2, built on purecrypto. Object model, packfiles, refs, and the smart transport over HTTP and SSH — client and server.
Documentation
# puregit

[![CI](https://github.com/KarpelesLab/puregit/actions/workflows/ci.yml/badge.svg)](https://github.com/KarpelesLab/puregit/actions/workflows/ci.yml)
[![crates.io](https://img.shields.io/crates/v/puregit.svg)](https://crates.io/crates/puregit)
[![docs.rs](https://img.shields.io/docsrs/puregit)](https://docs.rs/puregit)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

A pure-Rust implementation of git, written from scratch in the spirit of
`libgit2` — the object model, packfiles, references, the staging index, and the
*smart* transfer protocol, as both a **client and a server**, over **HTTP and
SSH**.

puregit is built on the same first-party, no-C-toolchain foundation as its
sibling crates:

- **[`purecrypto`]https://crates.io/crates/purecrypto** — SHA-1 / SHA-256 for
  object names (and, later, commit/tag signing).
- **[`compcol`]https://crates.io/crates/compcol** — zlib for loose objects and
  packfiles.
- **[`puressh`]../puressh** — the SSH transport.
- **[`rsurl`]../rsurl** — the HTTP(S) transport.

There is **no C in the dependency tree** and **no `*-sys` crate** — the whole
stack compiles with nothing but a Rust toolchain.

## Design: a `no_std` core and a `std` shell

The crate is split so the engine that manipulates git data is portable and the
parts that touch a socket, a clock, or the real filesystem are isolated behind
features:

```
┌─────────────────────────────────────────────────────────────┐
│ std shell (feature `std`)                                    │
│   vfs::StdFs · Repository · worktree · transport::{http,ssh} │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ no_std + alloc core                                          │
│   oid · hash · object · odb · pack · refs · index · config   │
│   protocol (pkt-line · capabilities · fetch/push negotiation)│
└─────────────────────────────────────────────────────────────┘
```

The core is `#![no_std]` (with `alloc`); it never names `std`. Filesystem
access goes through the [`Vfs`](src/vfs/mod.rs) trait, so the same repository
logic runs over the real disk ([`StdFs`](src/vfs/std_impl.rs)), an in-memory
store, or any custom backend. The wire protocols are **sans-IO** — the
negotiation layer transforms byte buffers and the transport owns the socket,
the same architecture as `puressh` and `rsurl`.

## What works today

**puregit clones real repositories from GitHub over HTTPS**, and round-trips
clone / fetch / push over an in-process transport — the object engine,
protocol, client, and server all work end to end and are byte-compatible with
canonical git (puregit-created history passes `git fsck`; a real GitHub clone
matches git's HEAD, history, and checkout exactly).

- **Object engine** — SHA-1 / SHA-256 ids; blob/tree/commit/tag parse +
  serialize (signed commits and annotated tags round-trip byte-for-byte); the
  combined loose + packed object database with delta resolution across backends.
- **Packfiles** — read (random access + delta chains, v2 `.idx`), write
  (`PackWriter` + `.idx` generation), and ingest a received pack with no index
  (`explode_pack`) — verified against real `git repack` output.
- **Reachability** — object-graph closure, the fetch/push object set, and a
  commit `RevWalk`.
- **References / index / config** — loose + `packed-refs` + symrefs; the `DIRC`
  v2/v3 index with `write-tree`; the `.git/config` INI format.
- **Local porcelain** — `init`, `add`, `commit`, `log`, working-tree checkout.
- **Networking** — smart-HTTP(S) over `rsurl` (clones GitHub) and SSH over
  `puressh` (password + public-key auth); client `fetch`/`clone`/`push`;
  server `upload-pack`/`receive-pack` plus a framework-agnostic smart-HTTP
  handler and a `git://` daemon.
- **Git LFS** — pointer format, the local `.git/lfs/objects` store, clean/smudge
  filters wired into `add`/checkout, `.gitattributes` tracking, and the batch
  API + object transfer over HTTP — with a dependency-free JSON reader. The
  pointers it writes are byte-compatible with `git lfs`.
- **`puregit` CLI** (a git-compatible front end) — `init`, `hash-object`, `cat-file`, `rev-parse`
  (full revision syntax), `add`, `rm`, `mv`, `ls-files`, `ls-tree`, `write-tree`, `commit`, `log`,
  `show`, `status`, `diff`, `diff-tree`, `merge-base`, `branch`, `tag`, `checkout`/`switch`,
  `reset`, `config`, `unpack-objects`, `fsck`, `clone` (local, HTTP(S), SSH). Output, exit codes
  and common error messages are checked side by side against real git
  (`tests/interop_cli*.rs`).

The long tail — SSH key/agent auth, multi-round negotiation + sideband,
protocol v2, more porcelain (`status`/`branch`/`checkout`/`diff`/`merge`), and
maintenance (`repack`/`gc`) — is the focus of the [roadmap](ROADMAP.md).

## Usage

```rust
use puregit::{Repository, object::ObjectType};

let repo = Repository::init("/tmp/demo")?;
let id = repo.write_object(ObjectType::Blob, b"hello\n")?;
println!("{id}"); // ce013625030ba8dba906f756967f9e9ca394464a
let blob = repo.read_object(&id)?;
# Ok::<(), puregit::Error>(())
```

```console
$ git init demo && cd demo
$ printf 'hello\n' > a.txt
$ git add a.txt && git commit -m "first commit"
committed 9b2c8e…
$ git log

# clone a real repository over HTTPS (pure-Rust TLS, no C):
$ git clone https://github.com/octocat/Hello-World.git
Cloned into 'Hello-World' (HEAD 7fd1a60b)
```

## Features

| Feature   | Default | Description                                              |
|-----------|:-------:|----------------------------------------------------------|
| `std`     |   ✓     | Standard library: `StdFs`, `Repository`, worktree, I/O   |
| `client`  |   ✓     | Client-side porcelain/plumbing (local + fetch/push driver)|
| `server`  |         | `upload-pack` / `receive-pack` request handlers          |
| `http`    |         | Smart-HTTP(S) transport over `rsurl`                      |
| `ssh`     |         | SSH transport over `puressh`                             |

Build the `no_std` core with `--no-default-features` (an allocator is still
required). `--features full` turns on everything.

## License

Licensed under the [MIT License](LICENSE).