Rust Git2’s Concepts

Rust has a crate git2, which is a wrapper over libgit2 to work with git repositories.


Primary data structure to work with git repositories is git2::Repository. Everything is tied to repository, all objects, eg Commit, Branch etc have a lifetime linked to repository, so this is going to be starting point for everything.

git2::Repository object can be created by referring to an existing git repository on filesystem using:

let repo = git2::Repository::open("/path/to/a/repo")?;

Or we can create a new git repository (equivalent of git init):

let repo = git2::Repository::init("/path/to/a/repo")?;

Or we can clone repository using a git url:

let repo = match Repository::clone(url, "/path/to/a/repo")?;

::init() and ::open() have _bare() versions too, if you are working with bare git repositories. ::open() can be used with either bare or normal git repository.


A git2::Repository may have a “workdir” if it is a “normal” repository, or not, if it is a “bare” repository.

We can get the workdir for a repository using git2::Repository.workdir() -> Option<&Path>. Similarly, there is .set_workdir().

When setting a workdir to a repository, we can pass a flag update_gitlink, which will set core.worktree to the workdir passed in the bare repository (else the information will only be kept in the in-memory version of git2::Repository.

Reference Vs Objects

A git repository can be thought of as a collection of objects (git2::Object), where objects usually represent a file (blob), a tree (collection of files in any folder, non recursive, tree is composed of blobs and trees), commits and tags (these types are represented using git2::ObjectType enum.)

Each of above objects are stored with an id which is hash of content (and header, where header represents type of object and size of content). These ids are called git2::Oid.

References on the other hand are like aliases to these object ids. Common references are branches. And a reference for HEAD which represents the commit associated with the workdir.

A simplified story: a repository is collection of branches, which are references. A branch is a reference to the latest commit. Each commit stores zero, one or two to parent commit object ids, a tree object id representing content of repository at that commit, commit message, author info, and date time of commit.

Finding Branches

Branches are represented by git2::Branch struct. To find branches of a repository there is a .branches() method. Then there is a .find_branch() method to find a branch by name.

From a git2::Branch you can find git2::Reference (.get() or .into_reference()), and from Reference you can get the Oid using .target(), or straight to Commit (.peel_to_commit()) or Tree (.peel_to_tree()) for the the reference.

Checking Out Things

To checkout the content of a Tree (that say you found via Branch -> Reference -> peel_to_tree()), you can do: Repository.checkout_tree(), which will update the working directory and the repositories index.

You can also checkout write the content of Index to working directory using Repository.checkout_index(), or you can checkout HEAD using Repository.checkout_head(), which will reset both index and working directory to the commit pointed to by HEAD.

Understanding Index

When using command git command line, there is a “index”, which is stored in .git/index. git add updates index, and git commit created a commit out of index.

When using git2, index can either represent the index on disc, or in memory version.

To get the reference to git2::Index stored in a Repository, use Repository.index() method, which will read the .git/index file and use the same index used by git command line tool. Or to create new in-memory index, git2::Index::new().

Table Of Content

Immobile v2

Link Log

July 2020

June 2020

May 2020

April 2020

March 2020

February 2020

January 2020


Books Have Read / Recommend

Product Management Books

Badass: Making Users Awesome


Five Cs of An Organisation

Success and failure of encryption

Open Source

Observer: Observability for Rust

Realm: Web Development Framework Using Rust and Elm

MartD: Server To Browser Messages

On Writing And Formats Of Written Communications

Rust Stuff

Rust feature flags

Why is diesel not compatible with async?

Making Postgres Only Diesel Code To Also Support Sqlite

Rust Git2’s Concepts

Git Hash And Build Date In Rust Build

Systray Only Native App In Rust

Software and Tools I Use Often


DNS Over HTTPS Controversy

The Patel Motel Cartel

Standalone Complex


January 2020

Word Of The Day





Nix On OSX Catalina

Postgres: WAL / Logical Decoding

Postgres: Listen-Notify



Go All The Way

SSH Commands



Nu Shell

SHA256 vs SHA224

Pronouns Bad


Web Components