From d2f423521ec76406944ad83098ec33afe20c692b Mon Sep 17 00:00:00 2001 From: Kim Altintop Date: Mon, 9 Jan 2023 13:18:33 +0100 Subject: This is it Squashed commit of all the exploration history. Development starts here. Signed-off-by: Kim Altintop --- src/git/repo.rs | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 src/git/repo.rs (limited to 'src/git/repo.rs') diff --git a/src/git/repo.rs b/src/git/repo.rs new file mode 100644 index 0000000..3fb8a16 --- /dev/null +++ b/src/git/repo.rs @@ -0,0 +1,93 @@ +// Copyright © 2022 Kim Altintop +// SPDX-License-Identifier: GPL-2.0-only WITH openvpn-openssl-exception + +use std::{ + collections::HashSet, + ffi::OsString, + io::{ + BufReader, + Seek, + Write, + }, + iter, + path::Path, + result::Result as StdResult, +}; + +use super::{ + if_not_found_then, + Result, +}; +use crate::{ + fs::LockedFile, + io::Lines, +}; + +pub fn open>(path: P) -> Result { + git2::Repository::open_ext( + path, + git2::RepositoryOpenFlags::FROM_ENV, + iter::empty::(), + ) +} + +pub fn open_bare>(path: P) -> Result { + git2::Repository::open_ext( + path, + git2::RepositoryOpenFlags::FROM_ENV | git2::RepositoryOpenFlags::BARE, + iter::empty::(), + ) +} + +pub fn open_or_init>(path: P, opts: InitOpts) -> Result { + if_not_found_then(open(path.as_ref()), || init(path, opts)) +} + +pub struct InitOpts<'a> { + pub bare: bool, + pub description: &'a str, + pub initial_head: &'a str, +} + +pub fn init>(path: P, opts: InitOpts) -> Result { + git2::Repository::init_opts( + path, + git2::RepositoryInitOptions::new() + .no_reinit(true) + .mkdir(true) + .mkpath(true) + .bare(opts.bare) + .description(opts.description) + .initial_head(opts.initial_head), + ) +} + +pub fn add_alternates<'a, I>(repo: &git2::Repository, alt: I) -> crate::Result<()> +where + I: IntoIterator, +{ + let (mut persistent, known) = { + let mut lock = LockedFile::atomic( + repo.path().join("objects").join("info").join("alternates"), + false, + LockedFile::DEFAULT_PERMISSIONS, + )?; + lock.seek(std::io::SeekFrom::Start(0))?; + let mut bufread = BufReader::new(lock); + let known = Lines::new(&mut bufread).collect::, _>>()?; + (bufread.into_inner(), known) + }; + { + let odb = repo.odb()?; + for alternate in alt { + let path = format!("{}", alternate.path().join("objects").display()); + odb.add_disk_alternate(&path)?; + if !known.contains(&path) { + writeln!(&mut persistent, "{}", path)? + } + } + } + persistent.persist()?; + + Ok(()) +} -- cgit v1.2.3