remove core::git::Repository shell type

This commit is contained in:
Kiril Videlov 2024-06-05 01:11:10 +02:00
parent 4c7a8ce9b9
commit e63081c69d
19 changed files with 504 additions and 747 deletions

View File

@ -122,7 +122,9 @@ impl Helper {
Ok(remote)
} else {
let ssh_url = remote_url.as_ssh()?;
project_repository.git_repository.remote_anonymous(&ssh_url)
project_repository
.git_repository
.remote_anonymous(&ssh_url.to_string())
}?;
Ok(vec![(
@ -138,7 +140,9 @@ impl Helper {
Ok(remote)
} else {
let url = remote_url.as_https()?;
project_repository.git_repository.remote_anonymous(&url)
project_repository
.git_repository
.remote_anonymous(&url.to_string())
}?;
let flow = Self::https_flow(project_repository, &remote_url)?
.into_iter()
@ -170,7 +174,9 @@ impl Helper {
Ok(remote)
} else {
let ssh_url = remote_url.as_ssh()?;
project_repository.git_repository.remote_anonymous(&ssh_url)
project_repository
.git_repository
.remote_anonymous(&ssh_url.to_string())
}?;
let key = self.keys.get_or_create()?;

View File

@ -7,7 +7,6 @@ use bstr::{BStr, BString, ByteSlice, ByteVec};
use serde::{Deserialize, Serialize};
use tracing::instrument;
use super::Repository;
use crate::git;
use crate::id::Id;
use crate::virtual_branches::Branch;
@ -129,7 +128,7 @@ pub struct FileDiff {
}
#[instrument(skip(repository))]
pub fn workdir(repository: &Repository, commit_oid: &git::Oid) -> Result<DiffByPathMap> {
pub fn workdir(repository: &git2::Repository, commit_oid: &git2::Oid) -> Result<DiffByPathMap> {
let commit = repository
.find_commit(*commit_oid)
.context("failed to find commit")?;
@ -159,7 +158,7 @@ pub fn workdir(repository: &Repository, commit_oid: &git::Oid) -> Result<DiffByP
}
pub fn trees(
repository: &Repository,
repository: &git2::Repository,
old_tree: &git2::Tree,
new_tree: &git2::Tree,
) -> Result<DiffByPathMap> {
@ -218,7 +217,10 @@ pub fn without_large_files(
/// `repository` should be `None` if there is no reason to access the workdir, which it will do to
/// keep the binary data in the object database, which otherwise would be lost to the system
/// (it's not reconstructable from the delta, or it's not attempted).
pub fn hunks_by_filepath(repo: Option<&Repository>, diff: &git2::Diff) -> Result<DiffByPathMap> {
pub fn hunks_by_filepath(
repo: Option<&git2::Repository>,
diff: &git2::Diff,
) -> Result<DiffByPathMap> {
enum LineOrHexHash<'a> {
Line(Cow<'a, BStr>),
HexHashOfBinaryBlob(String),
@ -259,7 +261,7 @@ pub fn hunks_by_filepath(repo: Option<&Repository>, diff: &git2::Diff) -> Result
{
if !delta.new_file().id().is_zero() && full_path.exists() {
let oid = repo.blob_path(full_path.as_path()).unwrap();
if delta.new_file().id() != oid.into() {
if delta.new_file().id() != oid {
err = Some(format!("we only store the file which is already known by the diff system, but it was different: {} != {}", delta.new_file().id(), oid));
return false
}

View File

@ -6,9 +6,6 @@ pub use error::*;
mod reference;
pub use reference::*;
mod repository;
pub use repository::*;
mod oid;
pub use oid::*;

View File

@ -1,406 +0,0 @@
use super::{Oid, Refname, Result, Url};
use git2::Submodule;
use git2_hooks::HookResult;
use std::{path::Path, str};
// wrapper around git2::Repository to get control over how it's used.
pub struct Repository(git2::Repository);
impl<'a> From<&'a Repository> for &'a git2::Repository {
fn from(repo: &'a Repository) -> Self {
&repo.0
}
}
impl From<git2::Repository> for Repository {
fn from(repo: git2::Repository) -> Self {
Self(repo)
}
}
impl Repository {
pub fn init<P: AsRef<Path>>(path: P) -> Result<Self> {
let inner = git2::Repository::init(path)?;
Ok(Repository(inner))
}
pub fn init_opts<P: AsRef<Path>>(path: P, opts: &git2::RepositoryInitOptions) -> Result<Self> {
let inner = git2::Repository::init_opts(path, opts)?;
Ok(Repository(inner))
}
pub fn open<P: AsRef<Path>>(path: P) -> Result<Self> {
let inner = git2::Repository::open(path)?;
Ok(Repository(inner))
}
pub fn add_submodule<P: AsRef<Path>>(&self, url: &Url, path: P) -> Result<Submodule<'_>> {
self.0
.submodule(&url.to_string(), path.as_ref(), false)
.map_err(Into::into)
}
pub fn rebase(
&self,
branch_oid: Option<Oid>,
upstream_oid: Option<Oid>,
onto_oid: Option<Oid>,
opts: Option<&mut git2::RebaseOptions<'_>>,
) -> Result<git2::Rebase<'_>> {
let annotated_branch = if let Some(branch) = branch_oid {
Some(self.0.find_annotated_commit(branch.into())?)
} else {
None
};
let annotated_upstream = if let Some(upstream) = upstream_oid {
Some(self.0.find_annotated_commit(upstream.into())?)
} else {
None
};
let annotated_onto = if let Some(onto) = onto_oid {
Some(self.0.find_annotated_commit(onto.into())?)
} else {
None
};
self.0
.rebase(
annotated_branch.as_ref(),
annotated_upstream.as_ref(),
annotated_onto.as_ref(),
opts,
)
.map_err(Into::into)
}
pub fn merge_base(&self, one: Oid, two: Oid) -> Result<Oid> {
self.0
.merge_base(one.into(), two.into())
.map(Oid::from)
.map_err(Into::into)
}
pub fn merge_trees(
&self,
ancestor_tree: &git2::Tree<'_>,
our_tree: &git2::Tree<'_>,
their_tree: &git2::Tree<'_>,
) -> Result<git2::Index> {
self.0
.merge_trees(ancestor_tree, our_tree, their_tree, None)
.map_err(Into::into)
}
pub fn diff_tree_to_tree(
&self,
old_tree: Option<&git2::Tree<'_>>,
new_tree: Option<&git2::Tree<'_>>,
opts: Option<&mut git2::DiffOptions>,
) -> Result<git2::Diff<'_>> {
self.0
.diff_tree_to_tree(old_tree, new_tree, opts)
.map_err(Into::into)
}
pub fn diff_tree_to_workdir(
&self,
old_tree: Option<&git2::Tree<'_>>,
opts: Option<&mut git2::DiffOptions>,
) -> Result<git2::Diff<'_>> {
if let Ok(mut index) = self.0.index() {
index.update_all(vec!["*"], None)?;
}
self.0
.diff_tree_to_workdir_with_index(old_tree, opts)
.map_err(Into::into)
}
pub fn reset(
&self,
commit: &git2::Commit<'_>,
kind: git2::ResetType,
checkout: Option<&mut git2::build::CheckoutBuilder<'_>>,
) -> Result<()> {
let commit: &git2::Commit = commit;
self.0
.reset(commit.as_object(), kind, checkout)
.map_err(Into::into)
}
pub fn find_reference(&self, name: &Refname) -> Result<git2::Reference> {
self.0.find_reference(&name.to_string()).map_err(Into::into)
}
pub fn head(&self) -> Result<git2::Reference> {
self.0.head().map_err(Into::into)
}
pub fn find_tree(&self, id: Oid) -> Result<git2::Tree> {
self.0.find_tree(id.into()).map_err(Into::into)
}
pub fn find_commit(&self, id: Oid) -> Result<git2::Commit> {
self.0.find_commit(id.into()).map_err(Into::into)
}
pub fn revwalk(&self) -> Result<git2::Revwalk> {
self.0.revwalk().map_err(Into::into)
}
pub fn is_path_ignored<P: AsRef<Path>>(&self, path: P) -> Result<bool> {
self.0.is_path_ignored(path).map_err(Into::into)
}
pub fn branches(
&self,
filter: Option<git2::BranchType>,
) -> Result<impl Iterator<Item = Result<git2::Branch>>> {
self.0
.branches(filter)
.map(|branches| {
branches.map(|branch| branch.map(|(branch, _)| branch).map_err(Into::into))
})
.map_err(Into::into)
}
pub fn index(&self) -> Result<git2::Index> {
self.0.index().map_err(Into::into)
}
pub fn index_size(&self) -> Result<usize> {
Ok(self.0.index()?.len())
}
pub fn blob_path<P: AsRef<Path>>(&self, path: P) -> Result<Oid> {
self.0
.blob_path(path.as_ref())
.map(Into::into)
.map_err(Into::into)
}
pub fn cherry_pick(&self, base: &git2::Commit, target: &git2::Commit) -> Result<git2::Index> {
self.0
.cherrypick_commit(target, base, 0, None)
.map_err(Into::into)
}
pub fn blob(&self, data: &[u8]) -> Result<Oid> {
self.0.blob(data).map(Into::into).map_err(Into::into)
}
pub fn config(&self) -> Result<git2::Config> {
self.0.config().map_err(Into::into)
}
pub fn path(&self) -> &Path {
self.0.path()
}
pub fn workdir(&self) -> Option<&Path> {
self.0.workdir()
}
pub fn statuses(
&self,
options: Option<&mut git2::StatusOptions>,
) -> Result<git2::Statuses<'_>> {
self.0.statuses(options).map_err(Into::into)
}
pub fn remote_anonymous(&self, url: &super::Url) -> Result<git2::Remote> {
self.0
.remote_anonymous(&url.to_string())
.map_err(Into::into)
}
pub fn find_remote(&self, name: &str) -> Result<git2::Remote> {
self.0.find_remote(name).map_err(Into::into)
}
pub fn find_branch(&self, name: &Refname) -> Result<git2::Branch> {
self.0
.find_branch(
&name.simple_name(),
match name {
Refname::Virtual(_) | Refname::Local(_) | Refname::Other(_) => {
git2::BranchType::Local
}
Refname::Remote(_) => git2::BranchType::Remote,
},
)
.map_err(Into::into)
}
pub fn refname_to_id(&self, name: &str) -> Result<Oid> {
self.0
.refname_to_id(name)
.map(Into::into)
.map_err(Into::into)
}
pub fn checkout_head(&self, opts: Option<&mut git2::build::CheckoutBuilder>) -> Result<()> {
self.0.checkout_head(opts).map_err(Into::into)
}
pub fn checkout_index<'a>(&'a self, index: &'a mut git2::Index) -> CheckoutIndexBuilder {
CheckoutIndexBuilder {
index,
repo: &self.0,
checkout_builder: git2::build::CheckoutBuilder::new(),
}
}
pub fn checkout_index_path<P: AsRef<Path>>(&self, path: P) -> Result<()> {
let mut builder = git2::build::CheckoutBuilder::new();
builder.path(path.as_ref());
builder.force();
let mut index = self.0.index()?;
self.0
.checkout_index(Some(&mut index), Some(&mut builder))?;
Ok(())
}
pub fn checkout_tree<'a>(&'a self, tree: &'a git2::Tree<'a>) -> CheckoutTreeBuidler {
CheckoutTreeBuidler {
tree,
repo: &self.0,
checkout_builder: git2::build::CheckoutBuilder::new(),
}
}
pub fn set_head(&self, refname: &Refname) -> Result<()> {
self.0.set_head(&refname.to_string()).map_err(Into::into)
}
pub fn set_head_detached(&self, commitish: Oid) -> Result<()> {
self.0
.set_head_detached(commitish.into())
.map_err(Into::into)
}
pub fn reference(
&self,
name: &Refname,
id: Oid,
force: bool,
log_message: &str,
) -> Result<git2::Reference> {
self.0
.reference(&name.to_string(), id.into(), force, log_message)
.map(Into::into)
.map_err(Into::into)
}
pub fn remote(&self, name: &str, url: &Url) -> Result<git2::Remote> {
self.0.remote(name, &url.to_string()).map_err(Into::into)
}
pub fn references(&self) -> Result<impl Iterator<Item = Result<git2::Reference>>> {
self.0
.references()
.map(|iter| iter.map(|reference| reference.map(Into::into).map_err(Into::into)))
.map_err(Into::into)
}
pub fn references_glob(
&self,
glob: &str,
) -> Result<impl Iterator<Item = Result<git2::Reference>>> {
self.0
.references_glob(glob)
.map(|iter| iter.map(|reference| reference.map(Into::into).map_err(Into::into)))
.map_err(Into::into)
}
pub fn run_hook_pre_commit(&self) -> Result<HookResult> {
let res = git2_hooks::hooks_pre_commit(&self.0, Some(&["../.husky"]))?;
Ok(res)
}
pub fn run_hook_commit_msg(&self, msg: &mut String) -> Result<HookResult> {
let res = git2_hooks::hooks_commit_msg(&self.0, Some(&["../.husky"]), msg)?;
Ok(res)
}
pub fn run_hook_post_commit(&self) -> Result<()> {
git2_hooks::hooks_post_commit(&self.0, Some(&["../.husky"]))?;
Ok(())
}
/// Returns a list of remotes
///
/// Returns `Vec<String>` instead of StringArray because StringArray cannot safly be sent between threads
pub fn remotes(&self) -> Result<Vec<String>> {
self.0
.remotes()
.map(|string_array| {
string_array
.iter()
.filter_map(|s| s.map(String::from))
.collect()
})
.map_err(super::Error::Remotes)
}
pub fn add_remote(&self, name: &str, url: &str) -> Result<()> {
self.0.remote(name, url)?;
Ok(())
}
}
pub struct CheckoutTreeBuidler<'a> {
repo: &'a git2::Repository,
tree: &'a git2::Tree<'a>,
checkout_builder: git2::build::CheckoutBuilder<'a>,
}
impl CheckoutTreeBuidler<'_> {
pub fn force(&mut self) -> &mut Self {
self.checkout_builder.force();
self
}
pub fn remove_untracked(&mut self) -> &mut Self {
self.checkout_builder.remove_untracked(true);
self
}
pub fn checkout(&mut self) -> Result<()> {
self.repo
.checkout_tree(self.tree.as_object(), Some(&mut self.checkout_builder))
.map_err(Into::into)
}
}
pub struct CheckoutIndexBuilder<'a> {
repo: &'a git2::Repository,
index: &'a mut git2::Index,
checkout_builder: git2::build::CheckoutBuilder<'a>,
}
impl CheckoutIndexBuilder<'_> {
pub fn force(&mut self) -> &mut Self {
self.checkout_builder.force();
self
}
pub fn allow_conflicts(&mut self) -> &mut Self {
self.checkout_builder.allow_conflicts(true);
self
}
pub fn conflict_style_merge(&mut self) -> &mut Self {
self.checkout_builder.conflict_style_merge(true);
self
}
pub fn checkout(&mut self) -> Result<()> {
self.repo
.checkout_index(Some(&mut self.index), Some(&mut self.checkout_builder))
.map_err(Into::into)
}
}

