Skip to content

Latest commit

 

History

History
45 lines (31 loc) · 2.54 KB

File metadata and controls

45 lines (31 loc) · 2.54 KB

cgit

cgit reimplements git's core plumbing commands in C: init, hash-object, cat-file, ls-tree, write-tree, and commit-tree. It stores and retrieves objects in git's binary format, computes SHA-1 hashes with OpenSSL, and compresses objects with zlib. The objects cgit writes have the same content as git's for files, folders and commits, except for the cases listed under Known Limitations. Real git can read them, and cgit can read objects written by git.

Architecture

cgit has three layers. main.c owns the dispatch table: it parses argv, matches the command name in a static array of structs, and calls the matching handler. The command layer (commands/) validates arguments, calls into core, and formats output. The core layer (core/) implements object I/O, hashing, compression, tree parsing, and path utilities. Dependencies point only downward; core has no knowledge of which commands exist or which flags they parse.

Build

cmake -B build && cmake --build build

Requires CMake 4.2 or later, OpenSSL, and zlib. On macOS, OpenSSL is detected automatically via Homebrew.

Usage

cgit init
cgit hash-object -w <file>
cgit cat-file -p <hash>
cgit cat-file -t <hash>
cgit cat-file -s <hash>
cgit cat-file -e <hash>
cgit ls-tree [--name-only] <hash>
cgit write-tree
cgit commit-tree <tree-hash> [-p <parent-hash>] -m <message>

Architecture Decision Records

All decision records live in docs/adr/. Each file documents the context, the options considered, and the consequences for the codebase.

Project Status

init, hash-object, cat-file, ls-tree, write-tree, and commit-tree are implemented, and their output was checked against real git in the verification report. Author and committer identity in commit-tree are compile-time constants; there is no config file parsing. Objects are addressed by full 40-character SHA-1 hex; there is no ref resolution, no HEAD dereferencing, and no branch tracking. The staging area is not implemented: write-tree reads the working directory directly. Only loose objects are supported; pack files are not.

Known Limitations

  • A folder and a file whose names start the same way, such as foo/ and foo.txt, are ordered differently from git.
  • Empty folders are included, while git ignores them.
  • Symbolic links are saved as regular files.
  • A commit message that already ends with a new line gets an extra one.
  • The files on disk are compressed slightly differently from git's, even though their content is the same.