Playing around with gitoxide - an implementation of git in Rust
Background
There’s git
which is a CLI tool implementing git
SCM which we all know and love.
Additionally, there’s libgit2 which is a reference implementation of git “standard”/“protocol”. The focus of it, is primarily to be used within applications that wish to integrate with git repositories and provide programmatic access to git facilities.
Usually, languages like Python or Go use libgit2 under the hood to implement git bindings. This is the case with e.g. pygit2 or git2go and many more.
Recently, I stumbled upon gitoxide. Which,
as I initially thought, would cultivate exactly the same approach, meaning it would
use libgit2
as low level routines for git, but this doesn’t seem to be the
case.
First thing that comes to mind is … why? Reading through project goals, the aspiration is to:
… be the go-to implementation for anyone who wants to solve problems around git, and become the alternative to GitPython and libgit2 in the process.
There’s a whole slew of questions I might have behind this motivation, but I’m gonna spare myself the effort. Regardless of all of that I decided to give it, at least, some sort of superficial valuation.
Benchmarks
gix
is not yet feature complete so there’s a limited set of things that can
be tested. Cloning a repository is supported though and its performance might
be compared between git
and gix
so, this is what I’m going to do.
For the purpose of this exercise I’ve clone Linux kernel repo (to eliminate any networking related aspects) like so:
git clone --bare --progress https://github.com/torvalds/linux.git
Bare in mind as well that I’m using a relatively slow SATA SSD so the numbers might seem high.
git clone
Starting with git
I get a bit of a weird results.
|
|
This is too good to be true as it’s physically impossible to copy ~5G worth of data on my machine that quickly. So, what has actually happened?
Turns out that git
implements an optimisation when cloning a local repository
and instead of copying the data from .git/objects
it just creates hard links.
Listing the contents of the new clone, sure enough, ls
reports link count > 1
for majority of files.
|
|
This can be further confirmed by inspecting the inode
number of an arbitrarily
chosen object between two repositories:
|
|
As expected both point to the same inode
. This behaviour can be disabled
with --no-hardlinks
flag. Let’s try that.
|
|
This result is comparable with cp -r
or rsync -a
so, it seems to be more
reliable and useful as a baseline for comparison.
gix clone
Installation of gitoxide
is easy in my case as it is available in Arch so I need pacman
to do it.
I will use version 0.32.0
.
Let’s perform the same test as with git
.
|
|
This is very disappointing. We’re talking about ~60x time difference. Judging
by the log it seems like gix
re-packaged all objects when cloning - this is
something that git
probably doesn’t do.
Conclusion
I’m not sure if gitoxide
will ever become a viable rust based alternative to
libgit2
. There’s definitely a lot of effort and time required to bring the
project to maturity. As of now, I’m happy to stick with libgit2
rust
bindings like e.g. git2-rs. gix
as a
CLI tool utilising gitoxide
is definitely not yet there to be a true
competitor with git
.