etc/speak/gitmerge-2024.marp.html
Previous slideNext slideToggle fullscreenOpen presenter view
What it is, and isn't
https://github.com/Byron/gitoxide
(and wants to be)
https://github.com/Byron/gitoxide
git2 - A Rust crate binding to libgit2
libgit2
Git - the mothership
libgit-rs - a Rust crate binding to libgit.athe high-performance Rust crate that acts like Git would
the binaries gix and ein
Gitoxidea Git replica
always quite as easy-to-use as git2
usable from any other language but Rust
stable (yet)
be the go-to Git library for anyone, usable from any language
be the best choice for large monorepos
power an entire Git forge
be the first with new (experimental) Git features
jjnew project with Git integration, gitoxide features suffice
gix::Repository)need Git-level repository compatbility
need to read from untrusted repositories
need next-level performance and fearless concurrency
you deal with massive monorepos
read & write thread-safe & lock-free object database
read + write ref-database
lossless git-config reading and writing
read and write index
.gitignore (with precious files) & .gitattributes
pathspecs: /**hello.*
revspecs: @~1
refspecs: refs/heads/*:refs/remotes/origin/*
read commit-graphs and use them for traversals
rev-parse
diff
find untracked files/classify worktree
(shallow) fetch
first checkout after fetch
full status (tree-index diff missing)
commit (index-add, index-to-tree)
merge (blob-diff works , but WIP)
push (but can build packs by object-copy)
rebase
cherry-pick
reset/checkout
blame (but WIP)
progress-reporting and are interrupt-handling
easy-to-use API without hiding any knob
async-support for networked IO
Security
Real world code written by a real API user, courtesy of GitButler.
#[tauri::command(async)]
pub fn git_clone_repository(repository_url: &str, target_dir: &Path) -> Result<(), Error> {
git2::Repository::clone(repository_url, target_dir).context("Cloning failed")?;
Ok(())
}
#[tauri::command(async)]
pub fn git_clone_repository(repository_url: &str, target_dir: &Path) -> Result<(), Error> {
let url =
gix::url::parse(repository_url.into()).context("Failed to parse repository URL")?;
let should_interrupt = AtomicBool::new(false);
let mut prepared_clone =
gix::prepare_clone(url, target_dir).context("Failed to prepare clone")?;
let (mut prepared_checkout, _) = prepared_clone
.fetch_then_checkout(Discard, &should_interrupt)
.context("Failed to fetch")?;
let should_interrupt = AtomicBool::new(false);
prepared_checkout
.main_worktree(Discard, &should_interrupt)
.context("Failed to checkout main worktree")?;
Ok(())
}
#[tauri::command(async)]
pub fn git_clone_repository(repository_url: &str, target_dir: &Path) -> Result<(), Error> {
let url = gix::url::parse(repository_url.into()).map_err(anyhow::Error::from)?;
let should_interrupt = AtomicBool::new(false);
let (mut checkout, _outcome) = gix::prepare_clone(url, target_dir)
.map_err(anyhow::Error::from)?
.fetch_then_checkout(Discard, &should_interrupt)
.map_err(anyhow::Error::from)?;
checkout
.main_worktree(Discard, &should_interrupt)
.map_err(anyhow::Error::from)?;
Ok(())
}
#[tauri::command(async)]
pub fn git_clone_repository(repository_url: &str, target_dir: &Path) -> Result<(), UnmarkedError> {
let should_interrupt = AtomicBool::new(false);
gix::prepare_clone(repository_url, target_dir)?
.fetch_then_checkout(gix::progress::Discard, &should_interrupt)
.map(|(checkout, _outcome)| checkout)?
.main_worktree(gix::progress::Discard, &should_interrupt)?;
Ok(())
}
#[tauri::command(async)]
pub fn git_clone_repository(repository_url: &str, target_dir: &Path) -> Result<(), Error> {
git2::Repository::clone(repository_url, target_dir).context("Cloning failed")?;
Ok(())
}
#[tauri::command(async)]
pub fn git_clone_repository(repository_url: &str, target_dir: &Path) -> Result<(), UnmarkedError> {
let should_interrupt = AtomicBool::new(false);
gix::prepare_clone(repository_url, target_dir)?
.fetch_then_checkout(gix::progress::Discard, &should_interrupt)
.map(|(checkout, _outcome)| checkout)?
.main_worktree(gix::progress::Discard, &should_interrupt)?;
Ok(())
}
benefits clients, no need to re-implement stuff users expect from you
respect configuration, but allow overrides
gix dev tool, ein client + tooling
gix will never be git, never stable, won't mimmick it
But gitoxide should be versatile enough to implement the majority of Git
in great contrast to git2
disclaimer: not entirely just yet, still git2 in there