A Git implementation in Go, written to understand how Git works internally. It covers the core object model plus the day-to-day commands: staging, status, diff, log, branches, checkout, and merge.
Inspired by ugit. This is a learning project, not a replacement for Git.
Needs Go 1.18+.
git clone https://github.com/vx6fid/git-go.git
cd git-go
go build -o ggit ./cmd/ggitggit init # initialize a repository
ggit hash-object <file> # store a file as a blob
ggit cat-file -p <hash> # inspect an object
ggit write-tree # write a tree from the working directory
ggit read-tree <tree-sha> # restore a tree into the working directory
ggit add <file>... # stage files
ggit rm <file> # unstage a file
ggit status # show working tree status
ggit diff # working tree vs index
ggit diff --staged # index vs HEAD
ggit commit -m <message> # commit staged changes
ggit log [-n <count>] # show commit history
ggit branch # list branches
ggit branch <name> # create a branch
ggit branch -d <name> # delete a branch
ggit checkout <branch|sha> # switch branch / detach
ggit checkout -b <name> # create and switch
ggit merge <branch> # merge a branch into the current onecmd/ggit/ CLI commands
internal/
object/ blobs, trees, commits, read/write
index/ staging area (binary .git/index, DIRC v2)
diff/ Myers diff, status and diff computation
log/ commit parsing and history walking
branch/ branch management and checkout
merge/ merge base, fast-forward and three-way merge
ref/ HEAD and refs
Objects are stored like Git does it: zlib-compressed, keyed by the SHA-1 of
<type> <size>\0<content>, under .git/objects/<2 hex>/<38 hex>.
Pack files, the network protocols (push/pull/fetch), rebase, tags, and the
config system are out of scope for now. The author name is currently hardcoded
in cmd/ggit/commit.go.
Inspired by ugit and Git's internals.