View File

@ -16,6 +16,10 @@ use std::os::windows::process::CommandExt;
///
/// For now, it collects useful methods from `gitbutler-core::git::Repository`
pub trait RepositoryExt {
fn checkout_index_builder<'a>(&'a self, index: &'a mut git2::Index) -> CheckoutIndexBuilder;
fn checkout_index_path_builder<P: AsRef<Path>>(&self, path: P) -> Result<()>;
fn checkout_tree_builder<'a>(&'a self, tree: &'a git2::Tree<'a>) -> CheckoutTreeBuidler;
fn find_branch_by_refname(&self, name: &Refname) -> Result<git2::Branch, git2::Error>;
/// Based on the index, add all data similar to `git add .` and create a tree from it, which is returned.
fn get_wd_tree(&self) -> Result<Tree>;
@ -49,6 +53,45 @@ pub trait RepositoryExt {
}
impl RepositoryExt for Repository {
fn checkout_index_builder<'a>(&'a self, index: &'a mut git2::Index) -> CheckoutIndexBuilder {
CheckoutIndexBuilder {
index,
repo: self,
checkout_builder: git2::build::CheckoutBuilder::new(),
}
}
fn checkout_index_path_builder<P: AsRef<Path>>(&self, path: P) -> Result<()> {
let mut builder = git2::build::CheckoutBuilder::new();
builder.path(path.as_ref());
builder.force();
let mut index = self.index()?;
self.checkout_index(Some(&mut index), Some(&mut builder))?;
Ok(())
}
fn checkout_tree_builder<'a>(&'a self, tree: &'a git2::Tree<'a>) -> CheckoutTreeBuidler {
CheckoutTreeBuidler {
tree,
repo: self,
checkout_builder: git2::build::CheckoutBuilder::new(),
}
}
fn find_branch_by_refname(&self, name: &Refname) -> Result<git2::Branch, git2::Error> {
self.find_branch(
&name.simple_name(),
match name {
Refname::Virtual(_) | Refname::Local(_) | Refname::Other(_) => {
git2::BranchType::Local
}
Refname::Remote(_) => git2::BranchType::Remote,
},
)
// .map_err(Into::into)
}
#[instrument(level = tracing::Level::DEBUG, skip(self), err(Debug))]
fn get_wd_tree(&self) -> Result<Tree> {
let mut index = self.index()?;
@ -254,3 +297,56 @@ fn inject_change_id(commit_buffer: &[u8], change_id: Option<&str>) -> Result<Str
}
Ok(new_buffer)
}
pub struct CheckoutTreeBuidler<'a> {
repo: &'a git2::Repository,
tree: &'a git2::Tree<'a>,
checkout_builder: git2::build::CheckoutBuilder<'a>,
}
impl CheckoutTreeBuidler<'_> {
pub fn force(&mut self) -> &mut Self {
self.checkout_builder.force();
self
}
pub fn remove_untracked(&mut self) -> &mut Self {
self.checkout_builder.remove_untracked(true);
self
}
pub fn checkout(&mut self) -> Result<()> {
self.repo
.checkout_tree(self.tree.as_object(), Some(&mut self.checkout_builder))
.map_err(Into::into)
}
}
pub struct CheckoutIndexBuilder<'a> {
repo: &'a git2::Repository,
index: &'a mut git2::Index,
checkout_builder: git2::build::CheckoutBuilder<'a>,
}
impl CheckoutIndexBuilder<'_> {
pub fn force(&mut self) -> &mut Self {
self.checkout_builder.force();
self
}
pub fn allow_conflicts(&mut self) -> &mut Self {
self.checkout_builder.allow_conflicts(true);
self
}
pub fn conflict_style_merge(&mut self) -> &mut Self {
self.checkout_builder.conflict_style_merge(true);
self
}
pub fn checkout(&mut self) -> Result<()> {
self.repo
.checkout_index(Some(&mut self.index), Some(&mut self.checkout_builder))
.map_err(Into::into)
}
}

View File

