From c1d7714a212e80756e8f1b83cbc7f077dedb7abd Mon Sep 17 00:00:00 2001 From: Profpatsch Date: Mon, 19 Apr 2021 22:49:15 +0200 Subject: feat(users/Profpatsch): add git-db MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WIP: currently just a simple setup that creates an empty git repo if it doesn’t exist yet, and writes a commit to it. A simple database backed by a bare git repository. WIP: Will speak a simple interactive protocol to query files and update them atomically. It could be made atomic on the git repo level, if a lock is taken between reading the current commit ref and creating the commit. Change-Id: I1fd30a046ac977063c3e08c36d96e835b35ff07d Reviewed-on: https://cl.tvl.fyi/c/depot/+/3046 Tested-by: BuildkiteCI Reviewed-by: Profpatsch --- users/Profpatsch/git-db/default.nix | 8 ++++ users/Profpatsch/git-db/git-db.rs | 85 +++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 users/Profpatsch/git-db/default.nix create mode 100644 users/Profpatsch/git-db/git-db.rs (limited to 'users') diff --git a/users/Profpatsch/git-db/default.nix b/users/Profpatsch/git-db/default.nix new file mode 100644 index 000000000000..7c6f1aee7c5c --- /dev/null +++ b/users/Profpatsch/git-db/default.nix @@ -0,0 +1,8 @@ +{ depot, pkgs, lib, ... }: + +depot.nix.writers.rustSimple { + name = "git-db"; + dependencies = [ + depot.third_party.rust-crates.git2 + ]; +} (builtins.readFile ./git-db.rs) diff --git a/users/Profpatsch/git-db/git-db.rs b/users/Profpatsch/git-db/git-db.rs new file mode 100644 index 000000000000..5c6bb1f85646 --- /dev/null +++ b/users/Profpatsch/git-db/git-db.rs @@ -0,0 +1,85 @@ +extern crate git2; +use std::os::unix::ffi::OsStrExt; +use std::path::PathBuf; + +const DEFAULT_BRANCH : &str = "refs/heads/main"; + +fn main() { + let git_db_dir = std::env::var_os("GIT_DB_DIR").expect("set GIT_DB_DIR"); + let git_db = PathBuf::from(git_db_dir).join("git"); + + std::fs::create_dir_all(&git_db).unwrap(); + + let repo = git2::Repository::init_opts( + &git_db, + git2::RepositoryInitOptions::new() + .bare(true) + .mkpath(true) + .description("git-db database") + .initial_head(DEFAULT_BRANCH) + ).expect(&format!("unable to create or open bare git repo at {}", &git_db.display())); + + let mut index = repo.index().expect("cannot get the git index file"); + eprintln!("{:#?}", index.version()); + index.clear().expect("could not clean the index"); + + let now = std::time::SystemTime::now() + .duration_since(std::time::SystemTime::UNIX_EPOCH) + .expect("unable to get system time"); + + let now_git_time = git2::IndexTime::new( + now.as_secs() as i32, // lol + u32::from(now.subsec_nanos()), + ); + + let data = "hi, it’s me".as_bytes(); + + index.add_frombuffer( + &git2::IndexEntry { + mtime: now_git_time, + ctime: now_git_time, + // don’t make sense + dev: 0, + ino: 0, + mode: /*libc::S_ISREG*/ 0b1000 << (3+9) | /* read write for owner */ 0o644, + uid: 0, + gid: 0, + file_size: data.len() as u32, // lol again + id: git2::Oid::zero(), + flags: 0, + flags_extended: 0, + path: "hi.txt".as_bytes().to_owned(), + }, + data + ).expect("could not add data to index"); + + let oid = index.write_tree().expect("could not write index tree"); + + let to_add_tree = repo.find_tree(oid) + .expect("we just created this tree, where did it go?"); + + let parent_commits = match repo.find_reference(DEFAULT_BRANCH) { + Ok(ref_) => vec![ + ref_ + .peel_to_commit() + .expect(&format!("reference {} does not point to a commit", DEFAULT_BRANCH)) + ], + Err(err) => match err.code() { + // no commit exists yet + git2::ErrorCode::NotFound => vec![], + _ => panic!("could not read latest commit from {}", DEFAULT_BRANCH), + } + }; + repo.commit( + Some(DEFAULT_BRANCH), + &git2::Signature::now("Mr. Authorboy", "author@example.com").unwrap(), + &git2::Signature::now("Mr. Commiterboy", "committer@example.com").unwrap(), + "This is my first commit!\n\ + \n\ + I wonder if it supports extended commit descriptions?\n", + &to_add_tree, + &parent_commits.iter().collect::>()[..], + ).expect("could not commit the index we just wrote"); + + +} -- cgit 1.4.1