gitbutler
gitbutler copied to clipboard
rebased commits are not re-signed
When a branch is updated and commits are rebased and SSH signing is on, we do not properly re-sign the commits. We should be checking for the signing option and re-signing commits that are rebased.
I'm able to reproduce the issue. I'll like to work on it. Hope to have a fix ready by Monday.
I'll create a more detailed PR soon. But I was able to figure out a fix.
The problem is rebase.commit
does not have support for signing the commits. This is because libgit2 itself does not have support for this. Ref: https://libgit2.org/libgit2/#v0.23.2/group/rebase
I was able to make it work by figuring out a workaround by using the commit
function ( which in turn uses the commit_signed function to create signed commits. )
https://github.com/gitbutlerapp/gitbutler/blob/229b9b9bc9661c8cbcc4aca8ea5a0f0774456876/gitbutler-app/src/project_repository/repository.rs#L329). In this approach, instead of calling rebase.commit
we call the commit
function in such a way that it mimics the way rebase.commit
would have worked.
Here's a sample piece of code which achieves it ( it's still WIP. I wanted to share it earlier to get feedback )
if let Some(_) = signing_key {
let commit_id = rebase_op.id();
let commit = project_repository.find_commit(commit_id.into()).unwrap();
let message = commit.message().unwrap();
let tree = commit.tree().unwrap();
let head = project_repository.get_head().unwrap();
let head_commit = head.peel_to_commit().unwrap();
if let Ok(commit_id) = project_repository.commit(user, message, &tree, &[&head_commit], signing_key) {
last_rebase_head = commit_id.into();
} else {
rebase_success = false;
break;
}
} else {
if let Ok(commit_id) = rebase.commit(None, &committer.clone().into(), None) {
last_rebase_head = commit_id.into();
} else {
rebase_success = false;
break;
}
}
Thoughts @schacon
There's also a parameter in the rebase options of libgit2 – git_commit_create_cb
( https://github.com/libgit2/libgit2/blob/2fe50e295d12fcfcb75bfe5fe08a4582d0aff527/include/git2/rebase.h#L87 )
which runs a commit creation callback which will allow us to sign commits.
The official documentation of the function also lists this as a possible use case for git_commit_create_cb
.
Unfortunately, git2 at the moment does not support this option ( https://docs.rs/git2/latest/git2/struct.RebaseOptions.html ).
There is already an open issue about this https://github.com/rust-lang/git2-rs/issues/850 and I was thinking of contributing a fix upstream as well so that we'll be able to use it in our codebase.