@ -1,11 +1,11 @@
use crate::git;
pub struct Config<'a> {
git_repository: &'a git::Repository,
git_repository: &'a git2::Repository,
}
impl<'a> From<&'a git::Repository> for Config<'a> {
fn from(value: &'a git::Repository) -> Self {
impl<'a> From<&'a git2::Repository> for Config<'a> {
fn from(value: &'a git2::Repository) -> Self {
Self {
git_repository: value,
}

View File

@ -9,7 +9,7 @@ use anyhow::{anyhow, Context, Result};
use super::conflicts;
use crate::{
askpass,
git::{self, Url},
git::{self, Refname, Url},
projects::{self, AuthKey},
ssh, users,
virtual_branches::{Branch, BranchId},
@ -18,19 +18,13 @@ use crate::{error::Code, git::Oid};
use crate::{git::RepositoryExt, virtual_branches::errors::Marker};
pub struct Repository {
pub git_repository: git::Repository,
pub git_repository: git2::Repository,
project: projects::Project,
}
impl Repository {
pub fn open(project: &projects::Project) -> Result<Self> {
let repo = git::Repository::open(&project.path).map_err(|err| match err {
git::Error::NotFound(_) => anyhow::Error::from(err).context(format!(
"repository not found at \"{}\"",
project.path.display()
)),
other => other.into(),
})?;
let repo = git2::Repository::open(&project.path)?;
// XXX(qix-): This is a temporary measure to disable GC on the project repository.
// XXX(qix-): We do this because the internal repository we use to store the "virtual"
@ -118,7 +112,7 @@ impl Repository {
}
pub fn git_index_size(&self) -> Result<usize, git::Error> {
let head = self.git_repository.index_size()?;
let head = self.git_repository.index()?.len();
Ok(head)
}
@ -141,7 +135,7 @@ impl Repository {
self.git_repository
.branches(Some(git2::BranchType::Remote))?
.flatten()
.map(|branch| {
.map(|(branch, _)| {
git::RemoteRefname::try_from(&branch)
.context("failed to convert branch to remote name")
})
@ -157,7 +151,15 @@ impl Repository {
) -> Result<()> {
let target_branch_refname =
git::Refname::from_str(&format!("refs/remotes/{}/{}", remote_name, branch_name))?;
let branch = self.git_repository.find_branch(&target_branch_refname)?;
let branch = self.git_repository.find_branch(
&target_branch_refname.simple_name(),
match target_branch_refname {
Refname::Virtual(_) | Refname::Local(_) | Refname::Other(_) => {
git2::BranchType::Local
}
Refname::Remote(_) => git2::BranchType::Remote,
},
)?;
let commit_id: Oid = branch.get().peel_to_commit()?.id().into();
let now = crate::time::now_ms();
@ -188,22 +190,26 @@ impl Repository {
}
pub fn add_branch_reference(&self, branch: &Branch) -> Result<()> {
let (should_write, with_force) =
match self.git_repository.find_reference(&branch.refname().into()) {
Ok(reference) => match reference.target() {
Some(head_oid) => Ok((head_oid != branch.head.into(), true)),
None => Ok((true, true)),
},
Err(git::Error::NotFound(_)) => Ok((true, false)),
Err(error) => Err(error),
}
.context("failed to lookup reference")?;
let (should_write, with_force) = match self
.git_repository
.find_reference(&branch.refname().to_string())
{
Ok(reference) => match reference.target() {
Some(head_oid) => Ok((head_oid != branch.head.into(), true)),
None => Ok((true, true)),
},
Err(err) => match err.code() {
git2::ErrorCode::NotFound => Ok((true, false)),
_ => Err(err),
},
}
.context("failed to lookup reference")?;
if should_write {
self.git_repository
.reference(
&branch.refname().into(),
branch.head,
&branch.refname().to_string(),
branch.head.into(),
with_force,
"new vbranch",
)
@ -214,15 +220,20 @@ impl Repository {
}
pub fn delete_branch_reference(&self, branch: &Branch) -> Result<()> {
match self.git_repository.find_reference(&branch.refname().into()) {
match self
.git_repository
.find_reference(&branch.refname().to_string())
{
Ok(mut reference) => {
reference
.delete()
.context("failed to delete branch reference")?;
Ok(())
}
Err(git::Error::NotFound(_)) => Ok(()),
Err(error) => Err(error),
Err(err) => match err.code() {
git2::ErrorCode::NotFound => Ok(()),
_ => Err(err),
},
}
.context("failed to lookup reference")
}
@ -273,7 +284,7 @@ impl Repository {
let commit = self
.git_repository
.find_commit(oid.into())
.find_commit(oid)
.context("failed to find commit")?;
if cond(&commit).context("failed to check condition")? {
@ -307,7 +318,7 @@ impl Repository {
Ok(self
.list(from, to)?
.into_iter()
.map(|oid| self.git_repository.find_commit(oid))
.map(|oid| self.git_repository.find_commit(oid.into()))
.collect::<Result<Vec<_>, _>>()?)
}
@ -315,7 +326,7 @@ impl Repository {
pub fn log(&self, from: git::Oid, to: LogUntil) -> Result<Vec<git2::Commit>> {
self.l(from, to)?
.into_iter()
.map(|oid| self.git_repository.find_commit(oid))
.map(|oid| self.git_repository.find_commit(oid.into()))
.collect::<Result<Vec<_>, _>>()
.context("failed to collect commits")
}
@ -389,7 +400,7 @@ impl Repository {
let headers = &[auth_header.as_str()];
push_options.custom_headers(headers);
let mut remote = self.git_repository.remote_anonymous(&url)?;
let mut remote = self.git_repository.remote_anonymous(&url.to_string())?;
remote
.push(ref_specs, Some(&mut push_options))
@ -600,15 +611,21 @@ impl Repository {
}
pub fn remotes(&self) -> Result<Vec<String>> {
Ok(self.git_repository.remotes()?)
Ok(self.git_repository.remotes().map(|string_array| {
string_array
.iter()
.filter_map(|s| s.map(String::from))
.collect()
})?)
}
pub fn add_remote(&self, name: &str, url: &str) -> Result<()> {
Ok(self.git_repository.add_remote(name, url)?)
self.git_repository.remote(name, url)?;
Ok(())
}
pub fn repo(&self) -> &git2::Repository {
(&self.git_repository).into()
&self.git_repository
}
}

View File

@ -104,7 +104,7 @@ async fn push_target(
}
fn batch_rev_walk(
repo: &crate::git::Repository,
repo: &git2::Repository,
batch_size: usize,
from: Oid,
until: Option<Oid>,

View File

@ -11,7 +11,7 @@ use super::{
},
target, BranchId, RemoteCommit, VirtualBranchHunk, VirtualBranchesHandle,
};
use crate::virtual_branches::errors::Marker;
use crate::{git::RepositoryExt, virtual_branches::errors::Marker};
use crate::{
git::{self, diff},
project_repository::{self, LogUntil},
@ -72,7 +72,7 @@ fn go_back_to_integration(
let target_commit = project_repository
.git_repository
.find_commit(default_target.sha)
.find_commit(default_target.sha.into())
.context("failed to find target commit")?;
let base_tree = target_commit
@ -85,27 +85,27 @@ fn go_back_to_integration(
// merge this branches tree with our tree
let branch_head = project_repository
.git_repository
.find_commit(branch.head)
.find_commit(branch.head.into())
.context("failed to find branch head")?;
let branch_tree = branch_head
.tree()
.context("failed to get branch head tree")?;
let mut result = project_repository
.git_repository
.merge_trees(&base_tree, &final_tree, &branch_tree)
.merge_trees(&base_tree, &final_tree, &branch_tree, None)
.context("failed to merge")?;
let final_tree_oid = result
.write_tree_to(project_repository.repo())
.context("failed to write tree")?;
final_tree = project_repository
.git_repository
.find_tree(final_tree_oid.into())
.find_tree(final_tree_oid)
.context("failed to find written tree")?;
}
project_repository
.git_repository
.checkout_tree(&final_tree)
.checkout_tree_builder(&final_tree)
.force()
.checkout()
.context("failed to checkout tree")?;
@ -129,9 +129,11 @@ pub fn set_base_branch(
}
// lookup a branch by name
let target_branch = match repo.find_branch(&target_branch_ref.clone().into()) {
let target_branch = match repo.find_branch_by_refname(&target_branch_ref.clone().into()) {
Ok(branch) => branch,
Err(git::Error::NotFound(_)) => bail!("remote branch '{}' not found", target_branch_ref),
Err(err) if err.code() == git2::ErrorCode::NotFound => {
bail!("remote branch '{}' not found", target_branch_ref)
}
Err(err) => return Err(err.into()),
};
@ -158,10 +160,7 @@ pub fn set_base_branch(
// calculate the commit as the merge-base between HEAD in project_repository and this target commit
let target_commit_oid = repo
.merge_base(
current_head_commit.id().into(),
target_branch_head.id().into(),
)
.merge_base(current_head_commit.id(), target_branch_head.id())
.context(format!(
"Failed to calculate merge base between {} and {}",
current_head_commit.id(),
@ -171,7 +170,7 @@ pub fn set_base_branch(
let target = target::Target {
branch: target_branch_ref.clone(),
remote_url: remote_url.to_string(),
sha: target_commit_oid,
sha: target_commit_oid.into(),
push_remote_name: None,
};
@ -190,7 +189,7 @@ pub fn set_base_branch(
// if there are any commits on the head branch or uncommitted changes in the working directory, we need to
// put them into a virtual branch
let wd_diff = diff::workdir(repo, &current_head_commit.id().into())?;
let wd_diff = diff::workdir(repo, &current_head_commit.id())?;
if !wd_diff.is_empty() || current_head_commit.id() != target.sha.into() {
// assign ownership to the branch
let ownership = wd_diff.iter().fold(
@ -218,7 +217,7 @@ pub fn set_base_branch(
if upstream_name.eq(target_branch_ref) {
(None, None)
} else {
match repo.find_reference(&git::Refname::from(&upstream_name)) {
match repo.find_reference(&git::Refname::from(&upstream_name).to_string()) {
Ok(upstream) => {
let head = upstream
.peel_to_commit()
@ -229,7 +228,7 @@ pub fn set_base_branch(
))?;
Ok((Some(upstream_name), Some(head)))
}
Err(git::Error::NotFound(_)) => Ok((None, None)),
Err(err) if err.code() == git2::ErrorCode::NotFound => Ok((None, None)),
Err(error) => Err(error),
}
.context(format!("failed to find upstream for {}", head_name))?
@ -337,7 +336,7 @@ pub fn update_base_branch(
let target = default_target(&project_repository.project().gb_dir())?;
let repo = &project_repository.git_repository;
let target_branch = repo
.find_branch(&target.branch.clone().into())
.find_branch_by_refname(&target.branch.clone().into())
.context(format!("failed to find branch {}", target.branch))?;
let new_target_commit = target_branch
@ -355,10 +354,13 @@ pub fn update_base_branch(
.tree()
.context("failed to get new target commit tree")?;
let old_target_tree = repo.find_commit(target.sha)?.tree().context(format!(
"failed to get old target commit tree {}",
target.sha
))?;
let old_target_tree = repo
.find_commit(target.sha.into())?
.tree()
.context(format!(
"failed to get old target commit tree {}",
target.sha
))?;
let vb_state = project_repository.project().virtual_branches();
let integration_commit = get_workspace_head(&vb_state, project_repository)?;
@ -371,12 +373,13 @@ pub fn update_base_branch(
.map(|(branch, _)| branch)
.map(
|mut branch: branch::Branch| -> Result<Option<branch::Branch>> {
let branch_tree = repo.find_tree(branch.tree)?;
let branch_tree = repo.find_tree(branch.tree.into())?;
let branch_head_commit = repo.find_commit(branch.head).context(format!(
"failed to find commit {} for branch {}",
branch.head, branch.id
))?;
let branch_head_commit =
repo.find_commit(branch.head.into()).context(format!(
"failed to find commit {} for branch {}",
branch.head, branch.id
))?;
let branch_head_tree = branch_head_commit.tree().context(format!(
"failed to find tree for commit {} for branch {}",
branch.head, branch.id
@ -417,7 +420,7 @@ pub fn update_base_branch(
// try to merge branch head with new target
let mut branch_tree_merge_index = repo
.merge_trees(&old_target_tree, &branch_tree, &new_target_tree)
.merge_trees(&old_target_tree, &branch_tree, &new_target_tree, None)
.context(format!("failed to merge trees for branch {}", branch.id))?;
if branch_tree_merge_index.has_conflicts() {
@ -446,7 +449,7 @@ pub fn update_base_branch(
}
let mut branch_head_merge_index = repo
.merge_trees(&old_target_tree, &branch_head_tree, &new_target_tree)
.merge_trees(&old_target_tree, &branch_head_tree, &new_target_tree, None)
.context(format!(
"failed to merge head tree for branch {}",
branch.id
@ -478,7 +481,7 @@ pub fn update_base_branch(
// branch was pushed to upstream, and user doesn't like force pushing.
// create a merge commit to avoid the need of force pushing then.
let branch_head_merge_tree = repo
.find_tree(branch_head_merge_tree_oid.into())
.find_tree(branch_head_merge_tree_oid)
.context("failed to find tree")?;
let new_target_head = project_repository
@ -543,7 +546,7 @@ pub fn update_base_branch(
.iter()
.filter(|branch| branch.applied)
.fold(new_target_commit.tree(), |final_tree, branch| {
let repo: &git2::Repository = repo.into();
let repo: &git2::Repository = repo;
let final_tree = final_tree?;
let branch_tree = repo.find_tree(branch.tree.into())?;
let mut merge_result: Index =
@ -553,7 +556,7 @@ pub fn update_base_branch(
})
.context("failed to calculate final tree")?;
repo.checkout_tree(&final_tree)
repo.checkout_tree_builder(&final_tree)
.force()
.checkout()
.context("failed to checkout index, this should not have happened, we should have already detected this")?;
@ -574,7 +577,7 @@ pub fn target_to_base_branch(
target: &target::Target,
) -> Result<super::BaseBranch> {
let repo = &project_repository.git_repository;
let branch = repo.find_branch(&target.branch.clone().into())?;
let branch = repo.find_branch_by_refname(&target.branch.clone().into())?;
let commit = branch.get().peel_to_commit()?;
let oid = commit.id();

View File

@ -14,13 +14,15 @@ pub struct RemoteBranchFile {
}
pub fn list_remote_commit_files(
repository: &git::Repository,
repository: &git2::Repository,
commit_id: git::Oid,
) -> Result<Vec<RemoteBranchFile>> {
let commit = repository.find_commit(commit_id).map_err(|err| match err {
git::Error::NotFound(_) => anyhow!("commit {commit_id} not found"),
err => err.into(),
})?;
let commit = repository
.find_commit(commit_id.into())
.map_err(|err| match err.code() {
git2::ErrorCode::NotFound => anyhow!("commit {commit_id} not found"),
_ => err.into(),
})?;
// If it's a merge commit, we list nothing. In the future we could to a fork exec of `git diff-tree --cc`
if commit.parent_count() != 1 {

View File

@ -40,7 +40,7 @@ pub fn get_workspace_head(
let target = vb_state
.get_default_target()
.context("failed to get target")?;
let repo: &git2::Repository = (&project_repo.git_repository).into();
let repo: &git2::Repository = &project_repo.git_repository;
let vb_state = project_repo.project().virtual_branches();
let all_virtual_branches = vb_state.list_branches()?;
@ -149,7 +149,7 @@ pub fn update_gitbutler_integration(
.get_default_target()
.context("failed to get target")?;
let repo: &git2::Repository = (&project_repository.git_repository).into();
let repo: &git2::Repository = &project_repository.git_repository;
// get commit object from target.sha
let target_commit = repo.find_commit(target.sha.into())?;
@ -362,7 +362,7 @@ impl project_repository::Repository {
self.git_repository
.reset(
integration_commit.as_ref().unwrap(),
integration_commit.as_ref().unwrap().as_object(),
git2::ResetType::Soft,
None,
)
@ -386,7 +386,7 @@ impl project_repository::Repository {
for commit in extra_commits {
let new_branch_head = self
.git_repository
.find_commit(head)
.find_commit(head.into())
.context("failed to find new branch head")?;
let rebased_commit_oid = self
@ -407,7 +407,7 @@ impl project_repository::Repository {
let rebased_commit = self
.git_repository
.find_commit(rebased_commit_oid.into())
.find_commit(rebased_commit_oid)
.context(format!(
"failed to find rebased commit {}",
rebased_commit_oid

View File

@ -6,7 +6,7 @@ use serde::Serialize;
use super::{target, Author, VirtualBranchesHandle};
use crate::{
git::{self, CommitExt},
git::{self, CommitExt, Refname},
project_repository::{self, LogUntil},
};
@ -60,7 +60,7 @@ pub fn list_remote_branches(
let default_target = default_target(&project_repository.project().gb_dir())?;
let mut remote_branches = vec![];
for branch in project_repository
for (branch, _) in project_repository
.git_repository
.branches(None)
.context("failed to list remote branches")?
@ -91,7 +91,15 @@ pub fn get_branch_data(
let branch = project_repository
.git_repository
.find_branch(refname)
.find_branch(
&refname.simple_name(),
match refname {
Refname::Virtual(_) | Refname::Local(_) | Refname::Other(_) => {
git2::BranchType::Local
}
Refname::Remote(_) => git2::BranchType::Remote,
},
)
.context(format!("failed to find branch with refname {refname}"))?;
branch_to_remote_branch_data(project_repository, &branch, default_target.sha)?

View File

@ -237,7 +237,7 @@ pub fn apply_branch(
}
let target_commit = repo
.find_commit(default_target.sha)
.find_commit(default_target.sha.into())
.context("failed to find target commit")?;
let target_tree = target_commit.tree().context("failed to get target tree")?;
@ -245,12 +245,12 @@ pub fn apply_branch(
// if not, we need to merge or rebase the branch to get it up to date
let merge_base = repo
.merge_base(default_target.sha, branch.head)
.merge_base(default_target.sha.into(), branch.head.into())
.context(format!(
"failed to find merge base between {} and {}",
default_target.sha, branch.head
))?;
if merge_base != default_target.sha {
if merge_base != default_target.sha.into() {
// Branch is out of date, merge or rebase it
let merge_base_tree = repo
.find_commit(merge_base)
@ -259,11 +259,11 @@ pub fn apply_branch(
.context("failed to find merge base tree")?;
let branch_tree = repo
.find_tree(branch.tree)
.find_tree(branch.tree.into())
.context("failed to find branch tree")?;
let mut merge_index = repo
.merge_trees(&merge_base_tree, &branch_tree, &target_tree)
.merge_trees(&merge_base_tree, &branch_tree, &target_tree, None)
.context("failed to merge trees")?;
if merge_index.has_conflicts() {
@ -284,7 +284,7 @@ pub fn apply_branch(
vb_state.set_branch(branch.clone())?;
// checkout the conflicts
repo.checkout_index(&mut merge_index)
repo.checkout_index_builder(&mut merge_index)
.allow_conflicts()
.conflict_style_merge()
.force()
@ -314,7 +314,7 @@ pub fn apply_branch(
}
let head_commit = repo
.find_commit(branch.head)
.find_commit(branch.head.into())
.context("failed to find head commit")?;
let merged_branch_tree_oid = merge_index
@ -322,7 +322,7 @@ pub fn apply_branch(
.context("failed to write tree")?;
let merged_branch_tree = repo
.find_tree(merged_branch_tree_oid.into())
.find_tree(merged_branch_tree_oid)
.context("failed to find tree")?;
let ok_with_force_push = project_repository.project().ok_with_force_push;
@ -374,7 +374,7 @@ pub fn apply_branch(
// get tree from merge_tree_oid
let merge_tree = repo
.find_tree(merged_branch_tree_oid.into())
.find_tree(merged_branch_tree_oid)
.context("failed to find tree")?;
// commit the merge tree oid
@ -399,7 +399,7 @@ pub fn apply_branch(
}
branch.tree = repo
.find_commit(branch.head)?
.find_commit(branch.head.into())?
.tree()
.map_err(anyhow::Error::from)?
.id()
@ -410,12 +410,12 @@ pub fn apply_branch(
let wd_tree = project_repository.repo().get_wd_tree()?;
let branch_tree = repo
.find_tree(branch.tree)
.find_tree(branch.tree.into())
.context("failed to find branch tree")?;
// check index for conflicts
let mut merge_index = repo
.merge_trees(&target_tree, &wd_tree, &branch_tree)
.merge_trees(&target_tree, &wd_tree, &branch_tree, None)
.context("failed to merge trees")?;
if merge_index.has_conflicts() {
@ -430,7 +430,7 @@ pub fn apply_branch(
ensure_selected_for_changes(&vb_state).context("failed to ensure selected for changes")?;
// checkout the merge index
repo.checkout_index(&mut merge_index)
repo.checkout_index_builder(&mut merge_index)
.force()
.checkout()
.context("failed to checkout index")?;
@ -506,7 +506,7 @@ pub fn unapply_ownership(
let repo = &project_repository.git_repository;
let target_commit = repo
.find_commit(integration_commit_id)
.find_commit(integration_commit_id.into())
.context("failed to find target commit")?;
let base_tree = target_commit.tree().context("failed to get target tree")?;
@ -515,20 +515,20 @@ pub fn unapply_ownership(
|final_tree, status| {
let final_tree = final_tree?;
let tree_oid = write_tree(project_repository, &integration_commit_id, status.1)?;
let branch_tree = repo.find_tree(tree_oid)?;
let mut result = repo.merge_trees(&base_tree, &final_tree, &branch_tree)?;
let branch_tree = repo.find_tree(tree_oid.into())?;
let mut result = repo.merge_trees(&base_tree, &final_tree, &branch_tree, None)?;
let final_tree_oid = result.write_tree_to(project_repository.repo())?;
repo.find_tree(final_tree_oid.into())
repo.find_tree(final_tree_oid)
.context("failed to find tree")
},
)?;
let final_tree_oid = write_tree_onto_tree(project_repository, &final_tree, diff)?;
let final_tree = repo
.find_tree(final_tree_oid)
.find_tree(final_tree_oid.into())
.context("failed to find tree")?;
repo.checkout_tree(&final_tree)
repo.checkout_tree_builder(&final_tree)
.force()
.remove_untracked()
.checkout()
@ -553,7 +553,7 @@ pub fn reset_files(
for file in files {
let entry = index.get_path(Path::new(file), 0);
if entry.is_some() {
repo.checkout_index_path(Path::new(file))
repo.checkout_index_path_builder(Path::new(file))
.context("failed to checkout index")?;
} else {
// find the project root
@ -583,7 +583,7 @@ pub fn unapply_branch(
let default_target = vb_state.get_default_target()?;
let repo = &project_repository.git_repository;
let target_commit = repo
.find_commit(default_target.sha)
.find_commit(default_target.sha.into())
.context("failed to find target commit")?;
let final_tree = if conflicts::is_resolving(project_repository) {
@ -641,7 +641,7 @@ pub fn unapply_branch(
}
let target_commit = repo
.find_commit(default_target.sha)
.find_commit(default_target.sha.into())
.context("failed to find target commit")?;
// ok, update the wd with the union of the rest of the branches
@ -658,10 +658,11 @@ pub fn unapply_branch(
let final_tree = final_tree?;
let branch = status.0;
let tree_oid = write_tree(project_repository, &branch.head, status.1)?;
let branch_tree = repo.find_tree(tree_oid)?;
let mut result = repo.merge_trees(&base_tree, &final_tree, &branch_tree)?;
let branch_tree = repo.find_tree(tree_oid.into())?;
let mut result =
repo.merge_trees(&base_tree, &final_tree, &branch_tree, None)?;
let final_tree_oid = result.write_tree_to(project_repository.repo())?;
repo.find_tree(final_tree_oid.into())
repo.find_tree(final_tree_oid)
.context("failed to find tree")
},
)?;
@ -672,7 +673,7 @@ pub fn unapply_branch(
};
// checkout final_tree into the working directory
repo.checkout_tree(&final_tree)
repo.checkout_tree_builder(&final_tree)
.force()
.remove_untracked()
.checkout()
@ -684,13 +685,13 @@ pub fn unapply_branch(
}
fn find_base_tree<'a>(
repo: &'a git::Repository,
repo: &'a git2::Repository,
branch_commit: &'a git2::Commit<'a>,
target_commit: &'a git2::Commit<'a>,
) -> Result<git2::Tree<'a>> {
// find merge base between target_commit and branch_commit
let merge_base = repo
.merge_base(target_commit.id().into(), branch_commit.id().into())
.merge_base(target_commit.id(), branch_commit.id())
.context("failed to find merge base")?;
// turn oid into a commit
let merge_base_commit = repo
@ -716,7 +717,7 @@ pub fn list_virtual_branches(
super::integration::get_workspace_head(&vb_state, project_repository)?;
let integration_commit = project_repository
.git_repository
.find_commit(integration_commit_id)
.find_commit(integration_commit_id.into())
.unwrap();
let (statuses, skipped_files) =
@ -734,12 +735,11 @@ pub fn list_virtual_branches(
let upstream_branch = match branch
.upstream
.as_ref()
.map(|name| repo.find_branch(&git::Refname::from(name)))
.map(|name| repo.find_branch_by_refname(&git::Refname::from(name)))
.transpose()
{
Err(git::Error::NotFound(_)) => Ok(None),
Err(error) => Err(error),
Ok(branch) => Ok(branch),
Err(error) => Err(error),
}
.context(format!(
"failed to find upstream branch for {}",
@ -759,13 +759,15 @@ pub fn list_virtual_branches(
let mut pushed_commits = HashMap::new();
if let Some(upstream) = &upstram_branch_commit {
let merge_base = repo
.merge_base(upstream.id().into(), default_target.sha)
.merge_base(upstream.id(), default_target.sha.into())
.context(format!(
"failed to find merge base between {} and {}",
upstream.id(),
default_target.sha
))?;
for oid in project_repository.l(upstream.id().into(), LogUntil::Commit(merge_base))? {
for oid in
project_repository.l(upstream.id().into(), LogUntil::Commit(merge_base.into()))?
{
pushed_commits.insert(oid, true);
}
}
@ -802,11 +804,11 @@ pub fn list_virtual_branches(
.collect::<Result<Vec<_>>>()?;
let merge_base = repo
.merge_base(default_target.sha, branch.head)
.merge_base(default_target.sha.into(), branch.head.into())
.context("failed to find merge base")?;
let mut base_current = true;
if !branch.applied {
base_current = merge_base == default_target.sha;
base_current = merge_base == default_target.sha.into();
}
let upstream = upstream_branch
@ -857,7 +859,7 @@ pub fn list_virtual_branches(
updated_at: branch.updated_timestamp_ms,
selected_for_changes: branch.selected_for_changes == Some(max_selected_for_changes),
head: branch.head,
merge_base,
merge_base: merge_base.into(),
fork_point,
};
branches.push(branch);
@ -904,7 +906,7 @@ fn is_requires_force(
.refname_to_id(&upstream.to_string())
{
Ok(reference) => reference,
Err(git::Error::NotFound(_)) => return Ok(false),
Err(err) if err.code() == git2::ErrorCode::NotFound => return Ok(false),
Err(other) => return Err(other).context("failed to find upstream reference"),
};
@ -915,9 +917,9 @@ fn is_requires_force(
let merge_base = project_repository
.git_repository
.merge_base(upstream_commit.id().into(), branch.head)?;
.merge_base(upstream_commit.id(), branch.head.into())?;
Ok(merge_base != upstream_commit.id().into())
Ok(merge_base != upstream_commit.id())
}
fn list_virtual_commit_files(
@ -990,7 +992,7 @@ pub fn create_virtual_branch(
let commit = project_repository
.git_repository
.find_commit(default_target.sha)
.find_commit(default_target.sha.into())
.context("failed to find default target commit")?;
let tree = commit
@ -1164,7 +1166,7 @@ pub fn integrate_upstream_commits(
return Ok(());
};
let merge_base = repo.merge_base(default_target.sha, upstream_oid)?;
let merge_base = repo.merge_base(default_target.sha.into(), upstream_oid)?;
// Booleans needed for a decision on how integrate upstream commits.
// let is_same_base = default_target.sha == merge_base;
@ -1195,7 +1197,7 @@ pub fn integrate_upstream_commits(
user,
&mut branch,
&upstream_commit,
merge_base,
merge_base.into(),
)
.map(Into::into)
}
@ -1209,18 +1211,18 @@ pub fn integrate_upstream_commits(
};
let new_head = integration_result?;
let new_head_tree = repo.find_commit(new_head)?.tree()?;
let head_commit = repo.find_commit(new_head)?;
let new_head_tree = repo.find_commit(new_head.into())?.tree()?;
let head_commit = repo.find_commit(new_head.into())?;
let wd_tree = project_repository.repo().get_wd_tree()?;
let integration_tree = repo
.find_commit(get_workspace_head(&vb_state, project_repository)?)?
.find_commit(get_workspace_head(&vb_state, project_repository)?.into())?
.tree()?;
let mut merge_index = repo.merge_trees(&integration_tree, &new_head_tree, &wd_tree)?;
let mut merge_index = repo.merge_trees(&integration_tree, &new_head_tree, &wd_tree, None)?;
if merge_index.has_conflicts() {
repo.checkout_index(&mut merge_index)
repo.checkout_index_builder(&mut merge_index)
.allow_conflicts()
.conflict_style_merge()
.force()
@ -1229,7 +1231,9 @@ pub fn integrate_upstream_commits(
branch.head = new_head;
branch.tree = head_commit.tree()?.id().into();
vb_state.set_branch(branch.clone())?;
repo.checkout_index(&mut merge_index).force().checkout()?;
repo.checkout_index_builder(&mut merge_index)
.force()
.checkout()?;
};
super::integration::update_gitbutler_integration(&vb_state, project_repository)?;
@ -1260,10 +1264,10 @@ pub fn integrate_with_merge(
let remote_tree = upstream_commit.tree().context("failed to get tree")?;
let upstream_branch = branch.upstream.as_ref().context("upstream not found")?;
// let merge_tree = repo.find_commit(merge_base).and_then(|c| c.tree())?;
let merge_tree = repo.find_commit(merge_base)?;
let merge_tree = repo.find_commit(merge_base.into())?;
let merge_tree = merge_tree.tree()?;
let mut merge_index = repo.merge_trees(&merge_tree, &wd_tree, &remote_tree)?;
let mut merge_index = repo.merge_trees(&merge_tree, &wd_tree, &remote_tree, None)?;
if merge_index.has_conflicts() {
let conflicts = merge_index.conflicts()?;
@ -1277,7 +1281,7 @@ pub fn integrate_with_merge(
merge_conflicts,
Some(upstream_commit.id().into()),
)?;
repo.checkout_index(&mut merge_index)
repo.checkout_index_builder(&mut merge_index)
.allow_conflicts()
.conflict_style_merge()
.force()
@ -1286,8 +1290,8 @@ pub fn integrate_with_merge(
}
let merge_tree_oid = merge_index.write_tree_to(project_repository.repo())?;
let merge_tree = repo.find_tree(merge_tree_oid.into())?;
let head_commit = repo.find_commit(branch.head)?;
let merge_tree = repo.find_tree(merge_tree_oid)?;
let head_commit = repo.find_commit(branch.head.into())?;
project_repository.commit(
user,
@ -1588,12 +1592,12 @@ fn get_non_applied_status(
}
let branch_tree = project_repository
.git_repository
.find_tree(branch.tree)
.find_tree(branch.tree.into())
.context(format!("failed to find tree {}", branch.tree))?;
let head_tree = project_repository
.git_repository
.find_commit(branch.head)
.find_commit(branch.head.into())
.context("failed to find target commit")?
.tree()
.context("failed to find target tree")?;
@ -1616,10 +1620,10 @@ fn compute_merge_base(
if let Some(last) = project_repository
.l(branch.head, LogUntil::Commit(*target_sha))?
.last()
.map(|id| repo.find_commit(*id))
.map(|id| repo.find_commit(id.to_owned().into()))
{
if let Ok(parent) = last?.parent(0) {
merge_base = repo.merge_base(parent.id().into(), merge_base)?;
merge_base = repo.merge_base(parent.id(), merge_base.into())?.into();
}
}
}
@ -1696,8 +1700,11 @@ fn get_applied_status(
target_sha: &git::Oid,
mut virtual_branches: Vec<branch::Branch>,
) -> Result<(AppliedStatuses, Vec<diff::FileDiff>)> {
let base_file_diffs = diff::workdir(&project_repository.git_repository, integration_commit)
.context("failed to diff workdir")?;
let base_file_diffs = diff::workdir(
&project_repository.git_repository,
&integration_commit.to_owned().into(),
)
.context("failed to diff workdir")?;
let mut skipped_files: Vec<diff::FileDiff> = Vec::new();
for file_diff in base_file_diffs.values() {
@ -1963,11 +1970,11 @@ pub fn reset_branch(
let diff = trees(
repo,
&repo
.find_commit(updated_head)?
.find_commit(updated_head.into())?
.tree()
.map_err(anyhow::Error::from)?,
&repo
.find_commit(old_head)?
.find_commit(old_head.into())?
.tree()
.map_err(anyhow::Error::from)?,
)?;
@ -2025,7 +2032,7 @@ pub fn write_tree_onto_commit(
// read the base sha into an index
let git_repository = &project_repository.git_repository;
let head_commit = git_repository.find_commit(commit_oid)?;
let head_commit = git_repository.find_commit(commit_oid.into())?;
let base_tree = head_commit.tree()?;
write_tree_onto_tree(project_repository, &base_tree, files)
@ -2100,7 +2107,7 @@ pub fn write_tree_onto_tree(
})?
.as_bytes(),
)?;
builder.upsert(rel_path, blob_oid.into(), filemode);
builder.upsert(rel_path, blob_oid, filemode);
} else if let Ok(tree_entry) = base_tree.get_path(rel_path) {
if hunks.len() == 1 && hunks[0].binary {
let new_blob_oid = &hunks[0].diff_lines;
@ -2114,7 +2121,7 @@ pub fn write_tree_onto_tree(
} else {
// blob from tree_entry
let blob = tree_entry
.to_object(git_repository.into())
.to_object(git_repository)
.unwrap()
.peel_to_blob()
.context("failed to get blob")?;
@ -2138,7 +2145,7 @@ pub fn write_tree_onto_tree(
// create a blob
let new_blob_oid = git_repository.blob(&blob_contents)?;
// upsert into the builder
builder.upsert(rel_path, new_blob_oid.into(), filemode);
builder.upsert(rel_path, new_blob_oid, filemode);
}
} else if is_submodule {
let mut blob_contents = BString::default();
@ -2154,13 +2161,13 @@ pub fn write_tree_onto_tree(
// create a blob
let new_blob_oid = git_repository.blob(blob_contents.as_bytes())?;
// upsert into the builder
builder.upsert(rel_path, new_blob_oid.into(), filemode);
builder.upsert(rel_path, new_blob_oid, filemode);
} else {
// create a git blob from a file on disk
let blob_oid = git_repository
.blob_path(&full_path)
.context(format!("failed to create blob from path {:?}", &full_path))?;
builder.upsert(rel_path, blob_oid.into(), filemode);
builder.upsert(rel_path, blob_oid, filemode);
}
} else if base_tree.get_path(rel_path).is_ok() {
// remove file from index if it exists in the base tree
@ -2210,19 +2217,20 @@ pub fn commit(
let vb_state = project_repository.project().virtual_branches();
if run_hooks {
let hook_result = project_repository
.git_repository
.run_hook_commit_msg(&mut message_buffer)
.context("failed to run hook")?;
let hook_result = git2_hooks::hooks_commit_msg(
&project_repository.git_repository,
Some(&["../.husky"]),
&mut message_buffer,
)
.context("failed to run hook")?;
if let HookResult::RunNotSuccessful { stdout, .. } = hook_result {
bail!("commit-msg hook rejected: {}", stdout.trim());
}
let hook_result = project_repository
.git_repository
.run_hook_pre_commit()
.context("failed to run hook")?;
let hook_result =
git2_hooks::hooks_pre_commit(&project_repository.git_repository, Some(&["../.husky"]))
.context("failed to run hook")?;
if let HookResult::RunNotSuccessful { stdout, .. } = hook_result {
bail!("commit hook rejected: {}", stdout.trim());
@ -2275,10 +2283,10 @@ pub fn commit(
let git_repository = &project_repository.git_repository;
let parent_commit = git_repository
.find_commit(branch.head)
.find_commit(branch.head.into())
.context(format!("failed to find commit {:?}", branch.head))?;
let tree = git_repository
.find_tree(tree_oid)
.find_tree(tree_oid.into())
.context(format!("failed to find tree {:?}", tree_oid))?;
// now write a commit, using a merge parent if it exists
@ -2288,7 +2296,7 @@ pub fn commit(
let commit_oid = match extra_merge_parent {
Some(merge_parent) => {
let merge_parent = git_repository
.find_commit(merge_parent)
.find_commit(merge_parent.into())
.context(format!("failed to find merge parent {:?}", merge_parent))?;
let commit_oid = project_repository.commit(
user,
@ -2304,9 +2312,7 @@ pub fn commit(
};
if run_hooks {
project_repository
.git_repository
.run_hook_post_commit()
git2_hooks::hooks_post_commit(&project_repository.git_repository, Some(&["../.husky"]))
.context("failed to run hook")?;
}
@ -2396,7 +2402,7 @@ fn is_commit_integrated(
) -> Result<bool> {
let remote_branch = project_repository
.git_repository
.find_branch(&target.branch.clone().into())?;
.find_branch_by_refname(&target.branch.clone().into())?;
let remote_head = remote_branch.get().peel_to_commit()?;
let upstream_commits = project_repository.l(
remote_head.id().into(),
@ -2419,8 +2425,8 @@ fn is_commit_integrated(
let merge_base_id = project_repository
.git_repository
.merge_base(target.sha, commit.id().into())?;
if merge_base_id.eq(&commit.id().into()) {
.merge_base(target.sha.into(), commit.id())?;
if merge_base_id.eq(&commit.id()) {
// if merge branch is the same as branch head and there are upstream commits
// then it's integrated
return Ok(true);
@ -2432,7 +2438,7 @@ fn is_commit_integrated(
let merge_base_tree = merge_base.tree()?;
let upstream = project_repository
.git_repository
.find_commit(remote_head.id().into())?;
.find_commit(remote_head.id())?;
let upstream_tree = upstream.tree()?;
if merge_base_tree.id() == upstream_tree.id() {
@ -2443,7 +2449,7 @@ fn is_commit_integrated(
// try to merge our tree into the upstream tree
let mut merge_index = project_repository
.git_repository
.merge_trees(&merge_base_tree, &commit.tree()?, &upstream_tree)
.merge_trees(&merge_base_tree, &commit.tree()?, &upstream_tree, None)
.context("failed to merge trees")?;
if merge_index.has_conflicts() {
@ -2468,22 +2474,16 @@ pub fn is_remote_branch_mergeable(
let default_target = vb_state.get_default_target()?;
let target_commit = project_repository
.git_repository
.find_commit(default_target.sha)
.find_commit(default_target.sha.into())
.context("failed to find target commit")?;
let branch = project_repository
.git_repository
.find_branch(&branch_name.into())
.map_err(|err| match err {
git::Error::NotFound(_) => {
anyhow!("Remote branch {} not found", branch_name.clone())
}
err => err.into(),
})?;
.find_branch_by_refname(&branch_name.into())?;
let branch_oid = branch.get().target().context("detatched head")?;
let branch_commit = project_repository
.git_repository
.find_commit(branch_oid.into())
.find_commit(branch_oid)
.context("failed to find branch commit")?;
let base_tree = find_base_tree(
@ -2497,7 +2497,7 @@ pub fn is_remote_branch_mergeable(
let branch_tree = branch_commit.tree().context("failed to find branch tree")?;
let mergeable = !project_repository
.git_repository
.merge_trees(&base_tree, &branch_tree, &wd_tree)
.merge_trees(&base_tree, &branch_tree, &wd_tree, None)
.context("failed to merge trees")?
.has_conflicts();
@ -2518,21 +2518,21 @@ pub fn is_virtual_branch_mergeable(
// determine if this branch is up to date with the target/base
let merge_base = project_repository
.git_repository
.merge_base(default_target.sha, branch.head)
.merge_base(default_target.sha.into(), branch.head.into())
.context("failed to find merge base")?;
if merge_base != default_target.sha {
if merge_base != default_target.sha.into() {
return Ok(false);
}
let branch_commit = project_repository
.git_repository
.find_commit(branch.head)
.find_commit(branch.head.into())
.context("failed to find branch commit")?;
let target_commit = project_repository
.git_repository
.find_commit(default_target.sha)
.find_commit(default_target.sha.into())
.context("failed to find target commit")?;
let base_tree = find_base_tree(
@ -2546,12 +2546,12 @@ pub fn is_virtual_branch_mergeable(
// determine if this tree is mergeable
let branch_tree = project_repository
.git_repository
.find_tree(branch.tree)
.find_tree(branch.tree.into())
.context("failed to find branch tree")?;
let is_mergeable = !project_repository
.git_repository
.merge_trees(&base_tree, &branch_tree, &wd_tree)
.merge_trees(&base_tree, &branch_tree, &wd_tree, None)
.context("failed to merge trees")?
.has_conflicts();
@ -2583,7 +2583,7 @@ pub fn move_commit_file(
let mut to_amend_oid = to_commit_id;
let mut amend_commit = project_repository
.git_repository
.find_commit(to_amend_oid)
.find_commit(to_amend_oid.into())
.context("failed to find commit")?;
// find all the commits upstream from the target "to" commit
@ -2593,8 +2593,11 @@ pub fn move_commit_file(
)?;
// get a list of all the diffs across all the virtual branches
let base_file_diffs = diff::workdir(&project_repository.git_repository, &default_target.sha)
.context("failed to diff workdir")?;
let base_file_diffs = diff::workdir(
&project_repository.git_repository,
&default_target.sha.into(),
)
.context("failed to diff workdir")?;
// filter base_file_diffs to HashMap<filepath, Vec<GitHunk>> only for hunks in target_ownership
// this is essentially the group of patches that we're "moving"
@ -2641,7 +2644,7 @@ pub fn move_commit_file(
// first, let's get the from commit data and it's parent data
let from_commit = project_repository
.git_repository
.find_commit(from_commit_id)
.find_commit(from_commit_id.into())
.context("failed to find commit")?;
let from_tree = from_commit.tree().context("failed to find tree")?;
let from_parent = from_commit.parent(0).context("failed to find parent")?;
@ -2691,7 +2694,7 @@ pub fn move_commit_file(
let new_from_tree_id =
write_tree_onto_commit(project_repository, from_parent.id().into(), &diffs_to_keep)?;
let new_from_tree = &repo
.find_tree(new_from_tree_id)
.find_tree(new_from_tree_id.into())
.with_context(|| "tree {new_from_tree_oid} not found")?;
let change_id = from_commit.change_id();
let new_from_commit_oid = project_repository
@ -2746,7 +2749,7 @@ pub fn move_commit_file(
// reset the "to" commit variable for writing the changes back to
amend_commit = project_repository
.git_repository
.find_commit(to_amend_oid)
.find_commit(to_amend_oid.into())
.context("failed to find commit")?;
// reset the concept of what the upstream commits are to be the rebased ones
@ -2766,7 +2769,7 @@ pub fn move_commit_file(
let new_tree_oid = write_tree_onto_commit(project_repository, to_amend_oid, &diffs_to_amend)?;
let new_tree = project_repository
.git_repository
.find_tree(new_tree_oid)
.find_tree(new_tree_oid.into())
.context("failed to find new tree")?;
let parents: Vec<_> = amend_commit.parents().collect();
let change_id = amend_commit.change_id();
@ -2877,7 +2880,7 @@ pub fn amend(
// find commit oid
let amend_commit = project_repository
.git_repository
.find_commit(commit_oid)
.find_commit(commit_oid.into())
.context("failed to find commit")?;
let diffs_to_amend = target_ownership
@ -2915,7 +2918,7 @@ pub fn amend(
let new_tree_oid = write_tree_onto_commit(project_repository, commit_oid, &diffs_to_amend)?;
let new_tree = project_repository
.git_repository
.find_tree(new_tree_oid)
.find_tree(new_tree_oid.into())
.context("failed to find new tree")?;
let parents: Vec<_> = amend_commit.parents().collect();
@ -2982,7 +2985,7 @@ pub fn reorder_commit(
// find the commit to offset from
let commit = project_repository
.git_repository
.find_commit(commit_oid)
.find_commit(commit_oid.into())
.context("failed to find commit")?;
let parent = commit.parent(0).context("failed to find parent")?;
@ -3074,7 +3077,7 @@ pub fn insert_blank_commit(
// find the commit to offset from
let mut commit = project_repository
.git_repository
.find_commit(commit_oid)
.find_commit(commit_oid.into())
.context("failed to find commit")?;
if offset > 0 {
@ -3126,7 +3129,7 @@ pub fn undo_commit(
let mut branch = vb_state.get_branch(branch_id)?;
let commit = project_repository
.git_repository
.find_commit(commit_oid)
.find_commit(commit_oid.into())
.context("failed to find commit")?;
let new_commit_oid;
@ -3204,7 +3207,11 @@ fn cherry_rebase_group(
// now, rebase unchanged commits onto the new commit
let commits_to_rebase = ids_to_rebase
.iter()
.map(|oid| project_repository.git_repository.find_commit(*oid))
.map(|oid| {
project_repository
.git_repository
.find_commit(oid.to_owned().into())
})
.collect::<Result<Vec<_>, _>>()
.context("failed to read commits to rebase")?;
@ -3213,14 +3220,14 @@ fn cherry_rebase_group(
.fold(
project_repository
.git_repository
.find_commit(target_commit_oid)
.find_commit(target_commit_oid.into())
.context("failed to find new commit"),
|head, to_rebase| {
let head = head?;
let mut cherrypick_index = project_repository
.git_repository
.cherry_pick(&head, &to_rebase)
.cherrypick_commit(&to_rebase, &head, 0, None)
.context("failed to cherry pick")?;
if cherrypick_index.has_conflicts() {
@ -3233,7 +3240,7 @@ fn cherry_rebase_group(
let merge_tree = project_repository
.git_repository
.find_tree(merge_tree_oid.into())
.find_tree(merge_tree_oid)
.context("failed to find merge tree")?;
let change_id = to_rebase.change_id();
@ -3253,7 +3260,7 @@ fn cherry_rebase_group(
project_repository
.git_repository
.find_commit(commit_oid.into())
.find_commit(commit_oid)
.context("failed to find commit")
},
)?
@ -3282,15 +3289,17 @@ pub fn cherry_pick(
let target_commit = project_repository
.git_repository
.find_commit(target_commit_id.into())
.map_err(|error| match error {
git::Error::NotFound(_) => anyhow!("commit {target_commit_id} not found "),
.find_commit(target_commit_id)
.map_err(|err| match err {
err if err.code() == git2::ErrorCode::NotFound => {
anyhow!("commit {target_commit_id} not found ")
}
err => err.into(),
})?;
let branch_head_commit = project_repository
.git_repository
.find_commit(branch.head)
.find_commit(branch.head.into())
.context("failed to find branch tree")?;
let default_target = vb_state.get_default_target()?;
@ -3323,7 +3332,7 @@ pub fn cherry_pick(
let wip_tree_oid = write_tree(project_repository, &branch.head, branch_files)?;
let wip_tree = project_repository
.git_repository
.find_tree(wip_tree_oid)
.find_tree(wip_tree_oid.into())
.context("failed to find tree")?;
let signature = git2::Signature::now("GitButler", "gitbutler@gitbutler.com")
@ -3342,13 +3351,13 @@ pub fn cherry_pick(
.context("failed to commit wip work")?;
project_repository
.git_repository
.find_commit(oid.into())
.find_commit(oid)
.context("failed to find wip commit")?
};
let mut cherrypick_index = project_repository
.git_repository
.cherry_pick(&wip_commit, &target_commit)
.cherrypick_commit(&target_commit, &wip_commit, 0, None)
.context("failed to cherry pick")?;
// unapply other branches
@ -3364,7 +3373,7 @@ pub fn cherry_pick(
// checkout the conflicts
project_repository
.git_repository
.checkout_index(&mut cherrypick_index)
.checkout_index_builder(&mut cherrypick_index)
.allow_conflicts()
.conflict_style_merge()
.force()
@ -3393,12 +3402,12 @@ pub fn cherry_pick(
.context("failed to write merge tree")?;
let merge_tree = project_repository
.git_repository
.find_tree(merge_tree_oid.into())
.find_tree(merge_tree_oid)
.context("failed to find merge tree")?;
let branch_head_commit = project_repository
.git_repository
.find_commit(branch.head)
.find_commit(branch.head.into())
.context("failed to find branch head commit")?;
let change_id = target_commit.change_id();
@ -3418,7 +3427,7 @@ pub fn cherry_pick(
// checkout final_tree into the working directory
project_repository
.git_repository
.checkout_tree(&merge_tree)
.checkout_tree_builder(&merge_tree)
.force()
.remove_untracked()
.checkout()
@ -3460,7 +3469,7 @@ pub fn squash(
let commit_to_squash = project_repository
.git_repository
.find_commit(commit_id)
.find_commit(commit_id.into())
.context("failed to find commit")?;
let parent_commit = commit_to_squash
@ -3584,7 +3593,7 @@ pub fn update_commit_message(
let target_commit = project_repository
.git_repository
.find_commit(commit_id)
.find_commit(commit_id.into())
.context("failed to find commit")?;
let parents: Vec<_> = target_commit.parents().collect();
@ -3671,7 +3680,7 @@ pub fn move_commit(
let source_branch_head = project_repository
.git_repository
.find_commit(commit_id)
.find_commit(commit_id.into())
.context("failed to find commit")?;
let source_branch_head_parent = source_branch_head
.parent(0)
@ -3746,7 +3755,7 @@ pub fn move_commit(
.context("failed to write tree onto commit")?;
let new_destination_tree = project_repository
.git_repository
.find_tree(new_destination_tree_oid)
.find_tree(new_destination_tree_oid.into())
.context("failed to find tree")?;
let change_id = source_branch_head.change_id();
@ -3757,7 +3766,7 @@ pub fn move_commit(
&new_destination_tree,
&[&project_repository
.git_repository
.find_commit(destination_branch.head)
.find_commit(destination_branch.head.into())
.context("failed to get dst branch head commit")?],
change_id.as_deref(),
)
@ -3808,10 +3817,14 @@ pub fn create_virtual_branch_from_branch(
}
let repo = &project_repository.git_repository;
let head_reference = repo.find_reference(upstream).map_err(|err| match err {
git::Error::NotFound(_) => anyhow!("branch {upstream} was not found"),
err => err.into(),
})?;
let head_reference = repo
.find_reference(&upstream.to_string())
.map_err(|err| match err {
err if err.code() == git2::ErrorCode::NotFound => {
anyhow!("branch {upstream} was not found")
}
err => err.into(),
})?;
let head_commit = head_reference
.peel_to_commit()
.context("failed to peel to commit")?;
@ -3833,8 +3846,8 @@ pub fn create_virtual_branch_from_branch(
let now = crate::time::now_ms();
// add file ownership based off the diff
let target_commit = repo.find_commit(default_target.sha)?;
let merge_base_oid = repo.merge_base(target_commit.id().into(), head_commit.id().into())?;
let target_commit = repo.find_commit(default_target.sha.into())?;
let merge_base_oid = repo.merge_base(target_commit.id(), head_commit.id())?;
let merge_base_tree = repo.find_commit(merge_base_oid)?.tree()?;
// do a diff between the head of this branch and the target base

View File

@ -29,11 +29,7 @@ impl TestCase<'_> {
let helper = Helper::new(keys);
let (repo, _tmp) = test_repository();
repo.remote(
"origin",
&self.remote_url.parse().expect("failed to parse remote url"),
)
.unwrap();
repo.remote("origin", self.remote_url).unwrap();
let project = projects::Project {
path: repo.workdir().unwrap().to_path_buf(),
preferred_key: self.preferred_key.clone(),

View File

@ -168,7 +168,9 @@ fn track_binary_files() -> Result<()> {
// status (no files)
let (branches, _) = virtual_branches::list_virtual_branches(project_repository).unwrap();
let commit_id = &branches[0].commits[0].id;
let commit_obj = project_repository.git_repository.find_commit(*commit_id)?;
let commit_obj = project_repository
.git_repository
.find_commit(commit_id.to_owned().into())?;
let tree = commit_obj.tree()?;
let files = tree_to_entry_list(&project_repository.git_repository, &tree);
assert_eq!(files[0].0, "image.bin");
@ -199,7 +201,9 @@ fn track_binary_files() -> Result<()> {
let (branches, _) = virtual_branches::list_virtual_branches(project_repository).unwrap();
let commit_id = &branches[0].commits[0].id;
// get tree from commit_id
let commit_obj = project_repository.git_repository.find_commit(*commit_id)?;
let commit_obj = project_repository
.git_repository
.find_commit(commit_id.to_owned().into())?;
let tree = commit_obj.tree()?;
let files = tree_to_entry_list(&project_repository.git_repository, &tree);
@ -691,7 +695,7 @@ fn commit_id_can_be_generated_or_specified() -> Result<()> {
.unwrap();
let target = project_repository
.git_repository
.find_commit(target_oid.into())
.find_commit(target_oid)
.unwrap();
let change_id = target.change_id();
@ -722,9 +726,7 @@ fn commit_id_can_be_generated_or_specified() -> Result<()> {
&signature,
&signature,
"some commit",
&repository
.find_tree(oid.into())
.expect("failed to find tree"),
&repository.find_tree(oid).expect("failed to find tree"),
&[&repository
.find_commit(
repository
@ -744,7 +746,7 @@ fn commit_id_can_be_generated_or_specified() -> Result<()> {
.unwrap();
let target = project_repository
.git_repository
.find_commit(target_oid.into())
.find_commit(target_oid)
.unwrap();
let change_id = target.change_id();
@ -805,8 +807,8 @@ fn merge_vbranch_upstream_clean_rebase() -> Result<()> {
//update repo ref refs/remotes/origin/master to up_target oid
project_repository.git_repository.reference(
&"refs/remotes/origin/master".parse().unwrap(),
coworker_work.into(),
"refs/remotes/origin/master",
coworker_work,
true,
"update target",
)?;
@ -929,8 +931,8 @@ async fn merge_vbranch_upstream_conflict() -> Result<()> {
//update repo ref refs/remotes/origin/master to up_target oid
project_repository.git_repository.reference(
&"refs/remotes/origin/master".parse().unwrap(),
coworker_work.into(),
"refs/remotes/origin/master",
coworker_work,
true,
"update target",
)?;
@ -1014,7 +1016,9 @@ async fn merge_vbranch_upstream_conflict() -> Result<()> {
// make sure the last commit was a merge commit (2 parents)
let last_id = &branch1.commits[0].id;
let last_commit = project_repository.git_repository.find_commit(*last_id)?;
let last_commit = project_repository
.git_repository
.find_commit(last_id.to_owned().into())?;
assert_eq!(last_commit.parent_count(), 2);
Ok(())
@ -1268,7 +1272,7 @@ fn detect_mergeable_branch() -> Result<()> {
project_repository
.git_repository
.set_head(&"refs/heads/master".parse().unwrap())?;
.set_head("refs/heads/master")?;
project_repository
.git_repository
.checkout_head(Some(&mut git2::build::CheckoutBuilder::default().force()))?;
@ -1286,8 +1290,8 @@ fn detect_mergeable_branch() -> Result<()> {
.target()
.unwrap();
project_repository.git_repository.reference(
&"refs/remotes/origin/remote_branch".parse().unwrap(),
up_target.into(),
"refs/remotes/origin/remote_branch",
up_target,
true,
"update target",
)?;
@ -1307,8 +1311,8 @@ fn detect_mergeable_branch() -> Result<()> {
.target()
.unwrap();
project_repository.git_repository.reference(
&"refs/remotes/origin/remote_branch2".parse().unwrap(),
up_target.into(),
"refs/remotes/origin/remote_branch2",
up_target,
true,
"update target",
)?;
@ -1317,7 +1321,7 @@ fn detect_mergeable_branch() -> Result<()> {
project_repository
.git_repository
.set_head(&"refs/heads/gitbutler/integration".parse().unwrap())?;
.set_head("refs/heads/gitbutler/integration")?;
project_repository
.git_repository
.checkout_head(Some(&mut git2::build::CheckoutBuilder::default().force()))?;
@ -1425,8 +1429,8 @@ fn upstream_integrated_vbranch() -> Result<()> {
.target()
.unwrap();
project_repository.git_repository.reference(
&"refs/remotes/origin/master".parse().unwrap(),
upstream_commit.into(),
"refs/remotes/origin/master",
upstream_commit,
true,
"update target",
)?;
@ -1439,7 +1443,7 @@ fn upstream_integrated_vbranch() -> Result<()> {
})?;
project_repository
.git_repository
.remote("origin", &"http://origin.com/project".parse().unwrap())?;
.remote("origin", "http://origin.com/project")?;
virtual_branches::integration::update_gitbutler_integration(&vb_state, project_repository)?;
// create vbranches, one integrated, one not
@ -1808,7 +1812,7 @@ fn commit_partial_by_file() -> Result<()> {
.unwrap();
let commit1 = project_repository
.git_repository
.find_commit(commit1_oid.into())
.find_commit(commit1_oid)
.unwrap();
set_test_target(project_repository)?;
@ -1840,7 +1844,7 @@ fn commit_partial_by_file() -> Result<()> {
let commit2 = &branch1.commits[0].id;
let commit2 = project_repository
.git_repository
.find_commit(*commit2)
.find_commit(commit2.to_owned().into())
.expect("failed to get commit object");
let tree = commit1.tree().expect("failed to get tree");
@ -1875,7 +1879,7 @@ fn commit_add_and_delete_files() -> Result<()> {
.unwrap();
let commit1 = project_repository
.git_repository
.find_commit(commit1_oid.into())
.find_commit(commit1_oid)
.unwrap();
set_test_target(project_repository)?;
@ -1907,7 +1911,7 @@ fn commit_add_and_delete_files() -> Result<()> {
let commit2 = &branch1.commits[0].id;
let commit2 = project_repository
.git_repository
.find_commit(*commit2)
.find_commit(commit2.to_owned().into())
.expect("failed to get commit object");
let tree = commit1.tree().expect("failed to get tree");
@ -1971,7 +1975,7 @@ fn commit_executable_and_symlinks() -> Result<()> {
let commit = &branch1.commits[0].id;
let commit = project_repository
.git_repository
.find_commit(*commit)
.find_commit(commit.to_owned().into())
.expect("failed to get commit object");
let tree = commit.tree().expect("failed to get tree");
@ -1990,12 +1994,12 @@ fn commit_executable_and_symlinks() -> Result<()> {
Ok(())
}
fn tree_to_file_list(repository: &git::Repository, tree: &git2::Tree) -> Vec<String> {
fn tree_to_file_list(repository: &git2::Repository, tree: &git2::Tree) -> Vec<String> {
let mut file_list = Vec::new();
walk(tree, |_, entry| {
let path = entry.name().unwrap();
let entry = tree.get_path(Path::new(path)).unwrap();
let object = entry.to_object(repository.into()).unwrap();
let object = entry.to_object(repository).unwrap();
if object.kind() == Some(git2::ObjectType::Blob) {
file_list.push(path.to_string());
}
@ -2006,14 +2010,14 @@ fn tree_to_file_list(repository: &git::Repository, tree: &git2::Tree) -> Vec<Str
}
fn tree_to_entry_list(
repository: &git::Repository,
repository: &git2::Repository,
tree: &git2::Tree,
) -> Vec<(String, String, String, String)> {
let mut file_list = Vec::new();
walk(tree, |_root, entry| {
let path = entry.name().unwrap();
let entry = tree.get_path(Path::new(path)).unwrap();
let object = entry.to_object(repository.into()).unwrap();
let object = entry.to_object(repository).unwrap();
let blob = object.as_blob().expect("failed to get blob");
// convert content to string
let octal_mode = format!("{:o}", entry.filemode());
@ -2087,7 +2091,7 @@ fn verify_branch_not_integration() -> Result<()> {
project_repository
.git_repository
.set_head(&"refs/heads/master".parse().unwrap())?;
.set_head("refs/heads/master")?;
let verify_result = verify_branch(project_repository);
assert!(verify_result.is_err());
@ -2128,7 +2132,7 @@ fn pre_commit_hook_rejection() -> Result<()> {
";
git2_hooks::create_hook(
(&project_repository.git_repository).into(),
&project_repository.git_repository,
git2_hooks::HOOK_PRE_COMMIT,
hook,
);
@ -2176,7 +2180,7 @@ fn post_commit_hook() -> Result<()> {
";
git2_hooks::create_hook(
(&project_repository.git_repository).into(),
&project_repository.git_repository,
git2_hooks::HOOK_POST_COMMIT,
hook,
);
@ -2233,7 +2237,7 @@ fn commit_msg_hook_rejection() -> Result<()> {
";
git2_hooks::create_hook(
(&project_repository.git_repository).into(),
&project_repository.git_repository,
git2_hooks::HOOK_COMMIT_MSG,
hook,
);

View File

@ -29,10 +29,7 @@ pub mod virtual_branches {
let (remote_repo, _tmp) = empty_bare_repository();
let mut remote = project_repository
.git_repository
.remote(
"origin",
&remote_repo.path().to_str().unwrap().parse().unwrap(),
)
.remote("origin", remote_repo.path().to_str().unwrap())
.expect("failed to add remote");
remote.push(&["refs/heads/master:refs/heads/master"], None)?;

View File

@ -150,34 +150,31 @@ pub fn temp_dir() -> TempDir {
tempdir().unwrap()
}
pub fn empty_bare_repository() -> (gitbutler_core::git::Repository, TempDir) {
pub fn empty_bare_repository() -> (git2::Repository, TempDir) {
let tmp = temp_dir();
(
gitbutler_core::git::Repository::init_opts(&tmp, &init_opts_bare())
.expect("failed to init repository"),
git2::Repository::init_opts(&tmp, &init_opts_bare()).expect("failed to init repository"),
tmp,
)
}
pub fn test_repository() -> (gitbutler_core::git::Repository, TempDir) {
pub fn test_repository() -> (git2::Repository, TempDir) {
let tmp = temp_dir();
let repository = gitbutler_core::git::Repository::init_opts(&tmp, &init_opts())
.expect("failed to init repository");
let repository =
git2::Repository::init_opts(&tmp, &init_opts()).expect("failed to init repository");
project_repository::Config::from(&repository)
.set_local("commit.gpgsign", "false")
.unwrap();
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();
let repo: &git2::Repository = (&repository).into();
let repo: &git2::Repository = &repository;
repo.commit_with_signature(
Some(&"refs/heads/master".parse().unwrap()),
&signature,
&signature,
"Initial commit",
&repository
.find_tree(oid.into())
.expect("failed to find tree"),
&repository.find_tree(oid).expect("failed to find tree"),
&[],
None,
)
@ -185,7 +182,7 @@ pub fn test_repository() -> (gitbutler_core::git::Repository, TempDir) {
(repository, tmp)
}
pub fn commit_all(repository: &gitbutler_core::git::Repository) -> gitbutler_core::git::Oid {
pub fn commit_all(repository: &git2::Repository) -> gitbutler_core::git::Oid {
let mut index = repository.index().expect("failed to get index");
index
.add_all(["."], git2::IndexAddOption::DEFAULT, None)
@ -194,16 +191,14 @@ pub fn commit_all(repository: &gitbutler_core::git::Repository) -> gitbutler_cor
let oid = index.write_tree().expect("failed to write tree");
let signature = git2::Signature::now("test", "test@email.com").unwrap();
let head = repository.head().expect("failed to get head");
let repo: &git2::Repository = repository.into();
let repo: &git2::Repository = repository;
let commit_oid = repo
.commit_with_signature(
Some(&head.name().map(|name| name.parse().unwrap()).unwrap()),
&signature,
&signature,
"some commit",
&repository
.find_tree(oid.into())
.expect("failed to find tree"),
&repository.find_tree(oid).expect("failed to find tree"),
&[&repository
.find_commit(
repository

View File

@ -11,9 +11,9 @@ pub fn temp_dir() -> TempDir {
}
pub struct TestProject {
local_repository: git::Repository,
local_repository: git2::Repository,
local_tmp: Option<TempDir>,
remote_repository: git::Repository,
remote_repository: git2::Repository,
remote_tmp: Option<TempDir>,
}
@ -29,20 +29,20 @@ impl Drop for TestProject {
impl Default for TestProject {
fn default() -> Self {
let local_tmp = temp_dir();
let local_repository = git::Repository::init_opts(local_tmp.path(), &init_opts())
let local_repository = git2::Repository::init_opts(local_tmp.path(), &init_opts())
.expect("failed to init repository");
setup_config(&local_repository.config().unwrap()).unwrap();
let mut index = local_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();
let repo: &git2::Repository = (&local_repository).into();
let repo: &git2::Repository = &local_repository;
repo.commit_with_signature(
Some(&"refs/heads/master".parse().unwrap()),
&signature,
&signature,
"Initial commit",
&local_repository
.find_tree(oid.into())
.find_tree(oid)
.expect("failed to find tree"),
&[],
None,
@ -50,7 +50,7 @@ impl Default for TestProject {
.expect("failed to commit");
let remote_tmp = temp_dir();
let remote_repository = git::Repository::init_opts(
let remote_repository = git2::Repository::init_opts(
remote_tmp.path(),
git2::RepositoryInitOptions::new()
.bare(true)
@ -63,12 +63,10 @@ impl Default for TestProject {
let mut remote = local_repository
.remote(
"origin",
&remote_repository
remote_repository
.path()
.to_str()
.expect("failed to convert path to str")
.parse()
.unwrap(),
.expect("failed to convert path to str"),
)
.expect("failed to add remote");
remote
@ -120,16 +118,14 @@ impl TestProject {
let head = self.local_repository.head().unwrap();
let commit = oid.map_or(head.peel_to_commit().unwrap(), |oid| {
self.local_repository.find_commit(oid).unwrap()
self.local_repository.find_commit(oid.into()).unwrap()
});
let head_ref = head.name().unwrap();
self.local_repository
.find_reference(&head_ref.parse().expect("libgit2 provides valid refnames"))
.unwrap();
self.local_repository.find_reference(head_ref).unwrap();
self.local_repository
.reset(&commit, git2::ResetType::Hard, None)
.reset(commit.as_object(), git2::ResetType::Hard, None)
.unwrap();
}
@ -149,12 +145,17 @@ impl TestProject {
}
_ => "INVALID".parse().unwrap(), // todo
};
let branch = self.remote_repository.find_branch(&branch_name).unwrap();
let branch = self
.remote_repository
.find_branch_by_refname(&branch_name)
.unwrap();
let branch_commit = branch.get().peel_to_commit().unwrap();
let master_branch = {
let name: git::Refname = "refs/heads/master".parse().unwrap();
self.remote_repository.find_branch(&name).unwrap()
self.remote_repository
.find_branch_by_refname(&name)
.unwrap()
};
let master_branch_commit = master_branch.get().peel_to_commit().unwrap();
@ -165,8 +166,18 @@ impl TestProject {
let mut rebase = self
.remote_repository
.rebase(
Some(branch_commit.id().into()),
Some(master_branch_commit.id().into()),
Some(
&self
.remote_repository
.find_annotated_commit(branch_commit.id())
.unwrap(),
),
Some(
&self
.remote_repository
.find_annotated_commit(master_branch_commit.id())
.unwrap(),
),
None,
Some(&mut rebase_options),
)
@ -175,7 +186,7 @@ impl TestProject {
let mut rebase_success = true;
let mut last_rebase_head = branch_commit.id();
while let Some(Ok(op)) = rebase.next() {
let commit = self.remote_repository.find_commit(op.id().into()).unwrap();
let commit = self.remote_repository.find_commit(op.id()).unwrap();
let index = rebase.inmemory_index().unwrap();
if index.has_conflicts() {
rebase_success = false;
@ -193,8 +204,8 @@ impl TestProject {
if rebase_success {
self.remote_repository
.reference(
&"refs/heads/master".parse().unwrap(),
last_rebase_head.into(),
"refs/heads/master",
last_rebase_head,
true,
&format!("rebase: {}", branch_name),
)
@ -213,19 +224,24 @@ impl TestProject {
}
_ => "INVALID".parse().unwrap(), // todo
};
let branch = self.remote_repository.find_branch(&branch_name).unwrap();
let branch = self
.remote_repository
.find_branch_by_refname(&branch_name)
.unwrap();
let branch_commit = branch.get().peel_to_commit().unwrap();
let master_branch = {
let name: git::Refname = "refs/heads/master".parse().unwrap();
self.remote_repository.find_branch(&name).unwrap()
self.remote_repository
.find_branch_by_refname(&name)
.unwrap()
};
let master_branch_commit = master_branch.get().peel_to_commit().unwrap();
let merge_base = {
let oid = self
.remote_repository
.merge_base(branch_commit.id().into(), master_branch_commit.id().into())
.merge_base(branch_commit.id(), master_branch_commit.id())
.unwrap();
self.remote_repository.find_commit(oid).unwrap()
};
@ -236,14 +252,15 @@ impl TestProject {
&merge_base.tree().unwrap(),
&master_branch.get().peel_to_tree().unwrap(),
&branch.get().peel_to_tree().unwrap(),
None,
)
.unwrap();
let repo: &git2::Repository = (&self.remote_repository).into();
let repo: &git2::Repository = &self.remote_repository;
let oid = merge_index.write_tree_to(repo).unwrap();
self.remote_repository.find_tree(oid.into()).unwrap()
self.remote_repository.find_tree(oid).unwrap()
};
let repo: &git2::Repository = (&self.remote_repository).into();
let repo: &git2::Repository = &self.remote_repository;
repo.commit_with_signature(
Some(&"refs/heads/master".parse().unwrap()),
&branch_commit.author(),
@ -256,17 +273,22 @@ impl TestProject {
.unwrap();
}
pub fn find_commit(&self, oid: git::Oid) -> Result<git2::Commit<'_>, git::Error> {
self.local_repository.find_commit(oid)
pub fn find_commit(&self, oid: git::Oid) -> Result<git2::Commit<'_>, git2::Error> {
self.local_repository.find_commit(oid.into())
}
pub fn checkout_commit(&self, commit_oid: git::Oid) {
let commit = self.local_repository.find_commit(commit_oid).unwrap();
let commit = self
.local_repository
.find_commit(commit_oid.into())
.unwrap();
let commit_tree = commit.tree().unwrap();
self.local_repository.set_head_detached(commit_oid).unwrap();
self.local_repository
.checkout_tree(&commit_tree)
.set_head_detached(commit_oid.into())
.unwrap();
self.local_repository
.checkout_tree_builder(&commit_tree)
.force()
.checkout()
.unwrap();
@ -280,19 +302,19 @@ impl TestProject {
.unwrap()
.peel_to_commit()
.unwrap();
let tree = match self.local_repository.find_branch(&branch) {
let tree = match self.local_repository.find_branch_by_refname(&branch) {
Ok(branch) => branch.get().peel_to_tree().unwrap(),
Err(git::Error::NotFound(_)) => {
Err(err) if err.code() == git2::ErrorCode::NotFound => {
self.local_repository
.reference(&branch, head_commit.id().into(), false, "new branch")
.reference(&branch.to_string(), head_commit.id(), false, "new branch")
.unwrap();
head_commit.tree().unwrap()
}
Err(error) => panic!("{:?}", error),
};
self.local_repository.set_head(&branch).unwrap();
self.local_repository.set_head(&branch.to_string()).unwrap();
self.local_repository
.checkout_tree(&tree)
.checkout_tree_builder(&tree)
.force()
.checkout()
.unwrap();
@ -309,7 +331,7 @@ impl TestProject {
let oid = index.write_tree().expect("failed to write tree");
let signature = git2::Signature::now("test", "test@email.com").unwrap();
let refname: git::Refname = head.name().unwrap().parse().unwrap();
let repo: &git2::Repository = (&self.local_repository).into();
let repo: &git2::Repository = &self.local_repository;
repo.commit_with_signature(
Some(&refname),
&signature,
@ -317,7 +339,7 @@ impl TestProject {
message,
&self
.local_repository
.find_tree(oid.into())
.find_tree(oid)
.expect("failed to find tree"),
&[&self
.local_repository
@ -342,7 +364,10 @@ impl TestProject {
}
pub fn add_submodule(&self, url: &git::Url, path: &path::Path) {
let mut submodule = self.local_repository.add_submodule(url, path).unwrap();
let mut submodule = self
.local_repository
.submodule(&url.to_string(), path.as_ref(), false)
.unwrap();
let repo = submodule.open().unwrap();
// checkout submodule's master head

View File

@ -178,12 +178,14 @@ impl Handler {
.context("failed to get head")?;
let head_ref_name = head_ref.name().context("failed to get head name")?;
if head_ref_name != "refs/heads/gitbutler/integration" {
let mut integration_reference = project_repository
.git_repository
.find_reference(&git::Refname::from(git::LocalRefname::new(
"gitbutler/integration",
None,
)))?;
let mut integration_reference =
project_repository.git_repository.find_reference(
&git::Refname::from(git::LocalRefname::new(
"gitbutler/integration",
None,
))
.to_string(),
)?;
integration_reference.delete()?;
}
if let Some(head) = head_ref.name() {