mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2025-01-01 22:12:04 +03:00
sign commits with real git
in the strangest possible way
This commit is contained in:
parent
ff11fcdb90
commit
51f9769024
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -2190,6 +2190,7 @@ dependencies = [
|
||||
"sysinfo",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"uuid",
|
||||
"winapi 0.3.9",
|
||||
"windows-named-pipe",
|
||||
]
|
||||
|
@ -274,6 +274,29 @@ impl Repository {
|
||||
.write(git2::ObjectType::Commit, commit_buffer.as_bytes())?;
|
||||
|
||||
// check git config for gpg.signingkey
|
||||
let signing_key = self.0.config()?.get_string("commit.gpgSign");
|
||||
dbg!(&signing_key);
|
||||
if let Ok(_should_sign) = signing_key {
|
||||
dbg!("SIGN IT");
|
||||
/*
|
||||
SOMETHING SOMETHING DARK SIDE...
|
||||
let path = self.path().to_path_buf();
|
||||
let res = std::thread::spawn(move || {
|
||||
tokio::runtime::Runtime::new()
|
||||
.unwrap()
|
||||
.block_on(gitbutler_git::sign_commit(
|
||||
path,
|
||||
gitbutler_git::tokio::TokioExecutor,
|
||||
oid.to_string(),
|
||||
handle_git_prompt_sign,
|
||||
extra,
|
||||
))
|
||||
})
|
||||
.join()
|
||||
.unwrap()
|
||||
.map_err(|e| Err(anyhow::anyhow!("fuck you")));
|
||||
*/
|
||||
}
|
||||
|
||||
// update reference
|
||||
if let Some(refname) = update_ref {
|
||||
|
@ -13,7 +13,6 @@ use crate::{
|
||||
askpass::AskpassBroker,
|
||||
error,
|
||||
git::{self, credentials::HelpError, Url},
|
||||
keys,
|
||||
projects::{self, AuthKey},
|
||||
ssh, users,
|
||||
virtual_branches::{Branch, BranchId},
|
||||
@ -344,20 +343,12 @@ impl Repository {
|
||||
message: &str,
|
||||
tree: &git::Tree,
|
||||
parents: &[&git::Commit],
|
||||
signing_key: Option<&keys::PrivateKey>,
|
||||
change_id: Option<&str>,
|
||||
) -> Result<git::Oid> {
|
||||
let (author, committer) = self.git_signatures(user)?;
|
||||
|
||||
if let Some(key) = signing_key {
|
||||
self.git_repository
|
||||
.commit_signed(&author, message, tree, parents, key, change_id)
|
||||
.context("failed to commit signed")
|
||||
} else {
|
||||
self.git_repository
|
||||
.commit(None, &author, &committer, message, tree, parents, change_id)
|
||||
.context("failed to commit")
|
||||
}
|
||||
self.git_repository
|
||||
.commit(None, &author, &committer, message, tree, parents, change_id)
|
||||
.context("failed to commit")
|
||||
}
|
||||
|
||||
pub fn push_to_gitbutler_server(
|
||||
|
@ -12,7 +12,6 @@ use super::{
|
||||
};
|
||||
use crate::{
|
||||
git::{self, diff},
|
||||
keys,
|
||||
project_repository::{self, LogUntil},
|
||||
projects::FetchResult,
|
||||
users,
|
||||
@ -342,7 +341,6 @@ fn _print_tree(repo: &git2::Repository, tree: &git2::Tree) -> Result<()> {
|
||||
pub fn update_base_branch(
|
||||
project_repository: &project_repository::Repository,
|
||||
user: Option<&users::User>,
|
||||
signing_key: Option<&keys::PrivateKey>,
|
||||
) -> Result<(), errors::UpdateBaseBranchError> {
|
||||
if project_repository.is_resolving() {
|
||||
return Err(errors::UpdateBaseBranchError::Conflict(
|
||||
@ -513,7 +511,6 @@ pub fn update_base_branch(
|
||||
.as_str(),
|
||||
&branch_head_merge_tree,
|
||||
&[&branch_head_commit, &new_target_commit],
|
||||
signing_key,
|
||||
None,
|
||||
)
|
||||
.context("failed to commit merge")?;
|
||||
|
@ -17,7 +17,7 @@ use super::{
|
||||
};
|
||||
use crate::{
|
||||
askpass::AskpassBroker,
|
||||
git, keys, project_repository,
|
||||
git, project_repository,
|
||||
projects::{self, ProjectId},
|
||||
users,
|
||||
};
|
||||
@ -26,7 +26,6 @@ use crate::{
|
||||
pub struct Controller {
|
||||
projects: projects::Controller,
|
||||
users: users::Controller,
|
||||
keys: keys::Controller,
|
||||
helper: git::credentials::Helper,
|
||||
|
||||
by_project_id: Arc<tokio::sync::Mutex<HashMap<ProjectId, ControllerInner>>>,
|
||||
@ -36,7 +35,6 @@ impl Controller {
|
||||
pub fn new(
|
||||
projects: projects::Controller,
|
||||
users: users::Controller,
|
||||
keys: keys::Controller,
|
||||
helper: git::credentials::Helper,
|
||||
) -> Self {
|
||||
Self {
|
||||
@ -44,7 +42,6 @@ impl Controller {
|
||||
|
||||
projects,
|
||||
users,
|
||||
keys,
|
||||
helper,
|
||||
}
|
||||
}
|
||||
@ -54,9 +51,7 @@ impl Controller {
|
||||
.lock()
|
||||
.await
|
||||
.entry(*project_id)
|
||||
.or_insert_with(|| {
|
||||
ControllerInner::new(&self.projects, &self.users, &self.keys, &self.helper)
|
||||
})
|
||||
.or_insert_with(|| ControllerInner::new(&self.projects, &self.users, &self.helper))
|
||||
.clone()
|
||||
}
|
||||
|
||||
@ -430,7 +425,6 @@ struct ControllerInner {
|
||||
|
||||
projects: projects::Controller,
|
||||
users: users::Controller,
|
||||
keys: keys::Controller,
|
||||
helper: git::credentials::Helper,
|
||||
}
|
||||
|
||||
@ -438,14 +432,12 @@ impl ControllerInner {
|
||||
pub fn new(
|
||||
projects: &projects::Controller,
|
||||
users: &users::Controller,
|
||||
keys: &keys::Controller,
|
||||
helper: &git::credentials::Helper,
|
||||
) -> Self {
|
||||
Self {
|
||||
semaphore: Arc::new(Semaphore::new(1)),
|
||||
projects: projects.clone(),
|
||||
users: users.clone(),
|
||||
keys: keys.clone(),
|
||||
helper: helper.clone(),
|
||||
}
|
||||
}
|
||||
@ -461,23 +453,11 @@ impl ControllerInner {
|
||||
let _permit = self.semaphore.acquire().await;
|
||||
|
||||
self.with_verify_branch(project_id, |project_repository, user| {
|
||||
let signing_key = project_repository
|
||||
.config()
|
||||
.sign_commits()
|
||||
.context("failed to get sign commits option")?
|
||||
.then(|| {
|
||||
self.keys
|
||||
.get_or_create()
|
||||
.context("failed to get private key")
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
let result = super::commit(
|
||||
project_repository,
|
||||
branch_id,
|
||||
message,
|
||||
ownership,
|
||||
signing_key.as_ref(),
|
||||
user,
|
||||
run_hooks,
|
||||
)
|
||||
@ -548,22 +528,8 @@ impl ControllerInner {
|
||||
let _permit = self.semaphore.acquire().await;
|
||||
|
||||
self.with_verify_branch(project_id, |project_repository, user| {
|
||||
let signing_key = project_repository
|
||||
.config()
|
||||
.sign_commits()
|
||||
.context("failed to get sign commits option")?
|
||||
.then(|| {
|
||||
self.keys
|
||||
.get_or_create()
|
||||
.context("failed to get private key")
|
||||
})
|
||||
.transpose()?;
|
||||
let result = super::create_virtual_branch_from_branch(
|
||||
project_repository,
|
||||
branch,
|
||||
signing_key.as_ref(),
|
||||
user,
|
||||
)?;
|
||||
let result =
|
||||
super::create_virtual_branch_from_branch(project_repository, branch, user)?;
|
||||
let _ = project_repository
|
||||
.project()
|
||||
.create_snapshot(SnapshotDetails::new(OperationType::CreateBranch));
|
||||
@ -624,24 +590,8 @@ impl ControllerInner {
|
||||
let _permit = self.semaphore.acquire().await;
|
||||
|
||||
self.with_verify_branch(project_id, |project_repository, user| {
|
||||
let signing_key = project_repository
|
||||
.config()
|
||||
.sign_commits()
|
||||
.context("failed to get sign commits option")?
|
||||
.then(|| {
|
||||
self.keys
|
||||
.get_or_create()
|
||||
.context("failed to get private key")
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
let result = super::merge_virtual_branch_upstream(
|
||||
project_repository,
|
||||
branch_id,
|
||||
signing_key.as_ref(),
|
||||
user,
|
||||
)
|
||||
.map_err(Into::into);
|
||||
let result = super::merge_virtual_branch_upstream(project_repository, branch_id, user)
|
||||
.map_err(Into::into);
|
||||
let _ = project_repository
|
||||
.project()
|
||||
.create_snapshot(SnapshotDetails::new(OperationType::MergeUpstream));
|
||||
@ -653,19 +603,7 @@ impl ControllerInner {
|
||||
let _permit = self.semaphore.acquire().await;
|
||||
|
||||
self.with_verify_branch(project_id, |project_repository, user| {
|
||||
let signing_key = project_repository
|
||||
.config()
|
||||
.sign_commits()
|
||||
.context("failed to get sign commits option")?
|
||||
.then(|| {
|
||||
self.keys
|
||||
.get_or_create()
|
||||
.context("failed to get private key")
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
let result = super::update_base_branch(project_repository, user, signing_key.as_ref())
|
||||
.map_err(Into::into);
|
||||
let result = super::update_base_branch(project_repository, user).map_err(Into::into);
|
||||
let _ = project_repository
|
||||
.project()
|
||||
.create_snapshot(SnapshotDetails::new(OperationType::UpdateWorkspaceBase));
|
||||
@ -726,20 +664,8 @@ impl ControllerInner {
|
||||
let _permit = self.semaphore.acquire().await;
|
||||
|
||||
self.with_verify_branch(project_id, |project_repository, user| {
|
||||
let signing_key = project_repository
|
||||
.config()
|
||||
.sign_commits()
|
||||
.context("failed to get sign commits option")?
|
||||
.then(|| {
|
||||
self.keys
|
||||
.get_or_create()
|
||||
.context("failed to get private key")
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
let result =
|
||||
super::apply_branch(project_repository, branch_id, signing_key.as_ref(), user)
|
||||
.map_err(Into::into);
|
||||
super::apply_branch(project_repository, branch_id, user).map_err(Into::into);
|
||||
let _ = project_repository
|
||||
.project()
|
||||
.create_snapshot(SnapshotDetails::new(OperationType::ApplyBranch));
|
||||
@ -1083,24 +1009,8 @@ impl ControllerInner {
|
||||
let _permit = self.semaphore.acquire().await;
|
||||
|
||||
self.with_verify_branch(project_id, |project_repository, user| {
|
||||
let signing_key = project_repository
|
||||
.config()
|
||||
.sign_commits()
|
||||
.context("failed to get sign commits option")?
|
||||
.then(|| {
|
||||
self.keys
|
||||
.get_or_create()
|
||||
.context("failed to get private key")
|
||||
})
|
||||
.transpose()?;
|
||||
let result = super::move_commit(
|
||||
project_repository,
|
||||
target_branch_id,
|
||||
commit_oid,
|
||||
user,
|
||||
signing_key.as_ref(),
|
||||
)
|
||||
.map_err(Into::into);
|
||||
let result = super::move_commit(project_repository, target_branch_id, commit_oid, user)
|
||||
.map_err(Into::into);
|
||||
let _ = project_repository
|
||||
.project()
|
||||
.create_snapshot(SnapshotDetails::new(OperationType::MoveCommit));
|
||||
|
@ -34,7 +34,6 @@ use crate::{
|
||||
diff::{self},
|
||||
Commit, Refname, RemoteRefname,
|
||||
},
|
||||
keys,
|
||||
project_repository::{self, conflicts, LogUntil},
|
||||
reader, users,
|
||||
};
|
||||
@ -101,6 +100,7 @@ pub struct VirtualBranchCommit {
|
||||
pub branch_id: BranchId,
|
||||
pub change_id: Option<String>,
|
||||
pub is_signed: bool,
|
||||
pub stack_points: Option<Vec<HashMap<String, String>>>,
|
||||
}
|
||||
|
||||
// this struct is a mapping to the view `File` type in Typescript
|
||||
@ -215,7 +215,6 @@ pub fn normalize_branch_name(name: &str) -> String {
|
||||
pub fn apply_branch(
|
||||
project_repository: &project_repository::Repository,
|
||||
branch_id: &BranchId,
|
||||
signing_key: Option<&keys::PrivateKey>,
|
||||
user: Option<&users::User>,
|
||||
) -> Result<(), errors::ApplyBranchError> {
|
||||
if project_repository.is_resolving() {
|
||||
@ -359,7 +358,6 @@ pub fn apply_branch(
|
||||
.as_str(),
|
||||
&merged_branch_tree,
|
||||
&[&head_commit, &target_commit],
|
||||
signing_key,
|
||||
None,
|
||||
)?;
|
||||
|
||||
@ -429,7 +427,6 @@ pub fn apply_branch(
|
||||
.as_str(),
|
||||
&merge_tree,
|
||||
&[&head_commit, &target_commit],
|
||||
signing_key,
|
||||
None,
|
||||
)
|
||||
.context("failed to commit merge")?;
|
||||
@ -1053,6 +1050,7 @@ fn commit_to_vbranch_commit(
|
||||
branch_id: branch.id,
|
||||
change_id: commit.change_id(),
|
||||
is_signed: commit.is_signed(),
|
||||
stack_points: Some(stack_points),
|
||||
};
|
||||
|
||||
Ok(commit)
|
||||
@ -1171,7 +1169,6 @@ pub fn create_virtual_branch(
|
||||
pub fn merge_virtual_branch_upstream(
|
||||
project_repository: &project_repository::Repository,
|
||||
branch_id: &BranchId,
|
||||
signing_key: Option<&keys::PrivateKey>,
|
||||
user: Option<&users::User>,
|
||||
) -> Result<(), errors::MergeVirtualBranchUpstreamError> {
|
||||
if conflicts::is_conflicting::<&Path>(project_repository, None)? {
|
||||
@ -1364,7 +1361,6 @@ pub fn merge_virtual_branch_upstream(
|
||||
.as_str(),
|
||||
&merge_tree,
|
||||
&[&head_commit, &upstream_commit],
|
||||
signing_key,
|
||||
None,
|
||||
)?;
|
||||
|
||||
@ -2312,7 +2308,6 @@ pub fn commit(
|
||||
branch_id: &BranchId,
|
||||
message: &str,
|
||||
ownership: Option<&branch::BranchOwnershipClaims>,
|
||||
signing_key: Option<&keys::PrivateKey>,
|
||||
user: Option<&users::User>,
|
||||
run_hooks: bool,
|
||||
) -> Result<git::Oid, errors::CommitError> {
|
||||
@ -2415,15 +2410,12 @@ pub fn commit(
|
||||
message,
|
||||
&tree,
|
||||
&[&parent_commit, &merge_parent],
|
||||
signing_key,
|
||||
None,
|
||||
)?;
|
||||
conflicts::clear(project_repository).context("failed to clear conflicts")?;
|
||||
commit_oid
|
||||
}
|
||||
None => {
|
||||
project_repository.commit(user, message, &tree, &[&parent_commit], signing_key, None)?
|
||||
}
|
||||
None => project_repository.commit(user, message, &tree, &[&parent_commit], None)?,
|
||||
};
|
||||
|
||||
if run_hooks {
|
||||
@ -3340,8 +3332,7 @@ pub fn insert_blank_commit(
|
||||
}
|
||||
|
||||
let commit_tree = commit.tree().unwrap();
|
||||
let blank_commit_oid =
|
||||
project_repository.commit(user, "", &commit_tree, &[&commit], None, None)?;
|
||||
let blank_commit_oid = project_repository.commit(user, "", &commit_tree, &[&commit], None)?;
|
||||
|
||||
if commit.id() == branch.head && offset < 0 {
|
||||
// inserting before the first commit
|
||||
@ -3983,7 +3974,6 @@ pub fn move_commit(
|
||||
target_branch_id: &BranchId,
|
||||
commit_oid: git::Oid,
|
||||
user: Option<&users::User>,
|
||||
signing_key: Option<&keys::PrivateKey>,
|
||||
) -> Result<(), errors::MoveCommitError> {
|
||||
if project_repository.is_resolving() {
|
||||
return Err(errors::MoveCommitError::Conflicted(
|
||||
@ -4140,7 +4130,6 @@ pub fn move_commit(
|
||||
.git_repository
|
||||
.find_commit(destination_branch.head)
|
||||
.context("failed to get dst branch head commit")?],
|
||||
signing_key,
|
||||
change_id.as_deref(),
|
||||
)
|
||||
.context("failed to commit")?;
|
||||
@ -4158,7 +4147,6 @@ pub fn move_commit(
|
||||
pub fn create_virtual_branch_from_branch(
|
||||
project_repository: &project_repository::Repository,
|
||||
upstream: &git::Refname,
|
||||
signing_key: Option<&keys::PrivateKey>,
|
||||
user: Option<&users::User>,
|
||||
) -> Result<BranchId, errors::CreateVirtualBranchFromBranchError> {
|
||||
if !matches!(upstream, git::Refname::Local(_) | git::Refname::Remote(_)) {
|
||||
@ -4297,7 +4285,7 @@ pub fn create_virtual_branch_from_branch(
|
||||
|
||||
project_repository.add_branch_reference(&branch)?;
|
||||
|
||||
match apply_branch(project_repository, &branch.id, signing_key, user) {
|
||||
match apply_branch(project_repository, &branch.id, user) {
|
||||
Ok(()) => Ok(branch.id),
|
||||
Err(errors::ApplyBranchError::BranchConflicts(_)) => {
|
||||
// if branch conflicts with the workspace, it's ok. keep it unapplied
|
||||
|
@ -3,14 +3,13 @@ use super::*;
|
||||
#[tokio::test]
|
||||
async fn twice() {
|
||||
let data_dir = paths::data_dir();
|
||||
let keys = keys::Controller::from_path(data_dir.path());
|
||||
let projects = projects::Controller::from_path(data_dir.path());
|
||||
let users = users::Controller::from_path(data_dir.path());
|
||||
let helper = git::credentials::Helper::from_path(data_dir.path());
|
||||
|
||||
let test_project = TestProject::default();
|
||||
|
||||
let controller = Controller::new(projects.clone(), users, keys, helper);
|
||||
let controller = Controller::new(projects.clone(), users, helper);
|
||||
|
||||
{
|
||||
let project = projects
|
||||
|
@ -1,7 +1,7 @@
|
||||
use std::{fs, path, str::FromStr};
|
||||
|
||||
use gitbutler_core::{
|
||||
git, keys,
|
||||
git,
|
||||
projects::{self, ProjectId},
|
||||
users,
|
||||
virtual_branches::{branch, errors, Controller},
|
||||
@ -29,7 +29,6 @@ impl Drop for Test {
|
||||
impl Default for Test {
|
||||
fn default() -> Self {
|
||||
let data_dir = paths::data_dir();
|
||||
let keys = keys::Controller::from_path(data_dir.path());
|
||||
let projects = projects::Controller::from_path(data_dir.path());
|
||||
let users = users::Controller::from_path(data_dir.path());
|
||||
let helper = git::credentials::Helper::from_path(data_dir.path());
|
||||
@ -42,7 +41,7 @@ impl Default for Test {
|
||||
Self {
|
||||
repository: test_project,
|
||||
project_id: project.id,
|
||||
controller: Controller::new(projects.clone(), users, keys, helper),
|
||||
controller: Controller::new(projects.clone(), users, helper),
|
||||
projects,
|
||||
data_dir: Some(data_dir),
|
||||
}
|
||||
|
@ -64,7 +64,6 @@ fn commit_on_branch_then_change_file_then_get_status() -> Result<()> {
|
||||
"test commit",
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
)?;
|
||||
|
||||
@ -123,7 +122,6 @@ fn signed_commit() -> Result<()> {
|
||||
&branch1_id,
|
||||
"test commit",
|
||||
None,
|
||||
Some(suite.keys.get_or_create()?).as_ref(),
|
||||
None,
|
||||
false,
|
||||
)?;
|
||||
@ -212,7 +210,6 @@ fn track_binary_files() -> Result<()> {
|
||||
"test commit",
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
)?;
|
||||
|
||||
@ -244,7 +241,6 @@ fn track_binary_files() -> Result<()> {
|
||||
"test commit",
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
)?;
|
||||
|
||||
@ -811,12 +807,7 @@ fn merge_vbranch_upstream_clean_rebase() -> Result<()> {
|
||||
assert_eq!(branch1.commits.len(), 1);
|
||||
// assert_eq!(branch1.upstream.as_ref().unwrap().commits.len(), 1);
|
||||
|
||||
merge_virtual_branch_upstream(
|
||||
project_repository,
|
||||
&branch1.id,
|
||||
Some(suite.keys.get_or_create()?).as_ref(),
|
||||
None,
|
||||
)?;
|
||||
merge_virtual_branch_upstream(project_repository, &branch1.id, None)?;
|
||||
|
||||
let (branches, _) = virtual_branches::list_virtual_branches(project_repository)?;
|
||||
let branch1 = &branches[0];
|
||||
@ -931,7 +922,7 @@ fn merge_vbranch_upstream_conflict() -> Result<()> {
|
||||
assert_eq!(branch1.commits.len(), 1);
|
||||
// assert_eq!(branch1.upstream.as_ref().unwrap().commits.len(), 1);
|
||||
|
||||
merge_virtual_branch_upstream(project_repository, &branch1.id, None, None)?;
|
||||
merge_virtual_branch_upstream(project_repository, &branch1.id, None)?;
|
||||
|
||||
let (branches, _) = virtual_branches::list_virtual_branches(project_repository)?;
|
||||
let branch1 = &branches[0];
|
||||
@ -963,7 +954,6 @@ fn merge_vbranch_upstream_conflict() -> Result<()> {
|
||||
"fix merge conflict",
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
)?;
|
||||
|
||||
@ -1095,7 +1085,7 @@ fn unapply_branch() -> Result<()> {
|
||||
assert_eq!(branch.files.len(), 1);
|
||||
assert!(!branch.active);
|
||||
|
||||
apply_branch(project_repository, &branch1_id, None, None)?;
|
||||
apply_branch(project_repository, &branch1_id, None)?;
|
||||
let contents = std::fs::read(Path::new(&project.path).join(file_path))?;
|
||||
assert_eq!(
|
||||
"line1\nline2\nline3\nline4\nbranch1\n",
|
||||
@ -1168,11 +1158,11 @@ fn apply_unapply_added_deleted_files() -> Result<()> {
|
||||
// check that file3 is gone
|
||||
assert!(!Path::new(&project.path).join(file_path3).exists());
|
||||
|
||||
apply_branch(project_repository, &branch2_id, None, None)?;
|
||||
apply_branch(project_repository, &branch2_id, None)?;
|
||||
// check that file2 is gone
|
||||
assert!(!Path::new(&project.path).join(file_path2).exists());
|
||||
|
||||
apply_branch(project_repository, &branch3_id, None, None)?;
|
||||
apply_branch(project_repository, &branch3_id, None)?;
|
||||
// check that file3 is back
|
||||
let contents = std::fs::read(Path::new(&project.path).join(file_path3))?;
|
||||
assert_eq!("file3\n", String::from_utf8(contents)?);
|
||||
@ -1461,7 +1451,6 @@ fn upstream_integrated_vbranch() -> Result<()> {
|
||||
"integrated commit",
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
)?;
|
||||
commit(
|
||||
@ -1470,7 +1459,6 @@ fn upstream_integrated_vbranch() -> Result<()> {
|
||||
"non-integrated commit",
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
)?;
|
||||
|
||||
@ -1531,7 +1519,6 @@ fn commit_same_hunk_twice() -> Result<()> {
|
||||
"first commit to test.txt",
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
)?;
|
||||
|
||||
@ -1567,7 +1554,6 @@ fn commit_same_hunk_twice() -> Result<()> {
|
||||
"second commit to test.txt",
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
)?;
|
||||
|
||||
@ -1626,7 +1612,6 @@ fn commit_same_file_twice() -> Result<()> {
|
||||
"first commit to test.txt",
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
)?;
|
||||
|
||||
@ -1662,7 +1647,6 @@ fn commit_same_file_twice() -> Result<()> {
|
||||
"second commit to test.txt",
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
)?;
|
||||
|
||||
@ -1721,7 +1705,6 @@ fn commit_partial_by_hunk() -> Result<()> {
|
||||
"first commit to test.txt",
|
||||
Some(&"test.txt:1-6".parse::<BranchOwnershipClaims>().unwrap()),
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
)?;
|
||||
|
||||
@ -1740,7 +1723,6 @@ fn commit_partial_by_hunk() -> Result<()> {
|
||||
"second commit to test.txt",
|
||||
Some(&"test.txt:16-22".parse::<BranchOwnershipClaims>().unwrap()),
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
)?;
|
||||
|
||||
@ -1799,7 +1781,6 @@ fn commit_partial_by_file() -> Result<()> {
|
||||
"branch1 commit",
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
)?;
|
||||
|
||||
@ -1867,7 +1848,6 @@ fn commit_add_and_delete_files() -> Result<()> {
|
||||
"branch1 commit",
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
)?;
|
||||
|
||||
@ -1933,7 +1913,6 @@ fn commit_executable_and_symlinks() -> Result<()> {
|
||||
"branch1 commit",
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
)?;
|
||||
|
||||
@ -2110,7 +2089,6 @@ fn pre_commit_hook_rejection() -> Result<()> {
|
||||
&branch1_id,
|
||||
"test commit",
|
||||
None,
|
||||
Some(suite.keys.get_or_create()?).as_ref(),
|
||||
None,
|
||||
true,
|
||||
);
|
||||
@ -2175,7 +2153,6 @@ fn post_commit_hook() -> Result<()> {
|
||||
&branch1_id,
|
||||
"test commit",
|
||||
None,
|
||||
Some(suite.keys.get_or_create()?).as_ref(),
|
||||
None,
|
||||
true,
|
||||
)?;
|
||||
@ -2224,7 +2201,6 @@ fn commit_msg_hook_rejection() -> Result<()> {
|
||||
&branch1_id,
|
||||
"test commit",
|
||||
None,
|
||||
Some(suite.keys.get_or_create()?).as_ref(),
|
||||
None,
|
||||
true,
|
||||
);
|
||||
|
@ -29,6 +29,7 @@ test-askpass-path = []
|
||||
thiserror.workspace = true
|
||||
serde = { workspace = true, optional = true }
|
||||
tokio = { workspace = true, optional = true, features = ["process", "time", "io-util", "net", "fs"] }
|
||||
uuid.workspace = true
|
||||
rand = "0.8.5"
|
||||
futures = "0.3.30"
|
||||
sysinfo = "0.30.11"
|
||||
|
@ -24,5 +24,5 @@ pub use self::executor::tokio;
|
||||
pub use self::{
|
||||
error::Error,
|
||||
refspec::{Error as RefSpecError, RefSpec},
|
||||
repository::{fetch, push},
|
||||
repository::{fetch, push, sign_commit},
|
||||
};
|
||||
|
@ -59,7 +59,7 @@ pub type Error<E> = RepositoryError<
|
||||
#[cold]
|
||||
async fn execute_with_auth_harness<P, F, Fut, E, Extra>(
|
||||
repo_path: P,
|
||||
executor: E,
|
||||
executor: &E,
|
||||
args: &[&str],
|
||||
envs: Option<HashMap<String, String>>,
|
||||
mut on_prompt: F,
|
||||
@ -155,7 +155,7 @@ where
|
||||
.or_else(|| std::env::var("GIT_SSH").ok())
|
||||
{
|
||||
Some(v) => v,
|
||||
None => get_core_sshcommand(&executor, &repo_path)
|
||||
None => get_core_sshcommand(executor, &repo_path)
|
||||
.await
|
||||
.unwrap_or_else(|| "ssh".into()),
|
||||
};
|
||||
@ -300,7 +300,7 @@ where
|
||||
args.push(&refspec);
|
||||
|
||||
let (status, stdout, stderr) =
|
||||
execute_with_auth_harness(repo_path, executor, &args, None, on_prompt, extra).await?;
|
||||
execute_with_auth_harness(repo_path, &executor, &args, None, on_prompt, extra).await?;
|
||||
|
||||
if status == 0 {
|
||||
Ok(())
|
||||
@ -362,7 +362,7 @@ where
|
||||
}
|
||||
|
||||
let (status, stdout, stderr) =
|
||||
execute_with_auth_harness(repo_path, executor, &args, None, on_prompt, extra).await?;
|
||||
execute_with_auth_harness(repo_path, &executor, &args, None, on_prompt, extra).await?;
|
||||
|
||||
if status == 0 {
|
||||
Ok(())
|
||||
@ -392,6 +392,118 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Signs the given commit-ish in the repository at the given path.
|
||||
/// Returns the newly signed commit SHA.
|
||||
///
|
||||
/// Any prompts for the user are passed to the asynchronous callback `on_prompt`,
|
||||
/// which should return the user's response or `None` if the operation should be
|
||||
/// aborted, in which case an `Err` value is returned from this function.
|
||||
pub async fn sign_commit<P, E, F, Extra, Fut>(
|
||||
repo_path: P,
|
||||
executor: E,
|
||||
base_commitish: String,
|
||||
on_prompt: F,
|
||||
extra: Extra,
|
||||
) -> Result<String, crate::Error<Error<E>>>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
E: GitExecutor,
|
||||
F: FnMut(String, Extra) -> Fut,
|
||||
Fut: std::future::Future<Output = Option<String>>,
|
||||
Extra: Send + Clone,
|
||||
{
|
||||
let repo_path = repo_path.as_ref();
|
||||
|
||||
// First, create a worktree to perform the commit.
|
||||
let worktree_path = repo_path
|
||||
.join(".git")
|
||||
.join("gitbutler")
|
||||
.join(".wt")
|
||||
.join(uuid::Uuid::new_v4().to_string());
|
||||
let args = [
|
||||
"worktree",
|
||||
"add",
|
||||
"--detach",
|
||||
"--no-checkout",
|
||||
worktree_path.to_str().unwrap(),
|
||||
base_commitish.as_str(),
|
||||
];
|
||||
let (status, stdout, stderr) = executor
|
||||
.execute(&args, repo_path, None)
|
||||
.await
|
||||
.map_err(Error::<E>::Exec)?;
|
||||
if status != 0 {
|
||||
return Err(Error::<E>::Failed {
|
||||
status,
|
||||
args: args.into_iter().map(Into::into).collect(),
|
||||
stdout,
|
||||
stderr,
|
||||
})?;
|
||||
}
|
||||
|
||||
// Now, perform the commit.
|
||||
let args = [
|
||||
"commit",
|
||||
"--amend",
|
||||
"-S",
|
||||
"-o",
|
||||
"--no-edit",
|
||||
"--no-verify",
|
||||
"--no-post-rewrite",
|
||||
"--allow-empty",
|
||||
"--allow-empty-message",
|
||||
];
|
||||
let (status, stdout, stderr) =
|
||||
execute_with_auth_harness(&worktree_path, &executor, &args, None, on_prompt, extra).await?;
|
||||
if status != 0 {
|
||||
return Err(Error::<E>::Failed {
|
||||
status,
|
||||
args: args.into_iter().map(Into::into).collect(),
|
||||
stdout,
|
||||
stderr,
|
||||
})?;
|
||||
}
|
||||
|
||||
// Get the commit hash that was generated
|
||||
let args = ["rev-parse", "--verify", "HEAD"];
|
||||
let (status, stdout, stderr) = executor
|
||||
.execute(&args, &worktree_path, None)
|
||||
.await
|
||||
.map_err(Error::<E>::Exec)?;
|
||||
if status != 0 {
|
||||
return Err(Error::<E>::Failed {
|
||||
status,
|
||||
args: args.into_iter().map(Into::into).collect(),
|
||||
stdout,
|
||||
stderr,
|
||||
})?;
|
||||
}
|
||||
|
||||
let commit_hash = stdout.trim().to_string();
|
||||
|
||||
// Finally, remove the worktree
|
||||
let args = [
|
||||
"worktree",
|
||||
"remove",
|
||||
"--force",
|
||||
worktree_path.to_str().unwrap(),
|
||||
];
|
||||
let (status, stdout, stderr) = executor
|
||||
.execute(&args, repo_path, None)
|
||||
.await
|
||||
.map_err(Error::<E>::Exec)?;
|
||||
if status != 0 {
|
||||
return Err(Error::<E>::Failed {
|
||||
status,
|
||||
args: args.into_iter().map(Into::into).collect(),
|
||||
stdout,
|
||||
stderr,
|
||||
})?;
|
||||
}
|
||||
|
||||
Ok(commit_hash)
|
||||
}
|
||||
|
||||
async fn get_core_sshcommand<E: GitExecutor, P: AsRef<Path>>(
|
||||
executor: &E,
|
||||
cwd: P,
|
||||
|
@ -140,7 +140,6 @@ fn main() {
|
||||
app_handle.manage(gitbutler_core::virtual_branches::controller::Controller::new(
|
||||
projects_controller.clone(),
|
||||
users_controller.clone(),
|
||||
keys_controller.clone(),
|
||||
git_credentials_controller.clone(),
|
||||
));
|
||||
|
||||
|
@ -37,7 +37,6 @@ mod support {
|
||||
let vbranch_controller = virtual_branches::Controller::new(
|
||||
inner.projects.clone(),
|
||||
inner.users.clone(),
|
||||
inner.keys.clone(),
|
||||
git_credentials_helper,
|
||||
);
|
||||
let assets_proxy = assets::Proxy::new(tmp.path().to_owned());
|
||||
|
Loading…
Reference in New Issue
Block a user