//! Building bare git repositories for the git browser, issue and SSH tests. //! //! Written with gitoxide, the same library the server reads through. use gix::objs::tree::EntryKind; /// Initialize a bare repo at `//.git`. pub(crate) fn init_bare(dir: &std::path::Path, owner: &str, name: &str) -> gix::Repository { let bare_path = dir.join(owner).join(format!("{name}.git")); std::fs::create_dir_all(&bare_path).unwrap(); gix::init_bare(&bare_path).unwrap() } /// Write a blob and return its id. pub(crate) fn blob(repo: &gix::Repository, content: &[u8]) -> gix::ObjectId { repo.write_blob(content).unwrap().detach() } /// Write a tree from `(name, id, kind)` entries. pub(crate) fn tree( repo: &gix::Repository, entries: &[(&str, gix::ObjectId, EntryKind)], ) -> gix::ObjectId { let mut tree = gix::objs::Tree::empty(); for (name, oid, kind) in entries { tree.entries.push(gix::objs::tree::Entry { mode: (*kind).into(), filename: (*name).into(), oid: *oid, }); } tree.entries.sort(); repo.write_object(&tree).unwrap().detach() } /// Commit a tree onto `refs/heads/main` with a fixed test identity. pub(crate) fn commit( repo: &gix::Repository, message: &str, tree: gix::ObjectId, parents: Vec, ) -> gix::ObjectId { let signature = gix::actor::SignatureRef { name: "Test".into(), email: "test@example.com".into(), time: "1700000000 +0000", }; repo.commit_as( signature, signature, "refs/heads/main", message, tree, parents, ) .unwrap() .detach() } /// Tip commit sha of `refs/heads/main` in an on-disk bare repo. pub(crate) fn main_tip_sha(dir: &std::path::Path, owner: &str, name: &str) -> String { let repo = gix::open(dir.join(owner).join(format!("{name}.git"))).unwrap(); repo.find_reference("refs/heads/main") .unwrap() .peel_to_id() .unwrap() .to_string() }