Skip to content

Commit

Permalink
Support git commit signing using OpenPGP
Browse files Browse the repository at this point in the history
  • Loading branch information
hendrikmaus committed Feb 20, 2023
1 parent 10bf4e3 commit 6aefadd
Show file tree
Hide file tree
Showing 5 changed files with 385 additions and 15 deletions.
8 changes: 8 additions & 0 deletions asyncgit/src/error.rs
Expand Up @@ -84,6 +84,14 @@ pub enum Error {
///
#[error("not on a branch")]
NoBranch,

///
#[error("sign builder error: {0}")]
SignBuilder(#[from] crate::sync::sign::SignBuilderError),

///
#[error("sign error: {0}")]
Sign(#[from] crate::sync::sign::SignError),
}

///
Expand Down
39 changes: 35 additions & 4 deletions asyncgit/src/sync/commit.rs
@@ -1,4 +1,5 @@
use super::{CommitId, RepoPath};
use crate::sync::sign::{SignBuilder, SignError};
use crate::{
error::Result,
sync::{repository::repo, utils::get_head_repo},
Expand Down Expand Up @@ -65,7 +66,7 @@ pub fn commit(repo_path: &RepoPath, msg: &str) -> Result<CommitId> {
scope_time!("commit");

let repo = repo(repo_path)?;

let config = repo.config()?;
let signature = signature_allow_undefined_name(&repo)?;
let mut index = repo.index()?;
let tree_id = index.write_tree()?;
Expand All @@ -79,16 +80,46 @@ pub fn commit(repo_path: &RepoPath, msg: &str) -> Result<CommitId> {

let parents = parents.iter().collect::<Vec<_>>();

Ok(repo
.commit(
let commit_id = if config
.get_bool("commit.gpgsign")
.unwrap_or(false)
{
use crate::sync::sign::Sign;

let buffer = repo.commit_create_buffer(
&signature,
&signature,
msg,
&tree,
parents.as_slice(),
)?;

let commit = std::str::from_utf8(&buffer).map_err(|_e| {
SignError::Shellout("utf8 conversion error".to_string())
})?;

let sign = SignBuilder::from_gitconfig(&repo, &config)?;
let signed_commit = sign.sign(commit)?;
let commit_id =
repo.commit_signed(commit, &signed_commit, None)?;

// manually advance to the new commit ID
// repo.commit does that on its own, repo.commit_signed does not
repo.head()?.set_target(commit_id, msg)?;

commit_id
} else {
repo.commit(
Some("HEAD"),
&signature,
&signature,
msg,
&tree,
parents.as_slice(),
)?
.into())
};

Ok(commit_id.into())
}

/// Tag a commit.
Expand Down
1 change: 1 addition & 0 deletions asyncgit/src/sync/mod.rs
Expand Up @@ -24,6 +24,7 @@ pub mod remotes;
mod repository;
mod reset;
mod reword;
pub mod sign;
mod staging;
mod stash;
mod state;
Expand Down

0 comments on commit 6aefadd

Please sign in to comment.