create a wrapper for git::repository

This commit is contained in:
Nikita Galaiko 2023-08-30 09:46:52 +02:00 committed by GitButler
parent af2f232772
commit 38517cdb19
9 changed files with 179 additions and 29 deletions

View File

@ -12,7 +12,7 @@ use sha2::{Digest, Sha256};
use uuid::Uuid;
use crate::{
fs, lock, projects, users,
fs, git, lock, projects, users,
virtual_branches::{self, target},
};
@ -26,7 +26,7 @@ pub struct Repository {
pub project_id: String,
project_store: projects::Storage,
users_store: users::Storage,
pub git_repository: git2::Repository,
pub git_repository: git::Repository,
}
#[derive(Debug, thiserror::Error)]
@ -64,10 +64,10 @@ impl Repository {
let path = root.as_ref().join("projects").join(project_id.clone());
if path.exists() {
let git_repository = git2::Repository::open(path.clone())
let git_repository = git::Repository::open(path.clone())
.with_context(|| format!("{}: failed to open git repository", path.display()))?;
git_repository
git_repository.inner()
.odb()
.map_err(Error::Git)?
.add_disk_alternate(project_objects_path.to_str().unwrap())
@ -80,7 +80,7 @@ impl Repository {
users_store,
})
} else {
let git_repository = git2::Repository::init_opts(
let git_repository = git::Repository::init_opts(
&path,
git2::RepositoryInitOptions::new()
.bare(true)
@ -89,7 +89,7 @@ impl Repository {
)
.with_context(|| format!("{}: failed to initialize git repository", path.display()))?;
git_repository
git_repository.inner()
.odb()?
.add_disk_alternate(project_objects_path.to_str().unwrap())
.context("failed to add disk alternate")?;
@ -740,7 +740,7 @@ fn build_wd_tree(
}
let wd_tree_oid = index
.write_tree_to(&gb_repository.git_repository)
.write_tree_to(&gb_repository.git_repository.inner())
.with_context(|| "failed to write wd tree".to_string())?;
Ok(wd_tree_oid)
}
@ -840,7 +840,7 @@ fn build_wd_tree_from_repo(
}
let tree_oid = index
.write_tree_to(&gb_repository.git_repository)
.write_tree_to(&gb_repository.git_repository.inner())
.context("failed to write tree to repo")?;
Ok(tree_oid)
}
@ -975,7 +975,7 @@ fn build_branches_tree(gb_repository: &Repository) -> Result<git2::Oid> {
}
let tree_oid = index
.write_tree_to(&gb_repository.git_repository)
.write_tree_to(&gb_repository.git_repository.inner())
.context("failed to write index to tree")?;
Ok(tree_oid)
@ -999,7 +999,7 @@ fn build_log_tree(
}
let tree_oid = index
.write_tree_to(&gb_repository.git_repository)
.write_tree_to(&gb_repository.git_repository.inner())
.context("failed to write index to tree")?;
Ok(tree_oid)
@ -1059,7 +1059,7 @@ fn build_session_tree(gb_repository: &Repository) -> Result<git2::Oid> {
}
let tree_oid = index
.write_tree_to(&gb_repository.git_repository)
.write_tree_to(&gb_repository.git_repository.inner())
.context("failed to write index to tree")?;
Ok(tree_oid)

View File

@ -1 +1,4 @@
pub mod credentials;
mod repository;
pub use repository::Repository;

View File

@ -0,0 +1,139 @@
use std::path;
// wrapper around git2::Repository to get control over how it's used.
pub struct Repository(git2::Repository);
type Result<T> = std::result::Result<T, git2::Error>;
impl Repository {
pub fn init<P: AsRef<path::Path>>(path: P) -> Result<Self> {
let inner = git2::Repository::init(path)?;
Ok(Repository(inner))
}
pub fn open<P: AsRef<path::Path>>(path: P) -> Result<Self> {
let inner = git2::Repository::open(path)?;
Ok(Repository(inner))
}
pub fn init_opts<P: AsRef<path::Path>>(
path: P,
opts: &git2::RepositoryInitOptions,
) -> Result<Self> {
let inner = git2::Repository::init_opts(path, opts)?;
Ok(Repository(inner))
}
pub fn inner(&self) -> &git2::Repository {
&self.0
}
pub fn revparse_single(&self, spec: &str) -> Result<git2::Object> {
self.0.revparse_single(spec)
}
pub fn find_reference(&self, name: &str) -> Result<git2::Reference> {
self.0.find_reference(name)
}
pub fn head(&self) -> Result<git2::Reference> {
self.0.head()
}
pub fn find_tree(&self, id: git2::Oid) -> Result<git2::Tree> {
self.0.find_tree(id)
}
pub fn find_commit(&self, id: git2::Oid) -> Result<git2::Commit> {
self.0.find_commit(id)
}
pub fn find_blob(&self, id: git2::Oid) -> Result<git2::Blob> {
self.0.find_blob(id)
}
pub fn revwalk(&self) -> Result<git2::Revwalk> {
self.0.revwalk()
}
pub fn branches(&self, filter: Option<git2::BranchType>) -> Result<git2::Branches> {
self.0.branches(filter)
}
pub fn index(&self) -> Result<git2::Index> {
self.0.index()
}
pub fn blob_path(&self, path: &path::Path) -> Result<git2::Oid> {
self.0.blob_path(path)
}
pub fn blob(&self, data: &[u8]) -> Result<git2::Oid> {
self.0.blob(data)
}
pub fn commit(
&self,
update_ref: Option<&str>,
author: &git2::Signature<'_>,
committer: &git2::Signature<'_>,
message: &str,
tree: &git2::Tree<'_>,
parents: &[&git2::Commit<'_>],
) -> Result<git2::Oid> {
self.0
.commit(update_ref, author, committer, message, tree, parents)
}
pub fn config(&self) -> Result<git2::Config> {
self.0.config()
}
pub fn treebuilder(&self, tree: Option<&git2::Tree>) -> Result<git2::TreeBuilder> {
self.0.treebuilder(tree)
}
pub fn path(&self) -> &path::Path {
self.0.path()
}
pub fn remote_anonymous(&self, url: &str) -> Result<git2::Remote> {
self.0.remote_anonymous(url)
}
#[cfg(test)]
pub fn refname_to_id(&self, name: &str) -> Result<git2::Oid> {
self.0.refname_to_id(name)
}
#[cfg(test)]
pub fn checkout_head(&self, opts: Option<&mut git2::build::CheckoutBuilder<'_>>) -> Result<()> {
self.0.checkout_head(opts)
}
#[cfg(test)]
pub fn set_head(&self, refname: &str) -> Result<()> {
self.0.set_head(refname)
}
#[cfg(test)]
pub fn reference(
&self,
name: &str,
id: git2::Oid,
force: bool,
log_message: &str,
) -> Result<git2::Reference> {
self.0.reference(name, id, force, log_message)
}
#[cfg(test)]
pub fn remote(&self, name: &str, url: &str) -> Result<git2::Remote> {
self.0.remote(name, url)
}
#[cfg(test)]
pub fn references(&self) -> Result<git2::References> {
self.0.references()
}
}

View File

@ -4,6 +4,8 @@ use anyhow::Result;
use serde::{Deserialize, Serialize};
use thiserror::Error;
use crate::git;
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct ApiProject {
pub name: String,
@ -137,10 +139,10 @@ impl Project {
}
}
impl TryFrom<&git2::Repository> for Project {
impl TryFrom<&git::Repository> for Project {
type Error = CreateError;
fn try_from(repository: &git2::Repository) -> std::result::Result<Self, Self::Error> {
fn try_from(repository: &git::Repository) -> std::result::Result<Self, Self::Error> {
Project::from_path(
repository
.path()

View File

@ -2,7 +2,7 @@ use std::{path, str};
use anyhow::{Context, Result};
use crate::fs;
use crate::{fs, git};
#[derive(Debug, PartialEq)]
pub enum Content {
@ -118,14 +118,14 @@ impl Reader for DirReader {
}
pub struct CommitReader<'reader> {
repository: &'reader git2::Repository,
repository: &'reader git::Repository,
commit_oid: git2::Oid,
tree: git2::Tree<'reader>,
}
impl<'reader> CommitReader<'reader> {
pub fn from_commit(
repository: &'reader git2::Repository,
repository: &'reader git::Repository,
commit: git2::Commit<'reader>,
) -> Result<CommitReader<'reader>> {
let tree = commit

View File

@ -1,16 +1,16 @@
use anyhow::{Context, Result};
use crate::reader::CommitReader;
use crate::{reader::CommitReader, git};
use super::{Session, SessionError};
pub struct SessionsIterator<'iterator> {
git_repository: &'iterator git2::Repository,
git_repository: &'iterator git::Repository,
iter: git2::Revwalk<'iterator>,
}
impl<'iterator> SessionsIterator<'iterator> {
pub(crate) fn new(git_repository: &'iterator git2::Repository) -> Result<Self> {
pub(crate) fn new(git_repository: &'iterator git::Repository) -> Result<Self> {
let mut iter = git_repository
.revwalk()
.context("failed to create revwalk")?;

View File

@ -2,15 +2,17 @@ use std::{fs, path};
use tempfile::tempdir;
use crate::git;
pub fn temp_dir() -> path::PathBuf {
let path = tempdir().unwrap().path().to_path_buf();
fs::create_dir_all(&path).unwrap();
path
}
pub fn test_repository() -> git2::Repository {
pub fn test_repository() -> git::Repository {
let path = temp_dir();
let repository = git2::Repository::init(path).expect("failed to init repository");
let repository = git::Repository::init(path).expect("failed to init repository");
let mut index = repository.index().expect("failed to get index");
let oid = index.write_tree().expect("failed to write tree");
let signature = git2::Signature::now("test", "test@email.com").unwrap();
@ -27,7 +29,7 @@ pub fn test_repository() -> git2::Repository {
repository
}
pub fn commit_all(repository: &git2::Repository) -> git2::Oid {
pub fn commit_all(repository: &git::Repository) -> git2::Oid {
let mut index = repository.index().expect("failed to get index");
index
.add_all(["."], git2::IndexAddOption::DEFAULT, None)

View File

@ -9,13 +9,15 @@ use std::{
use anyhow::{Context, Result};
use crate::{gb_repository, project_repository, projects, reader, sessions, test_utils, users};
use crate::{
gb_repository, git, project_repository, projects, reader, sessions, test_utils, users,
};
use super::branch::{Branch, BranchCreateRequest, Ownership};
use super::*;
pub struct TestDeps {
repository: git2::Repository,
repository: git::Repository,
project: projects::Project,
gb_repo: gb_repository::Repository,
gb_repo_path: path::PathBuf,
@ -50,7 +52,7 @@ fn new_test_deps() -> Result<TestDeps> {
fn set_test_target(
gb_repo: &gb_repository::Repository,
project_repository: &project_repository::Repository,
repository: &git2::Repository,
repository: &git::Repository,
) -> Result<()> {
target::Writer::new(gb_repo).write_default(&target::Target {
branch_name: "origin/master".to_string(),
@ -2722,7 +2724,7 @@ fn test_commit_executable_and_symlinks() -> Result<()> {
Ok(())
}
fn tree_to_file_list(repository: &git2::Repository, tree: &git2::Tree) -> Result<Vec<String>> {
fn tree_to_file_list(repository: &git::Repository, tree: &git2::Tree) -> Result<Vec<String>> {
let mut file_list = Vec::new();
for entry in tree.iter() {
let path = entry.name().unwrap();
@ -2730,7 +2732,7 @@ fn tree_to_file_list(repository: &git2::Repository, tree: &git2::Tree) -> Result
.get_path(std::path::Path::new(path))
.context(format!("failed to get tree entry for path {}", path))?;
let object = entry
.to_object(repository)
.to_object(repository.inner())
.context(format!("failed to get object for tree entry {}", path))?;
if object.kind() == Some(git2::ObjectType::Blob) {
file_list.push(path.to_string());
@ -2740,7 +2742,7 @@ fn tree_to_file_list(repository: &git2::Repository, tree: &git2::Tree) -> Result
}
fn tree_to_entry_list(
repository: &git2::Repository,
repository: &git::Repository,
tree: &git2::Tree,
) -> Result<Vec<(String, String, String, String)>> {
let mut file_list = Vec::new();
@ -2750,7 +2752,7 @@ fn tree_to_entry_list(
.get_path(std::path::Path::new(path))
.context(format!("failed to get tree entry for path {}", path))?;
let object = entry
.to_object(repository)
.to_object(repository.inner())
.context(format!("failed to get object for tree entry {}", path))?;
let blob = object.as_blob().context("failed to get blob")?;
// convert content to string

View File

@ -381,6 +381,7 @@ pub fn unapply_branch(
let target_commit = gb_repository
.git_repository
.inner()
.find_commit(default_target.sha)
.context("failed to find target commit")?;
@ -1059,6 +1060,7 @@ pub fn create_virtual_branch(
let repo = &gb_repository.git_repository;
let commit = repo
.inner()
.find_commit(default_target.sha)
.context("failed to find commit")?;
let tree = commit.tree().context("failed to find tree")?;