Skip to content

Commit

Permalink
Extract commit_with_signature, sign_buffer, and signatures
Browse files Browse the repository at this point in the history
  • Loading branch information
Caleb-T-Owens committed Dec 17, 2024
1 parent 178ec76 commit c5aee79
Show file tree
Hide file tree
Showing 18 changed files with 333 additions and 304 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use gitbutler_oxidize::gix_to_git2_oid;
use gitbutler_oxidize::{git2_to_gix_object_id, GixRepositoryExt};
use gitbutler_project::access::WorktreeWritePermission;
use gitbutler_reference::{normalize_branch_name, ReferenceName, Refname};
use gitbutler_repo::committing::RepositoryExt as _;
use gitbutler_repo::RepositoryExt;
use gitbutler_repo::SignaturePurpose;
use gitbutler_repo_actions::RepoActionsExt;
Expand Down
2 changes: 1 addition & 1 deletion crates/gitbutler-branch-actions/src/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ use gitbutler_error::error::Marker;
use gitbutler_operating_modes::OPEN_WORKSPACE_REFS;
use gitbutler_oxidize::{git2_to_gix_object_id, gix_to_git2_oid, GixRepositoryExt};
use gitbutler_project::access::WorktreeWritePermission;
use gitbutler_repo::committing::RepositoryExt as _;
use gitbutler_repo::logging::{LogUntil, RepositoryExt as _};
use gitbutler_repo::RepositoryExt;
use gitbutler_repo::SignaturePurpose;
use gitbutler_stack::{Stack, VirtualBranchesHandle};
use tracing::instrument;
Expand Down
1 change: 1 addition & 0 deletions crates/gitbutler-branch-actions/src/virtual.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use gitbutler_oxidize::{
use gitbutler_project::access::WorktreeWritePermission;
use gitbutler_reference::{normalize_branch_name, Refname, RemoteRefname};
use gitbutler_repo::{
committing::RepositoryExt as _,
logging::{LogUntil, RepositoryExt as _},
rebase::{cherry_rebase, cherry_rebase_group},
RepositoryExt,
Expand Down
2 changes: 1 addition & 1 deletion crates/gitbutler-branch-actions/tests/extra/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use gitbutler_branch_actions::{
};
use gitbutler_commit::{commit_ext::CommitExt, commit_headers::CommitHeadersV2};
use gitbutler_reference::{Refname, RemoteRefname};
use gitbutler_repo::RepositoryExt;
use gitbutler_repo::committing::RepositoryExt as _;
use gitbutler_stack::{BranchOwnershipClaims, Target, VirtualBranchesHandle};
use gitbutler_testsupport::{commit_all, virtual_branches::set_test_target, Case, Suite};
use pretty_assertions::assert_eq;
Expand Down
2 changes: 2 additions & 0 deletions crates/gitbutler-edit-mode/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ use gitbutler_operating_modes::{
use gitbutler_oxidize::{git2_to_gix_object_id, gix_to_git2_index, GixRepositoryExt};
use gitbutler_project::access::{WorktreeReadPermission, WorktreeWritePermission};
use gitbutler_reference::{ReferenceName, Refname};
use gitbutler_repo::committing::RepositoryExt as _;
use gitbutler_repo::identity::RepositoryExt as _;
use gitbutler_repo::{rebase::cherry_rebase, RepositoryExt};
use gitbutler_repo::{signature, SignaturePurpose};
use gitbutler_stack::{Stack, VirtualBranchesHandle};
Expand Down
2 changes: 2 additions & 0 deletions crates/gitbutler-repo-actions/src/repository.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ use gitbutler_stack::{Stack, StackId};

use crate::askpass;
use gitbutler_repo::{
committing::RepositoryExt as _,
credentials,
identity::RepositoryExt as _,
logging::{LogUntil, RepositoryExt as _},
RepositoryExt,
};
Expand Down
4 changes: 2 additions & 2 deletions crates/gitbutler-repo/src/commands.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{remote::GitRemote, Config, RepositoryExt};
use crate::{remote::GitRemote, sigining::sign_buffer, Config, RepositoryExt};
use anyhow::{bail, Result};
use base64::engine::Engine as _;
use git2::Oid;
Expand Down Expand Up @@ -138,7 +138,7 @@ impl RepoCommands for Project {

fn check_signing_settings(&self) -> Result<bool> {
let ctx = CommandContext::open(self)?;
let signed = ctx.repo().sign_buffer(b"test");
let signed = sign_buffer(ctx.repo(), b"test");
match signed {
Ok(_) => Ok(true),
Err(e) => Err(e),
Expand Down
80 changes: 80 additions & 0 deletions crates/gitbutler-repo/src/committing.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
use anyhow::{anyhow, Result};
use gitbutler_commit::commit_headers::CommitHeadersV2;
use gitbutler_config::git::{GbConfig, GitConfig as _};
use gitbutler_error::error::Code;
use gitbutler_oxidize::{git2_signature_to_gix_signature, git2_to_gix_object_id, gix_to_git2_oid};
use gitbutler_reference::Refname;
use gix::objs::WriteTo as _;

use crate::sigining::sign_buffer;

pub trait RepositoryExt {
#[allow(clippy::too_many_arguments)]
fn commit_with_signature(
&self,
update_ref: Option<&Refname>,
author: &git2::Signature<'_>,
committer: &git2::Signature<'_>,
message: &str,
tree: &git2::Tree<'_>,
parents: &[&git2::Commit<'_>],
commit_headers: Option<CommitHeadersV2>,
) -> Result<git2::Oid>;
}

impl RepositoryExt for git2::Repository {
#[allow(clippy::too_many_arguments)]
fn commit_with_signature(
&self,
update_ref: Option<&Refname>,
author: &git2::Signature<'_>,
committer: &git2::Signature<'_>,
message: &str,
tree: &git2::Tree<'_>,
parents: &[&git2::Commit<'_>],
commit_headers: Option<CommitHeadersV2>,
) -> Result<git2::Oid> {
let repo = gix::open(self.path())?;
let mut commit = gix::objs::Commit {
message: message.into(),
tree: git2_to_gix_object_id(tree.id()),
author: git2_signature_to_gix_signature(author),
committer: git2_signature_to_gix_signature(committer),
encoding: None,
parents: parents
.iter()
.map(|commit| git2_to_gix_object_id(commit.id()))
.collect(),
extra_headers: commit_headers.unwrap_or_default().into(),
};

if self.gb_config()?.sign_commits.unwrap_or(false) {
let mut buf = Vec::new();
commit.write_to(&mut buf)?;
let signature = sign_buffer(self, &buf);
match signature {
Ok(signature) => {
commit.extra_headers.push(("gpgsig".into(), signature));
}
Err(e) => {
// If signing fails, set the "gitbutler.signCommits" config to false before erroring out
self.set_gb_config(GbConfig {
sign_commits: Some(false),
..GbConfig::default()
})?;
return Err(
anyhow!("Failed to sign commit: {}", e).context(Code::CommitSigningFailed)
);
}
}
}
// TODO: extra-headers should be supported in `gix` directly.
let oid = gix_to_git2_oid(repo.write_object(&commit)?);

// update reference
if let Some(refname) = update_ref {
self.reference(&refname.to_string(), oid, true, message)?;
}
Ok(oid)
}
}
35 changes: 35 additions & 0 deletions crates/gitbutler-repo/src/identity.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use anyhow::{Context as _, Result};
use gitbutler_error::error::Code;
use gitbutler_oxidize::gix_to_git2_signature;

use crate::{Config, SignaturePurpose};

pub trait RepositoryExt {
fn signatures(&self) -> Result<(git2::Signature, git2::Signature)>;
}

impl RepositoryExt for git2::Repository {
fn signatures(&self) -> Result<(git2::Signature, git2::Signature)> {
let repo = gix::open(self.path())?;

let author = repo
.author()
.transpose()?
.map(gix_to_git2_signature)
.transpose()?
.context("No author is configured in Git")
.context(Code::AuthorMissing)?;

let config: Config = self.into();
let committer = if config.user_real_comitter()? {
repo.committer()
.transpose()?
.map(gix_to_git2_signature)
.unwrap_or_else(|| crate::signature(SignaturePurpose::Committer))
} else {
crate::signature(SignaturePurpose::Committer)
}?;

Ok((author, committer))
}
}
3 changes: 3 additions & 0 deletions crates/gitbutler-repo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ pub use config::Config;

pub mod temporary_workdir;

pub mod committing;
pub mod identity;
pub mod logging;
mod sigining;

use gitbutler_oxidize::gix_to_git2_signature;
pub const GITBUTLER_COMMIT_AUTHOR_NAME: &str = "GitButler";
Expand Down
83 changes: 42 additions & 41 deletions crates/gitbutler-repo/src/rebase.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use std::{collections::HashSet, path::PathBuf};

use crate::{
committing::RepositoryExt as _,
identity::RepositoryExt as _,
logging::{LogUntil, RepositoryExt as _},
RepositoryExt as _,
};
use anyhow::{Context, Result};
use bstr::ByteSlice;
Expand Down Expand Up @@ -130,17 +131,17 @@ fn commit_unconflicted_cherry_result<'repository>(

let (_, committer) = repository.signatures()?;

let commit_oid = crate::RepositoryExt::commit_with_signature(
repository,
None,
&to_rebase.author(),
&committer,
&to_rebase.message_bstr().to_str_lossy(),
&merge_tree,
&[&head],
commit_headers,
)
.context("failed to create commit")?;
let commit_oid = repository
.commit_with_signature(
None,
&to_rebase.author(),
&committer,
&to_rebase.message_bstr().to_str_lossy(),
&merge_tree,
&[&head],
commit_headers,
)
.context("failed to create commit")?;

repository
.find_commit(commit_oid)
Expand Down Expand Up @@ -211,19 +212,19 @@ fn commit_conflicted_cherry_result<'repository>(

let (_, committer) = repository.signatures()?;

let commit_oid = crate::RepositoryExt::commit_with_signature(
repository,
None,
&to_rebase.author(),
&committer,
&to_rebase.message_bstr().to_str_lossy(),
&repository
.find_tree(tree_oid)
.context("failed to find tree")?,
&[&head],
commit_headers,
)
.context("failed to create commit")?;
let commit_oid = repository
.commit_with_signature(
None,
&to_rebase.author(),
&committer,
&to_rebase.message_bstr().to_str_lossy(),
&repository
.find_tree(tree_oid)
.context("failed to find tree")?,
&[&head],
commit_headers,
)
.context("failed to create commit")?;

repository
.find_commit(commit_oid)
Expand Down Expand Up @@ -371,22 +372,22 @@ pub fn gitbutler_merge_commits<'repository>(
};

let (author, committer) = repository.signatures()?;
let commit_oid = crate::RepositoryExt::commit_with_signature(
repository,
None,
&author,
&committer,
&format!(
"Merge `{}` into `{}`",
incoming_branch_name, target_branch_name
),
&repository
.find_tree(tree_oid)
.context("failed to find tree")?,
&[&target_commit, &incoming_commit],
Some(commit_headers),
)
.context("failed to create commit")?;
let commit_oid = repository
.commit_with_signature(
None,
&author,
&committer,
&format!(
"Merge `{}` into `{}`",
incoming_branch_name, target_branch_name
),
&repository
.find_tree(tree_oid)
.context("failed to find tree")?,
&[&target_commit, &incoming_commit],
Some(commit_headers),
)
.context("failed to create commit")?;

Ok(repository.find_commit(commit_oid)?)
}
Expand Down
Loading

0 comments on commit c5aee79

Please sign in to comment.