From c543b2f25b6893e5dce6111bc12d9812099251ba Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Mon, 22 Jan 2024 00:00:00 +0000 Subject: feat(git): apply pgp sig event tag to commit to maintain correct commit ids which is required to apply multiple commits its noted that no tests are written and the scenario where the author and committer differ has not been tested clearly the validate_patch_applied function has code that corrects an error where the author / committer 'signatures' do not apply correctly. this will not be fixed under a pgp signed commit scenario. --- src/git.rs | 53 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/git.rs b/src/git.rs index 7292508..41520c6 100644 --- a/src/git.rs +++ b/src/git.rs @@ -465,14 +465,51 @@ fn apply_patch(git_repo: &Repo, patch: &nostr::Event) -> Result<()> { index.add_all(["."], git2::IndexAddOption::DEFAULT, None)?; index.write()?; - git_repo.git_repo.commit( - Some("HEAD"), - &extract_sig_from_patch_tags(&patch.tags, "author")?, - &extract_sig_from_patch_tags(&patch.tags, "committer")?, - tag_value(patch, "description")?.as_str(), - &git_repo.git_repo.find_tree(index.write_tree()?)?, - &[&prev_oid], - )?; + let pgp_sig = if let Ok(pgp_sig) = tag_value(patch, "commit-sig") { + if pgp_sig.is_empty() { + None + } else { + Some(pgp_sig) + } + } else { + None + }; + + if let Some(pgp_sig) = pgp_sig { + let commit_buff = git_repo.git_repo.commit_create_buffer( + &extract_sig_from_patch_tags(&patch.tags, "author")?, + &extract_sig_from_patch_tags(&patch.tags, "committer")?, + tag_value(patch, "description")?.as_str(), + &git_repo.git_repo.find_tree(index.write_tree()?)?, + &[&prev_oid], + )?; + let gpg_commit_id = git_repo.git_repo.commit_signed( + commit_buff.as_str().unwrap(), + pgp_sig.as_str(), + None, + )?; + git_repo.git_repo.reset( + &git_repo.git_repo.find_object(gpg_commit_id, None)?, + git2::ResetType::Mixed, + None, + )?; + if gpg_commit_id.to_string().eq(&tag_value(patch, "commit")?) { + return Ok(()); + } + } else { + git_repo.git_repo.commit( + Some("HEAD"), + &extract_sig_from_patch_tags(&patch.tags, "author")?, + &extract_sig_from_patch_tags(&patch.tags, "committer")?, + tag_value(patch, "description")?.as_str(), + &git_repo.git_repo.find_tree(index.write_tree()?)?, + &[&prev_oid], + )?; + } + validate_patch_applied(git_repo, patch) +} + +fn validate_patch_applied(git_repo: &Repo, patch: &nostr::Event) -> Result<()> { // end of stage and commit // check commit applied if git_repo -- cgit v1.2.3