From 93176c9e55878ec4f109dac3b0a43aa2dcf90a9c Mon Sep 17 00:00:00 2001 From: Antonio Yang Date: Tue, 13 Feb 2024 17:03:50 +0800 Subject: [PATCH 01/22] sign a commit if ssh secret key is provided --- asyncgit/Cargo.toml | 1 + asyncgit/src/error.rs | 4 +++ asyncgit/src/lib.rs | 1 + asyncgit/src/sync/commit.rs | 52 ++++++++++++++++++++++++++---- asyncgit/src/sync/commit_revert.rs | 4 ++- src/components/commit.rs | 47 ++++++++++++++++++++++++--- 6 files changed, 96 insertions(+), 13 deletions(-) diff --git a/asyncgit/Cargo.toml b/asyncgit/Cargo.toml index e2253f7afa..bd1dc03a36 100644 --- a/asyncgit/Cargo.toml +++ b/asyncgit/Cargo.toml @@ -27,6 +27,7 @@ rayon = "1.8" rayon-core = "1.12" scopetime = { path = "../scopetime", version = "0.1" } serde = { version = "1.0", features = ["derive"] } +ssh-key = { version = "0.6.4", features = ["crypto", "encryption"] } thiserror = "1.0" unicode-truncate = "0.2" url = "2.5" diff --git a/asyncgit/src/error.rs b/asyncgit/src/error.rs index 6ede042230..0cbaf28d96 100644 --- a/asyncgit/src/error.rs +++ b/asyncgit/src/error.rs @@ -84,6 +84,10 @@ pub enum Error { /// #[error("git hook error: {0}")] Hooks(#[from] git2_hooks::HooksError), + + /// + #[error("ssh key error: {0}")] + SshKeyError(#[from] ssh_key::Error), } /// diff --git a/asyncgit/src/lib.rs b/asyncgit/src/lib.rs index dc75de9d52..c1149a4371 100644 --- a/asyncgit/src/lib.rs +++ b/asyncgit/src/lib.rs @@ -76,6 +76,7 @@ pub use crate::{ treefiles::AsyncTreeFilesJob, }; pub use git2::message_prettify; +pub use ssh_key; use std::{ collections::hash_map::DefaultHasher, hash::{Hash, Hasher}, diff --git a/asyncgit/src/sync/commit.rs b/asyncgit/src/sync/commit.rs index d1af74d85d..3a0cd0e57d 100644 --- a/asyncgit/src/sync/commit.rs +++ b/asyncgit/src/sync/commit.rs @@ -5,6 +5,7 @@ use crate::{ }; use git2::{ErrorCode, ObjectType, Repository, Signature}; use scopetime::scope_time; +use ssh_key::{HashAlg, LineEnding, PrivateKey}; /// pub fn amend( @@ -61,7 +62,12 @@ pub(crate) fn signature_allow_undefined_name( } /// this does not run any git hooks, git-hooks have to be executed manually, checkout `hooks_commit_msg` for example -pub fn commit(repo_path: &RepoPath, msg: &str) -> Result { +/// If ssh private key is provided, the commit will be signed. +pub fn commit( + repo_path: &RepoPath, + msg: &str, + sk: Option<&PrivateKey>, +) -> Result { scope_time!("commit"); let repo = repo(repo_path)?; @@ -78,17 +84,49 @@ pub fn commit(repo_path: &RepoPath, msg: &str) -> Result { }; let parents = parents.iter().collect::>(); - - Ok(repo - .commit( - Some("HEAD"), + if let Some(sk) = sk { + let buffer = repo.commit_create_buffer( &signature, &signature, msg, &tree, parents.as_slice(), - )? - .into()) + )?; + let content = String::from_utf8(buffer.to_vec())?; + let sig = sk + .sign("git", HashAlg::Sha256, &buffer)? + .to_pem(LineEnding::LF)?; + let commit_id = repo.commit_signed(&content, &sig, None)?; + match repo.head() { + Ok(mut head) => { + head.set_target(commit_id, msg)?; + } + Err(_) => { + let config = repo.config()?; + let default_branch_name = config + .get_str("init.defaultBranch") + .unwrap_or("master"); + repo.reference( + &format!("refs/heads/{}", default_branch_name), + commit_id, + true, + msg, + )?; + } + } + Ok(commit_id.into()) + } else { + Ok(repo + .commit( + Some("HEAD"), + &signature, + &signature, + msg, + &tree, + parents.as_slice(), + )? + .into()) + } } /// Tag a commit. diff --git a/asyncgit/src/sync/commit_revert.rs b/asyncgit/src/sync/commit_revert.rs index 2d66a2a1d4..75faa54dc9 100644 --- a/asyncgit/src/sync/commit_revert.rs +++ b/asyncgit/src/sync/commit_revert.rs @@ -4,6 +4,7 @@ use crate::{ sync::{repository::repo, utils::read_file}, }; use scopetime::scope_time; +use ssh_key::PrivateKey; const GIT_REVERT_HEAD_FILE: &str = "REVERT_HEAD"; @@ -40,10 +41,11 @@ pub fn revert_head(repo_path: &RepoPath) -> Result { pub fn commit_revert( repo_path: &RepoPath, msg: &str, + sk: Option<&PrivateKey>, ) -> Result { scope_time!("commit_revert"); - let id = crate::sync::commit(repo_path, msg)?; + let id = crate::sync::commit(repo_path, msg, sk)?; repo(repo_path)?.cleanup_state()?; diff --git a/src/components/commit.rs b/src/components/commit.rs index 60365eee6f..50763f2645 100644 --- a/src/components/commit.rs +++ b/src/components/commit.rs @@ -14,6 +14,7 @@ use crate::{ use anyhow::{bail, Ok, Result}; use asyncgit::{ cached, message_prettify, + ssh_key::private::PrivateKey, sync::{ self, get_config_string, CommitId, HookResult, PrepareCommitMsgSource, RepoPathRef, RepoState, @@ -29,7 +30,8 @@ use ratatui::{ Frame, }; use std::{ - fs::{read_to_string, File}, + env::var, + fs::{read, read_to_string, File}, io::{Read, Write}, path::PathBuf, str::FromStr, @@ -60,6 +62,7 @@ pub struct CommitComponent { commit_msg_history_idx: usize, options: SharedOptions, verify: bool, + ssh_secret_key: Option, } const FIRST_LINE_LIMIT: usize = 50; @@ -67,6 +70,33 @@ const FIRST_LINE_LIMIT: usize = 50; impl CommitComponent { /// pub fn new(env: &Environment) -> Self { + let arg_ssh_key_path = var("GITUI_SSH_KEY_PATH") + .unwrap_or_else(|_| "~/.ssh/id_rsa".to_string()); + + let ssh_key_abs_path = if let Some(ssh_key_path) = + arg_ssh_key_path.strip_prefix("~") + { + dirs::home_dir().map(|home| { + home.join( + ssh_key_path + .strip_prefix("/") + .unwrap_or(ssh_key_path), + ) + }) + } else { + Some(PathBuf::from(arg_ssh_key_path)) + }; + + let mut ssh_secret_key = ssh_key_abs_path + .and_then(|p| read(p).ok()) + .and_then(|bytes| PrivateKey::from_openssh(bytes).ok()); + if let std::result::Result::Ok(password) = + var("GITUI_SSH_KEY_PASSWORD") + { + ssh_secret_key = ssh_secret_key + .and_then(|key| key.decrypt(password.as_bytes()).ok()) + } + Self { queue: env.queue.clone(), mode: Mode::Normal, @@ -86,6 +116,7 @@ impl CommitComponent { commit_msg_history_idx: 0, options: env.options.clone(), verify: true, + ssh_secret_key, } } @@ -284,16 +315,22 @@ impl CommitComponent { fn do_commit(&self, msg: &str) -> Result<()> { match &self.mode { - Mode::Normal => sync::commit(&self.repo.borrow(), msg)?, + Mode::Normal => sync::commit( + &self.repo.borrow(), + msg, + self.ssh_secret_key.as_ref(), + )?, Mode::Amend(amend) => { sync::amend(&self.repo.borrow(), *amend, msg)? } Mode::Merge(ids) => { sync::merge_commit(&self.repo.borrow(), msg, ids)? } - Mode::Revert => { - sync::commit_revert(&self.repo.borrow(), msg)? - } + Mode::Revert => sync::commit_revert( + &self.repo.borrow(), + msg, + self.ssh_secret_key.as_ref(), + )?, Mode::Reword(id) => { let commit = sync::reword(&self.repo.borrow(), *id, msg)?; From ace746530c2f4add075a1aae2d5fef522283f9ff Mon Sep 17 00:00:00 2001 From: Antonio Yang Date: Tue, 13 Feb 2024 17:17:36 +0800 Subject: [PATCH 02/22] update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e43b09d54..aec61fe202 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * `theme.ron` now supports customizing line break symbol ([#1894](https://github.com/extrawurst/gitui/issues/1894)) * add confirmation for dialog for undo commit [[@TeFiLeDo](https://github.com/TeFiLeDo)] ([#1912](https://github.com/extrawurst/gitui/issues/1912)) * support `prepare-commit-msg` hook ([#1873](https://github.com/extrawurst/gitui/issues/1873)) +* support sign commit with ssh key by `GITUI_SSH_KEY_PATH` and `GITUI_SSH_PASSWORD`([#1149](https://github.com/extrawurst/gitui/issues/1149)) ### Changed * do not allow tag when `tag.gpgsign` enabled [[@TeFiLeDo](https://github.com/TeFiLeDo)] ([#1915](https://github.com/extrawurst/gitui/pull/1915)) From a1e7b5b86e02b9927fdea4b7fa882bcb37227bc5 Mon Sep 17 00:00:00 2001 From: Antonio Yang Date: Tue, 13 Feb 2024 17:38:26 +0800 Subject: [PATCH 03/22] update cargo audit --- .cargo/audit.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.cargo/audit.toml b/.cargo/audit.toml index 46ec91ce05..37f7153733 100644 --- a/.cargo/audit.toml +++ b/.cargo/audit.toml @@ -1,2 +1,4 @@ [advisories] -ignore = [] \ No newline at end of file +# No fix for RSA, and this is a dependency from ssh_key crate to handle rsa ssh key. +# https://rustsec.org/advisories/RUSTSEC-2023-0071 +ignore = ["RUSTSEC-2023-0071"] From 596b28aadbb13e8a500b67246c2926036985dffb Mon Sep 17 00:00:00 2001 From: Antonio Yang Date: Tue, 13 Feb 2024 18:06:56 +0800 Subject: [PATCH 04/22] update test case --- Cargo.lock | 724 ++++++++++++++++++++++++++++ asyncgit/src/sync/blame.rs | 8 +- asyncgit/src/sync/commit.rs | 18 +- asyncgit/src/sync/commit_details.rs | 2 +- asyncgit/src/sync/commit_files.rs | 4 +- asyncgit/src/sync/commits_info.rs | 10 +- asyncgit/src/sync/diff.rs | 6 +- asyncgit/src/sync/logwalker.rs | 14 +- asyncgit/src/sync/mod.rs | 1 + asyncgit/src/sync/remotes/push.rs | 4 + asyncgit/src/sync/reset.rs | 2 +- asyncgit/src/sync/stash.rs | 2 +- asyncgit/src/sync/utils.rs | 2 +- 13 files changed, 763 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8513f117b9..57c19ddc4f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,41 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + [[package]] name = "aho-corasick" version = "1.1.2" @@ -115,6 +150,7 @@ dependencies = [ "scopetime", "serde", "serial_test", + "ssh-key", "tempfile", "thiserror", "unicode-truncate", @@ -142,12 +178,35 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bcrypt-pbkdf" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aeac2e1fe888769f34f05ac343bbef98b14d1ffb292ab69d4608b3abc86f2a2" +dependencies = [ + "blowfish", + "pbkdf2", + "sha2", +] + [[package]] name = "bincode" version = "1.3.3" @@ -187,6 +246,34 @@ dependencies = [ "serde", ] +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blowfish" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7" +dependencies = [ + "byteorder", + "cipher", +] + [[package]] name = "bugreport" version = "0.5.0" @@ -213,6 +300,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytesize" version = "1.3.0" @@ -225,6 +318,15 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" +[[package]] +name = "cbc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] + [[package]] name = "cc" version = "1.0.83" @@ -241,6 +343,17 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + [[package]] name = "chrono" version = "0.4.34" @@ -253,6 +366,16 @@ dependencies = [ "windows-targets 0.52.0", ] +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + [[package]] name = "clap" version = "4.5.0" @@ -286,12 +409,27 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + [[package]] name = "core-foundation-sys" version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + [[package]] name = "crc32fast" version = "1.3.2" @@ -361,6 +499,64 @@ dependencies = [ "winapi", ] +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "platforms", + "rustc_version", + "subtle", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "dashmap" version = "5.5.3" @@ -374,6 +570,16 @@ dependencies = [ "parking_lot_core", ] +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "deranged" version = "0.3.11" @@ -389,6 +595,18 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + [[package]] name = "dirs" version = "5.0.1" @@ -416,12 +634,66 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10936778145f3bea71fd9bf61332cce28c28e96a380714f7ab34838b80733fd6" +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" +dependencies = [ + "curve25519-dalek", + "ed25519", + "sha2", + "subtle", +] + [[package]] name = "either" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "env_filter" version = "0.1.0" @@ -477,6 +749,22 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1676f435fc1dadde4d03e43f5d62b259e1ce5f40bd4ffb21db2b42ebe59c1382" + [[package]] name = "filetime" version = "0.2.23" @@ -617,6 +905,17 @@ dependencies = [ "thread_local", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + [[package]] name = "getrandom" version = "0.2.12" @@ -638,6 +937,16 @@ dependencies = [ "regex", ] +[[package]] +name = "ghash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" +dependencies = [ + "opaque-debug", + "polyval", +] + [[package]] name = "gimli" version = "0.28.1" @@ -746,6 +1055,17 @@ dependencies = [ "which", ] +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + [[package]] name = "hashbrown" version = "0.14.3" @@ -758,6 +1078,15 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + [[package]] name = "home" version = "0.5.9" @@ -842,6 +1171,16 @@ dependencies = [ "libc", ] +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "block-padding", + "generic-array", +] + [[package]] name = "invalidstring" version = "0.1.2" @@ -913,6 +1252,9 @@ name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin", +] [[package]] name = "libc" @@ -934,6 +1276,12 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + [[package]] name = "libredox" version = "0.0.1" @@ -1050,12 +1398,49 @@ dependencies = [ "notify", ] +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand", + "smallvec", + "zeroize", +] + [[package]] name = "num-conv" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.18" @@ -1063,6 +1448,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -1102,6 +1488,12 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + [[package]] name = "openssl-probe" version = "0.1.5" @@ -1136,6 +1528,44 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[package]] +name = "p384" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[package]] +name = "p521" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc9e2161f1f215afdfce23677034ae137bbd45016a880c2eb3ba8eb95f085b2" +dependencies = [ + "base16ct", + "ecdsa", + "elliptic-curve", + "primeorder", + "rand_core", + "sha2", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -1165,6 +1595,24 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -1201,18 +1649,74 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + [[package]] name = "pkg-config" version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" +[[package]] +name = "platforms" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" + +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "polyval" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + [[package]] name = "powerfmt" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + [[package]] name = "pretty_assertions" version = "1.4.0" @@ -1223,6 +1727,15 @@ dependencies = [ "yansi", ] +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + [[package]] name = "proc-macro2" version = "1.0.78" @@ -1241,6 +1754,35 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "ratatui" version = "0.23.0" @@ -1328,6 +1870,16 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + [[package]] name = "ron" version = "0.8.1" @@ -1340,12 +1892,42 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "rsa" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core", + "sha2", + "signature", + "spki", + "subtle", + "zeroize", +] + [[package]] name = "rustc-demangle" version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "0.38.31" @@ -1393,6 +1975,26 @@ dependencies = [ "log", ] +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" + [[package]] name = "serde" version = "1.0.196" @@ -1449,6 +2051,17 @@ dependencies = [ "syn", ] +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "shell-escape" version = "0.1.5" @@ -1494,6 +2107,16 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core", +] + [[package]] name = "simplelog" version = "0.12.1" @@ -1525,6 +2148,73 @@ version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "ssh-cipher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caac132742f0d33c3af65bfcde7f6aa8f62f0e991d80db99149eb9d44708784f" +dependencies = [ + "aes", + "aes-gcm", + "cbc", + "chacha20", + "cipher", + "ctr", + "poly1305", + "ssh-encoding", + "subtle", +] + +[[package]] +name = "ssh-encoding" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9242b9ef4108a78e8cd1a2c98e193ef372437f8c22be363075233321dd4a15" +dependencies = [ + "base64ct", + "pem-rfc7468", + "sha2", +] + +[[package]] +name = "ssh-key" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01f8f4ea73476c0aa5d5e6a75ce1e8634e2c3f82005ef3bbed21547ac57f2bf7" +dependencies = [ + "bcrypt-pbkdf", + "ed25519-dalek", + "num-bigint-dig", + "p256", + "p384", + "p521", + "rand_core", + "rsa", + "sec1", + "sha2", + "signature", + "ssh-cipher", + "ssh-encoding", + "subtle", + "zeroize", +] + [[package]] name = "strsim" version = "0.11.0" @@ -1573,6 +2263,12 @@ dependencies = [ "syn", ] +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + [[package]] name = "syn" version = "2.0.48" @@ -1703,6 +2399,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + [[package]] name = "unicode-bidi" version = "0.3.15" @@ -1745,6 +2447,16 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + [[package]] name = "url" version = "2.5.0" @@ -1768,6 +2480,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + [[package]] name = "walkdir" version = "2.4.0" @@ -2028,3 +2746,9 @@ name = "yansi" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/asyncgit/src/sync/blame.rs b/asyncgit/src/sync/blame.rs index 92edc991d0..9ff0e5259f 100644 --- a/asyncgit/src/sync/blame.rs +++ b/asyncgit/src/sync/blame.rs @@ -175,7 +175,7 @@ mod tests { File::create(root.join(file_path))?.write_all(b"line 1\n")?; stage_add_file(repo_path, file_path)?; - commit(repo_path, "first commit")?; + commit(repo_path, "first commit", None)?; let blame = blame_file(repo_path, "foo", None)?; @@ -199,7 +199,7 @@ mod tests { file.write(b"line 2\n")?; stage_add_file(repo_path, file_path)?; - commit(repo_path, "second commit")?; + commit(repo_path, "second commit", None)?; let blame = blame_file(repo_path, "foo", None)?; @@ -233,7 +233,7 @@ mod tests { assert_eq!(blame.lines.len(), 2); stage_add_file(repo_path, file_path)?; - commit(repo_path, "third commit")?; + commit(repo_path, "third commit", None)?; let blame = blame_file(repo_path, "foo", None)?; @@ -258,7 +258,7 @@ mod tests { .unwrap(); stage_add_file(repo_path, file_path).unwrap(); - commit(repo_path, "first commit").unwrap(); + commit(repo_path, "first commit", None).unwrap(); assert!(blame_file(repo_path, "bar\\foo", None).is_ok()); } diff --git a/asyncgit/src/sync/commit.rs b/asyncgit/src/sync/commit.rs index 3a0cd0e57d..e342958157 100644 --- a/asyncgit/src/sync/commit.rs +++ b/asyncgit/src/sync/commit.rs @@ -200,7 +200,7 @@ mod tests { assert_eq!(get_statuses(repo_path), (0, 1)); - commit(repo_path, "commit msg").unwrap(); + commit(repo_path, "commit msg", None).unwrap(); assert_eq!(get_statuses(repo_path), (0, 0)); } @@ -226,7 +226,7 @@ mod tests { assert_eq!(get_statuses(repo_path), (0, 1)); - commit(repo_path, "commit msg").unwrap(); + commit(repo_path, "commit msg", None).unwrap(); assert_eq!(get_statuses(repo_path), (0, 0)); } @@ -243,7 +243,7 @@ mod tests { File::create(root.join(file_path1))?.write_all(b"test1")?; stage_add_file(repo_path, file_path1)?; - let id = commit(repo_path, "commit msg")?; + let id = commit(repo_path, "commit msg", None)?; assert_eq!(count_commits(&repo, 10), 1); @@ -282,7 +282,7 @@ mod tests { stage_add_file(repo_path, file_path)?; - let new_id = commit(repo_path, "commit msg")?; + let new_id = commit(repo_path, "commit msg", None)?; tag_commit(repo_path, &new_id, "tag", None)?; @@ -324,7 +324,7 @@ mod tests { stage_add_file(repo_path, file_path)?; - let new_id = commit(repo_path, "commit msg")?; + let new_id = commit(repo_path, "commit msg", None)?; tag_commit(repo_path, &new_id, "tag", Some("tag-message"))?; @@ -360,13 +360,13 @@ mod tests { repo.config()?.remove("user.email")?; - let error = commit(repo_path, "commit msg"); + let error = commit(repo_path, "commit msg", None); assert!(matches!(error, Err(_))); repo.config()?.set_str("user.email", "email")?; - let success = commit(repo_path, "commit msg"); + let success = commit(repo_path, "commit msg", None); assert!(matches!(success, Ok(_))); assert_eq!(count_commits(&repo, 10), 1); @@ -396,7 +396,7 @@ mod tests { repo.config()?.remove("user.name")?; - let mut success = commit(repo_path, "commit msg"); + let mut success = commit(repo_path, "commit msg", None); assert!(matches!(success, Ok(_))); assert_eq!(count_commits(&repo, 10), 1); @@ -409,7 +409,7 @@ mod tests { repo.config()?.set_str("user.name", "name")?; - success = commit(repo_path, "commit msg"); + success = commit(repo_path, "commit msg", None); assert!(matches!(success, Ok(_))); assert_eq!(count_commits(&repo, 10), 2); diff --git a/asyncgit/src/sync/commit_details.rs b/asyncgit/src/sync/commit_details.rs index 8de0894b71..4b516b1f12 100644 --- a/asyncgit/src/sync/commit_details.rs +++ b/asyncgit/src/sync/commit_details.rs @@ -144,7 +144,7 @@ mod tests { stage_add_file(repo_path, file_path).unwrap(); let msg = invalidstring::invalid_utf8("test msg"); - let id = commit(repo_path, msg.as_str()).unwrap(); + let id = commit(repo_path, msg.as_str(), None).unwrap(); let res = get_commit_details(repo_path, id).unwrap(); diff --git a/asyncgit/src/sync/commit_files.rs b/asyncgit/src/sync/commit_files.rs index d5927cc9ca..4d7f287134 100644 --- a/asyncgit/src/sync/commit_files.rs +++ b/asyncgit/src/sync/commit_files.rs @@ -209,7 +209,7 @@ mod tests { stage_add_file(repo_path, file_path)?; - let id = commit(repo_path, "commit msg")?; + let id = commit(repo_path, "commit msg", None)?; let diff = get_commit_files(repo_path, id, None)?; @@ -251,7 +251,7 @@ mod tests { File::create(root.join(file_path1))?.write_all(b"test")?; stage_add_file(repo_path, file_path1)?; - commit(repo_path, "c1")?; + commit(repo_path, "c1", None)?; File::create(root.join(file_path1))? .write_all(b"modified")?; diff --git a/asyncgit/src/sync/commits_info.rs b/asyncgit/src/sync/commits_info.rs index 1f049e9003..f10cb15c5b 100644 --- a/asyncgit/src/sync/commits_info.rs +++ b/asyncgit/src/sync/commits_info.rs @@ -172,10 +172,10 @@ mod tests { File::create(root.join(file_path))?.write_all(b"a")?; stage_add_file(repo_path, file_path).unwrap(); - let c1 = commit(repo_path, "commit1").unwrap(); + let c1 = commit(repo_path, "commit1", None).unwrap(); File::create(root.join(file_path))?.write_all(b"a")?; stage_add_file(repo_path, file_path).unwrap(); - let c2 = commit(repo_path, "commit2").unwrap(); + let c2 = commit(repo_path, "commit2", None).unwrap(); let res = get_commits_info(repo_path, &[c2, c1], 50).unwrap(); @@ -197,7 +197,7 @@ mod tests { File::create(root.join(file_path))?.write_all(b"a")?; stage_add_file(repo_path, file_path).unwrap(); - let c1 = commit(repo_path, "subject\nbody").unwrap(); + let c1 = commit(repo_path, "subject\nbody", None).unwrap(); let res = get_commits_info(repo_path, &[c1], 50).unwrap(); @@ -219,7 +219,7 @@ mod tests { stage_add_file(repo_path, file_path).unwrap(); let msg = invalidstring::invalid_utf8("test msg"); - commit(repo_path, msg.as_str()).unwrap(); + commit(repo_path, msg.as_str(), None).unwrap(); let res = get_commits_info( repo_path, @@ -245,7 +245,7 @@ mod tests { let foo_file = Path::new("foo"); File::create(root.join(foo_file))?.write_all(b"a")?; stage_add_file(repo_path, foo_file).unwrap(); - let c1 = commit(repo_path, "subject: foo\nbody").unwrap(); + let c1 = commit(repo_path, "subject: foo\nbody", None).unwrap(); let c1_rev = c1.get_short_string(); assert_eq!( diff --git a/asyncgit/src/sync/diff.rs b/asyncgit/src/sync/diff.rs index 60b8735ad3..50ba7dd035 100644 --- a/asyncgit/src/sync/diff.rs +++ b/asyncgit/src/sync/diff.rs @@ -597,7 +597,7 @@ mod tests { stage_add_file(repo_path, file_path).unwrap(); - commit(repo_path, "commit").unwrap(); + commit(repo_path, "commit", None).unwrap(); File::create(root.join(file_path))?.write_all(b"\x00\x02")?; @@ -653,13 +653,13 @@ mod tests { stage_add_file(repo_path, file_path).unwrap(); - commit(repo_path, "").unwrap(); + commit(repo_path, "", None).unwrap(); File::create(root.join(file_path))?.write_all(b"\x00\x02")?; stage_add_file(repo_path, file_path).unwrap(); - let id = commit(repo_path, "").unwrap(); + let id = commit(repo_path, "", None).unwrap(); let diff = get_diff_commit(repo_path, id, String::new(), None) diff --git a/asyncgit/src/sync/logwalker.rs b/asyncgit/src/sync/logwalker.rs index b13a9e5a26..6e0f197467 100644 --- a/asyncgit/src/sync/logwalker.rs +++ b/asyncgit/src/sync/logwalker.rs @@ -135,10 +135,10 @@ mod tests { File::create(root.join(file_path))?.write_all(b"a")?; stage_add_file(repo_path, file_path).unwrap(); - commit(repo_path, "commit1").unwrap(); + commit(repo_path, "commit1", None).unwrap(); File::create(root.join(file_path))?.write_all(b"a")?; stage_add_file(repo_path, file_path).unwrap(); - let oid2 = commit(repo_path, "commit2").unwrap(); + let oid2 = commit(repo_path, "commit2", None).unwrap(); let mut items = Vec::new(); let mut walk = LogWalker::new(&repo, 1)?; @@ -160,10 +160,10 @@ mod tests { File::create(root.join(file_path))?.write_all(b"a")?; stage_add_file(repo_path, file_path).unwrap(); - commit(repo_path, "commit1").unwrap(); + commit(repo_path, "commit1", None).unwrap(); File::create(root.join(file_path))?.write_all(b"a")?; stage_add_file(repo_path, file_path).unwrap(); - let oid2 = commit(repo_path, "commit2").unwrap(); + let oid2 = commit(repo_path, "commit2", None).unwrap(); let mut items = Vec::new(); let mut walk = LogWalker::new(&repo, 100)?; @@ -195,17 +195,17 @@ mod tests { File::create(root.join(file_path))?.write_all(b"a")?; stage_add_file(&repo_path, file_path).unwrap(); - let _first_commit_id = commit(&repo_path, "commit1").unwrap(); + let _first_commit_id = commit(&repo_path, "commit1", None).unwrap(); File::create(root.join(second_file_path))?.write_all(b"a")?; stage_add_file(&repo_path, second_file_path).unwrap(); - let second_commit_id = commit(&repo_path, "commit2").unwrap(); + let second_commit_id = commit(&repo_path, "commit2", None).unwrap(); File::create(root.join(file_path))?.write_all(b"b")?; stage_add_file(&repo_path, file_path).unwrap(); - let _third_commit_id = commit(&repo_path, "commit3").unwrap(); + let _third_commit_id = commit(&repo_path, "commit3", None).unwrap(); let diff_contains_baz = diff_contains_file("baz".into()); diff --git a/asyncgit/src/sync/mod.rs b/asyncgit/src/sync/mod.rs index 83683a9ea0..41e5cef18a 100644 --- a/asyncgit/src/sync/mod.rs +++ b/asyncgit/src/sync/mod.rs @@ -162,6 +162,7 @@ mod tests { commit( &repo.workdir().unwrap().to_str().unwrap().into(), commit_name, + None ) .unwrap() } diff --git a/asyncgit/src/sync/remotes/push.rs b/asyncgit/src/sync/remotes/push.rs index 37cdd4a9ca..fce5da91e0 100644 --- a/asyncgit/src/sync/remotes/push.rs +++ b/asyncgit/src/sync/remotes/push.rs @@ -226,6 +226,7 @@ mod tests { sync::commit( &tmp_repo_dir.path().to_str().unwrap().into(), "repo_1_commit", + None ) .unwrap(); @@ -249,6 +250,7 @@ mod tests { sync::commit( &tmp_other_repo_dir.path().to_str().unwrap().into(), "repo_2_commit", + None ) .unwrap(); @@ -323,6 +325,7 @@ mod tests { let repo_1_commit = sync::commit( &tmp_repo_dir.path().to_str().unwrap().into(), "repo_1_commit", + None ) .unwrap(); @@ -367,6 +370,7 @@ mod tests { let repo_2_commit = sync::commit( &tmp_other_repo_dir.path().to_str().unwrap().into(), "repo_2_commit", + None ) .unwrap(); diff --git a/asyncgit/src/sync/reset.rs b/asyncgit/src/sync/reset.rs index 4142255954..518fd11e03 100644 --- a/asyncgit/src/sync/reset.rs +++ b/asyncgit/src/sync/reset.rs @@ -189,7 +189,7 @@ mod tests { } stage_add_all(repo_path, "*", None).unwrap(); - commit(repo_path, "msg").unwrap(); + commit(repo_path, "msg", None).unwrap(); { File::create(root.join("foo/file1.txt"))? diff --git a/asyncgit/src/sync/stash.rs b/asyncgit/src/sync/stash.rs index fc5d69b73d..da67e0ecfe 100644 --- a/asyncgit/src/sync/stash.rs +++ b/asyncgit/src/sync/stash.rs @@ -222,7 +222,7 @@ mod tests { File::create(root.join(file_path1))?.write_all(b"test")?; stage_add_file(repo_path, file_path1)?; - commit(repo_path, "c1")?; + commit(repo_path, "c1", None)?; File::create(root.join(file_path1))? .write_all(b"modified")?; diff --git a/asyncgit/src/sync/utils.rs b/asyncgit/src/sync/utils.rs index a5ec1b3e9b..fc82508524 100644 --- a/asyncgit/src/sync/utils.rs +++ b/asyncgit/src/sync/utils.rs @@ -388,7 +388,7 @@ mod tests { stage_add_file(repo_path, file_path).unwrap(); - commit(repo_path, "commit msg").unwrap(); + commit(repo_path, "commit msg", None).unwrap(); // delete the file now assert_eq!(remove_file(full_path).is_ok(), true); From 86f2f539abc710316746293c510fc027ddca3afd Mon Sep 17 00:00:00 2001 From: Antonio Yang Date: Tue, 13 Feb 2024 20:21:53 +0800 Subject: [PATCH 05/22] fix linter --- asyncgit/src/sync/commit.rs | 29 +++++++++++++---------------- asyncgit/src/sync/commits_info.rs | 3 ++- asyncgit/src/sync/logwalker.rs | 9 ++++++--- asyncgit/src/sync/mod.rs | 2 +- asyncgit/src/sync/remotes/push.rs | 8 ++++---- 5 files changed, 26 insertions(+), 25 deletions(-) diff --git a/asyncgit/src/sync/commit.rs b/asyncgit/src/sync/commit.rs index e342958157..5f89c0e5bc 100644 --- a/asyncgit/src/sync/commit.rs +++ b/asyncgit/src/sync/commit.rs @@ -97,22 +97,19 @@ pub fn commit( .sign("git", HashAlg::Sha256, &buffer)? .to_pem(LineEnding::LF)?; let commit_id = repo.commit_signed(&content, &sig, None)?; - match repo.head() { - Ok(mut head) => { - head.set_target(commit_id, msg)?; - } - Err(_) => { - let config = repo.config()?; - let default_branch_name = config - .get_str("init.defaultBranch") - .unwrap_or("master"); - repo.reference( - &format!("refs/heads/{}", default_branch_name), - commit_id, - true, - msg, - )?; - } + if let Ok(mut head) = repo.head() { + head.set_target(commit_id, msg)?; + } else { + let config = repo.config()?; + let default_branch_name = config + .get_str("init.defaultBranch") + .unwrap_or("master"); + repo.reference( + &format!("refs/heads/{default_branch_name}"), + commit_id, + true, + msg, + )?; } Ok(commit_id.into()) } else { diff --git a/asyncgit/src/sync/commits_info.rs b/asyncgit/src/sync/commits_info.rs index f10cb15c5b..f813fb7c10 100644 --- a/asyncgit/src/sync/commits_info.rs +++ b/asyncgit/src/sync/commits_info.rs @@ -245,7 +245,8 @@ mod tests { let foo_file = Path::new("foo"); File::create(root.join(foo_file))?.write_all(b"a")?; stage_add_file(repo_path, foo_file).unwrap(); - let c1 = commit(repo_path, "subject: foo\nbody", None).unwrap(); + let c1 = + commit(repo_path, "subject: foo\nbody", None).unwrap(); let c1_rev = c1.get_short_string(); assert_eq!( diff --git a/asyncgit/src/sync/logwalker.rs b/asyncgit/src/sync/logwalker.rs index 6e0f197467..a0eb33b2d6 100644 --- a/asyncgit/src/sync/logwalker.rs +++ b/asyncgit/src/sync/logwalker.rs @@ -195,17 +195,20 @@ mod tests { File::create(root.join(file_path))?.write_all(b"a")?; stage_add_file(&repo_path, file_path).unwrap(); - let _first_commit_id = commit(&repo_path, "commit1", None).unwrap(); + let _first_commit_id = + commit(&repo_path, "commit1", None).unwrap(); File::create(root.join(second_file_path))?.write_all(b"a")?; stage_add_file(&repo_path, second_file_path).unwrap(); - let second_commit_id = commit(&repo_path, "commit2", None).unwrap(); + let second_commit_id = + commit(&repo_path, "commit2", None).unwrap(); File::create(root.join(file_path))?.write_all(b"b")?; stage_add_file(&repo_path, file_path).unwrap(); - let _third_commit_id = commit(&repo_path, "commit3", None).unwrap(); + let _third_commit_id = + commit(&repo_path, "commit3", None).unwrap(); let diff_contains_baz = diff_contains_file("baz".into()); diff --git a/asyncgit/src/sync/mod.rs b/asyncgit/src/sync/mod.rs index 41e5cef18a..8285129de2 100644 --- a/asyncgit/src/sync/mod.rs +++ b/asyncgit/src/sync/mod.rs @@ -162,7 +162,7 @@ mod tests { commit( &repo.workdir().unwrap().to_str().unwrap().into(), commit_name, - None + None, ) .unwrap() } diff --git a/asyncgit/src/sync/remotes/push.rs b/asyncgit/src/sync/remotes/push.rs index fce5da91e0..a48c1d369a 100644 --- a/asyncgit/src/sync/remotes/push.rs +++ b/asyncgit/src/sync/remotes/push.rs @@ -226,7 +226,7 @@ mod tests { sync::commit( &tmp_repo_dir.path().to_str().unwrap().into(), "repo_1_commit", - None + None, ) .unwrap(); @@ -250,7 +250,7 @@ mod tests { sync::commit( &tmp_other_repo_dir.path().to_str().unwrap().into(), "repo_2_commit", - None + None, ) .unwrap(); @@ -325,7 +325,7 @@ mod tests { let repo_1_commit = sync::commit( &tmp_repo_dir.path().to_str().unwrap().into(), "repo_1_commit", - None + None, ) .unwrap(); @@ -370,7 +370,7 @@ mod tests { let repo_2_commit = sync::commit( &tmp_other_repo_dir.path().to_str().unwrap().into(), "repo_2_commit", - None + None, ) .unwrap(); From 9acfb034630f50c45b1a8d3e2bfa23164d5ac325 Mon Sep 17 00:00:00 2001 From: Antonio Yang Date: Tue, 13 Feb 2024 20:43:40 +0800 Subject: [PATCH 06/22] fix linter for gitui --- src/components/commit.rs | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/components/commit.rs b/src/components/commit.rs index 50763f2645..0011177861 100644 --- a/src/components/commit.rs +++ b/src/components/commit.rs @@ -73,19 +73,19 @@ impl CommitComponent { let arg_ssh_key_path = var("GITUI_SSH_KEY_PATH") .unwrap_or_else(|_| "~/.ssh/id_rsa".to_string()); - let ssh_key_abs_path = if let Some(ssh_key_path) = - arg_ssh_key_path.strip_prefix("~") - { - dirs::home_dir().map(|home| { - home.join( - ssh_key_path - .strip_prefix("/") - .unwrap_or(ssh_key_path), - ) - }) - } else { - Some(PathBuf::from(arg_ssh_key_path)) - }; + let ssh_key_abs_path = + arg_ssh_key_path.strip_prefix('~').map_or_else( + || Some(PathBuf::from(&arg_ssh_key_path)), + |ssh_key_path| { + dirs::home_dir().map(|home| { + home.join( + ssh_key_path + .strip_prefix('/') + .unwrap_or(ssh_key_path), + ) + }) + }, + ); let mut ssh_secret_key = ssh_key_abs_path .and_then(|p| read(p).ok()) @@ -93,8 +93,9 @@ impl CommitComponent { if let std::result::Result::Ok(password) = var("GITUI_SSH_KEY_PASSWORD") { - ssh_secret_key = ssh_secret_key - .and_then(|key| key.decrypt(password.as_bytes()).ok()) + ssh_secret_key = ssh_secret_key.and_then(|key| { + key.decrypt(password.as_bytes()).ok() + }); } Self { From c48d0a36a74a8c48d92e8a35231f640c3e2f8485 Mon Sep 17 00:00:00 2001 From: Antonio Yang Date: Tue, 13 Feb 2024 22:56:06 +0800 Subject: [PATCH 07/22] add option for ssh_secret_key --- src/app.rs | 5 +++++ src/args.rs | 36 +++++++++++++++++++++++++++++++++++- src/components/commit.rs | 33 ++------------------------------- src/main.rs | 4 ++++ 4 files changed, 46 insertions(+), 32 deletions(-) diff --git a/src/app.rs b/src/app.rs index 6fdfc42460..57e39504cf 100644 --- a/src/app.rs +++ b/src/app.rs @@ -32,6 +32,7 @@ use crate::{ }; use anyhow::{bail, Result}; use asyncgit::{ + ssh_key::private::PrivateKey, sync::{ self, utils::{repo_work_dir, undo_last_commit}, @@ -121,6 +122,7 @@ pub struct Environment { pub options: SharedOptions, pub sender_git: Sender, pub sender_app: Sender, + pub ssh_secret_key: Option, } /// The need to construct a "whatever" environment only arises in testing right now @@ -136,6 +138,7 @@ impl Environment { options: Rc::new(RefCell::new(Options::test_env())), sender_git: unbounded().0, sender_app: unbounded().0, + ssh_secret_key: None, } } } @@ -151,6 +154,7 @@ impl App { input: Input, theme: Theme, key_config: KeyConfig, + ssh_secret_key: Option, ) -> Result { log::trace!("open repo at: {:?}", &repo); @@ -165,6 +169,7 @@ impl App { repo, sender_git, sender_app, + ssh_secret_key, }; let tab = env.options.borrow().current_tab(); diff --git a/src/args.rs b/src/args.rs index 0a45fb2864..b2db50b163 100644 --- a/src/args.rs +++ b/src/args.rs @@ -1,5 +1,6 @@ use crate::bug_report; use anyhow::{anyhow, Result}; +use asyncgit::ssh_key::private::PrivateKey; use asyncgit::sync::RepoPath; use clap::{ crate_authors, crate_description, crate_name, crate_version, Arg, @@ -8,7 +9,7 @@ use clap::{ use simplelog::{Config, LevelFilter, WriteLogger}; use std::{ env, - fs::{self, File}, + fs::{self, read, File}, path::PathBuf, }; @@ -16,6 +17,7 @@ pub struct CliArgs { pub theme: PathBuf, pub repo_path: RepoPath, pub notify_watcher: bool, + pub ssh_secret_key: Option, } pub fn process_cmdline() -> Result { @@ -57,10 +59,34 @@ pub fn process_cmdline() -> Result { let notify_watcher: bool = *arg_matches.get_one("watcher").unwrap_or(&false); + let ssh_secret_key = { + let default_ssh_path = "~/.ssh/id_rsa".to_string(); + let arg_ssh_key_path = arg_matches + .get_one::("ssh_key_path") + .unwrap_or(&default_ssh_path); + let ssh_key_abs_path = + arg_ssh_key_path.strip_prefix('~').map_or_else( + || Some(PathBuf::from(&arg_ssh_key_path)), + |ssh_key_path| { + dirs::home_dir().map(|home| { + home.join( + ssh_key_path + .strip_prefix('/') + .unwrap_or(ssh_key_path), + ) + }) + }, + ); + ssh_key_abs_path + .and_then(|p| read(p).ok()) + .and_then(|bytes| PrivateKey::from_openssh(bytes).ok()) + }; + Ok(CliArgs { theme, repo_path, notify_watcher, + ssh_secret_key, }) } @@ -123,6 +149,14 @@ fn app() -> ClapApp { .env("GIT_WORK_TREE") .num_args(1), ) + .arg( + Arg::new("ssh_key_path") + .help("Set ssh secret key for sign commit") + .short('s') + .long("ssh-key-path") + .env("SSH_KEY_PATH") + .num_args(1), + ) } fn setup_logging() -> Result<()> { diff --git a/src/components/commit.rs b/src/components/commit.rs index 0011177861..ac8aa70c56 100644 --- a/src/components/commit.rs +++ b/src/components/commit.rs @@ -30,8 +30,7 @@ use ratatui::{ Frame, }; use std::{ - env::var, - fs::{read, read_to_string, File}, + fs::{read_to_string, File}, io::{Read, Write}, path::PathBuf, str::FromStr, @@ -70,34 +69,6 @@ const FIRST_LINE_LIMIT: usize = 50; impl CommitComponent { /// pub fn new(env: &Environment) -> Self { - let arg_ssh_key_path = var("GITUI_SSH_KEY_PATH") - .unwrap_or_else(|_| "~/.ssh/id_rsa".to_string()); - - let ssh_key_abs_path = - arg_ssh_key_path.strip_prefix('~').map_or_else( - || Some(PathBuf::from(&arg_ssh_key_path)), - |ssh_key_path| { - dirs::home_dir().map(|home| { - home.join( - ssh_key_path - .strip_prefix('/') - .unwrap_or(ssh_key_path), - ) - }) - }, - ); - - let mut ssh_secret_key = ssh_key_abs_path - .and_then(|p| read(p).ok()) - .and_then(|bytes| PrivateKey::from_openssh(bytes).ok()); - if let std::result::Result::Ok(password) = - var("GITUI_SSH_KEY_PASSWORD") - { - ssh_secret_key = ssh_secret_key.and_then(|key| { - key.decrypt(password.as_bytes()).ok() - }); - } - Self { queue: env.queue.clone(), mode: Mode::Normal, @@ -117,7 +88,7 @@ impl CommitComponent { commit_msg_history_idx: 0, options: env.options.clone(), verify: true, - ssh_secret_key, + ssh_secret_key: env.ssh_secret_key.clone(), } } diff --git a/src/main.rs b/src/main.rs index 0fb613911e..cb31955a5e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -51,6 +51,7 @@ use crate::{app::App, args::process_cmdline}; use anyhow::{bail, Result}; use app::QuitState; use asyncgit::{ + ssh_key::private::PrivateKey, sync::{utils::repo_work_dir, RepoPath}, AsyncGitNotification, }; @@ -162,6 +163,7 @@ fn main() -> Result<()> { &input, updater, &mut terminal, + cliargs.ssh_secret_key.clone(), )?; match quit_state { @@ -183,6 +185,7 @@ fn run_app( input: &Input, updater: Updater, terminal: &mut Terminal>, + ssh_secret_key: Option, ) -> Result { let (tx_git, rx_git) = unbounded(); let (tx_app, rx_app) = unbounded(); @@ -208,6 +211,7 @@ fn run_app( input.clone(), theme, key_config, + ssh_secret_key, )?; let mut spinner = Spinner::default(); From 1d84f61e384a4ec29fbb20bcf7b832f0f0b1d3e5 Mon Sep 17 00:00:00 2001 From: Antonio Yang Date: Tue, 13 Feb 2024 23:14:10 +0800 Subject: [PATCH 08/22] fix clippy --- src/args.rs | 1 + src/main.rs | 44 +++++++++++++++++++------------------------- 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/src/args.rs b/src/args.rs index b2db50b163..6c56190e14 100644 --- a/src/args.rs +++ b/src/args.rs @@ -13,6 +13,7 @@ use std::{ path::PathBuf, }; +#[derive(Clone)] pub struct CliArgs { pub theme: PathBuf, pub repo_path: RepoPath, diff --git a/src/main.rs b/src/main.rs index cb31955a5e..d46f59f264 100644 --- a/src/main.rs +++ b/src/main.rs @@ -47,11 +47,13 @@ mod ui; mod version; mod watcher; -use crate::{app::App, args::process_cmdline}; +use crate::{ + app::App, + args::{process_cmdline, CliArgs}, +}; use anyhow::{bail, Result}; use app::QuitState; use asyncgit::{ - ssh_key::private::PrivateKey, sync::{utils::repo_work_dir, RepoPath}, AsyncGitNotification, }; @@ -131,12 +133,6 @@ fn main() -> Result<()> { if !valid_path(&cliargs.repo_path) { bail!("invalid path\nplease run gitui inside of a non-bare git repository"); } - - let key_config = KeyConfig::init() - .map_err(|e| eprintln!("KeyConfig loading error: {e}")) - .unwrap_or_default(); - let theme = Theme::init(&cliargs.theme); - setup_terminal()?; defer! { shutdown_terminal(); @@ -145,25 +141,16 @@ fn main() -> Result<()> { set_panic_handlers()?; let mut terminal = start_terminal(io::stdout())?; - let mut repo_path = cliargs.repo_path; + let mut repo_path = cliargs.repo_path.clone(); let input = Input::new(); - let updater = if cliargs.notify_watcher { - Updater::NotifyWatcher - } else { - Updater::Ticker - }; - loop { let quit_state = run_app( app_start, - repo_path.clone(), - theme.clone(), - key_config.clone(), + repo_path, &input, - updater, &mut terminal, - cliargs.ssh_secret_key.clone(), + cliargs.clone(), )?; match quit_state { @@ -180,13 +167,20 @@ fn main() -> Result<()> { fn run_app( app_start: Instant, repo: RepoPath, - theme: Theme, - key_config: KeyConfig, input: &Input, - updater: Updater, terminal: &mut Terminal>, - ssh_secret_key: Option, + cliargs: CliArgs, ) -> Result { + let key_config = KeyConfig::init() + .map_err(|e| eprintln!("KeyConfig loading error: {e}")) + .unwrap_or_default(); + let theme = Theme::init(&cliargs.theme); + let updater = if cliargs.notify_watcher { + Updater::NotifyWatcher + } else { + Updater::Ticker + }; + let (tx_git, rx_git) = unbounded(); let (tx_app, rx_app) = unbounded(); @@ -211,7 +205,7 @@ fn run_app( input.clone(), theme, key_config, - ssh_secret_key, + cliargs.ssh_secret_key, )?; let mut spinner = Spinner::default(); From d82ff46eacaaf585a750ac6bd83e2f9c47f671d8 Mon Sep 17 00:00:00 2001 From: Antonio Yang Date: Thu, 15 Feb 2024 22:27:20 +0800 Subject: [PATCH 09/22] use gitconfig user.signingKey to sign commit --- Cargo.lock | 1 + asyncgit/Cargo.toml | 1 + asyncgit/src/sync/blame.rs | 8 ++-- asyncgit/src/sync/commit.rs | 60 +++++++++++++++++++++-------- asyncgit/src/sync/commit_details.rs | 2 +- asyncgit/src/sync/commit_files.rs | 4 +- asyncgit/src/sync/commit_revert.rs | 4 +- asyncgit/src/sync/commits_info.rs | 11 +++--- asyncgit/src/sync/diff.rs | 6 +-- asyncgit/src/sync/logwalker.rs | 17 ++++---- asyncgit/src/sync/mod.rs | 1 - asyncgit/src/sync/remotes/push.rs | 4 -- asyncgit/src/sync/reset.rs | 2 +- asyncgit/src/sync/stash.rs | 2 +- asyncgit/src/sync/utils.rs | 2 +- src/app.rs | 5 --- src/args.rs | 36 +---------------- src/components/commit.rs | 17 ++------ src/main.rs | 39 ++++++++++--------- 19 files changed, 97 insertions(+), 125 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 57c19ddc4f..765ef16f94 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -136,6 +136,7 @@ version = "0.24.3" dependencies = [ "bitflags 2.4.2", "crossbeam-channel", + "dirs", "easy-cast", "env_logger", "fuzzy-matcher", diff --git a/asyncgit/Cargo.toml b/asyncgit/Cargo.toml index bd1dc03a36..f9bd7580b1 100644 --- a/asyncgit/Cargo.toml +++ b/asyncgit/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["git"] [dependencies] bitflags = "2" crossbeam-channel = "0.5" +dirs = "5.0" easy-cast = "0.5" fuzzy-matcher = "0.3" git2 = "0.18" diff --git a/asyncgit/src/sync/blame.rs b/asyncgit/src/sync/blame.rs index 9ff0e5259f..92edc991d0 100644 --- a/asyncgit/src/sync/blame.rs +++ b/asyncgit/src/sync/blame.rs @@ -175,7 +175,7 @@ mod tests { File::create(root.join(file_path))?.write_all(b"line 1\n")?; stage_add_file(repo_path, file_path)?; - commit(repo_path, "first commit", None)?; + commit(repo_path, "first commit")?; let blame = blame_file(repo_path, "foo", None)?; @@ -199,7 +199,7 @@ mod tests { file.write(b"line 2\n")?; stage_add_file(repo_path, file_path)?; - commit(repo_path, "second commit", None)?; + commit(repo_path, "second commit")?; let blame = blame_file(repo_path, "foo", None)?; @@ -233,7 +233,7 @@ mod tests { assert_eq!(blame.lines.len(), 2); stage_add_file(repo_path, file_path)?; - commit(repo_path, "third commit", None)?; + commit(repo_path, "third commit")?; let blame = blame_file(repo_path, "foo", None)?; @@ -258,7 +258,7 @@ mod tests { .unwrap(); stage_add_file(repo_path, file_path).unwrap(); - commit(repo_path, "first commit", None).unwrap(); + commit(repo_path, "first commit").unwrap(); assert!(blame_file(repo_path, "bar\\foo", None).is_ok()); } diff --git a/asyncgit/src/sync/commit.rs b/asyncgit/src/sync/commit.rs index 5f89c0e5bc..4c5f7a4ed5 100644 --- a/asyncgit/src/sync/commit.rs +++ b/asyncgit/src/sync/commit.rs @@ -6,6 +6,7 @@ use crate::{ use git2::{ErrorCode, ObjectType, Repository, Signature}; use scopetime::scope_time; use ssh_key::{HashAlg, LineEnding, PrivateKey}; +use std::path::PathBuf; /// pub fn amend( @@ -62,15 +63,42 @@ pub(crate) fn signature_allow_undefined_name( } /// this does not run any git hooks, git-hooks have to be executed manually, checkout `hooks_commit_msg` for example -/// If ssh private key is provided, the commit will be signed. -pub fn commit( - repo_path: &RepoPath, - msg: &str, - sk: Option<&PrivateKey>, -) -> Result { +pub fn commit(repo_path: &RepoPath, msg: &str) -> Result { scope_time!("commit"); let repo = repo(repo_path)?; + let ssh_secret_key = { + let config = repo.config()?; + config + .get_entry("user.signingKey") + .ok() + .and_then(|entry| { + entry.value().map(|key_path| { + key_path.strip_prefix('~').map_or_else( + || Some(PathBuf::from(&key_path)), + |ssh_key_path| { + dirs::home_dir().map(|home| { + home.join( + ssh_key_path + .strip_prefix('/') + .unwrap_or(ssh_key_path), + ) + }) + }, + ) + }) + }) + .and_then(|key_file| { + key_file + .and_then(|mut p| { + p.set_extension(""); + std::fs::read(p).ok() + }) + .and_then(|bytes| { + PrivateKey::from_openssh(bytes).ok() + }) + }) + }; let signature = signature_allow_undefined_name(&repo)?; let mut index = repo.index()?; @@ -84,7 +112,7 @@ pub fn commit( }; let parents = parents.iter().collect::>(); - if let Some(sk) = sk { + if let Some(sk) = ssh_secret_key { let buffer = repo.commit_create_buffer( &signature, &signature, @@ -197,7 +225,7 @@ mod tests { assert_eq!(get_statuses(repo_path), (0, 1)); - commit(repo_path, "commit msg", None).unwrap(); + commit(repo_path, "commit msg").unwrap(); assert_eq!(get_statuses(repo_path), (0, 0)); } @@ -223,7 +251,7 @@ mod tests { assert_eq!(get_statuses(repo_path), (0, 1)); - commit(repo_path, "commit msg", None).unwrap(); + commit(repo_path, "commit msg").unwrap(); assert_eq!(get_statuses(repo_path), (0, 0)); } @@ -240,7 +268,7 @@ mod tests { File::create(root.join(file_path1))?.write_all(b"test1")?; stage_add_file(repo_path, file_path1)?; - let id = commit(repo_path, "commit msg", None)?; + let id = commit(repo_path, "commit msg")?; assert_eq!(count_commits(&repo, 10), 1); @@ -279,7 +307,7 @@ mod tests { stage_add_file(repo_path, file_path)?; - let new_id = commit(repo_path, "commit msg", None)?; + let new_id = commit(repo_path, "commit msg")?; tag_commit(repo_path, &new_id, "tag", None)?; @@ -321,7 +349,7 @@ mod tests { stage_add_file(repo_path, file_path)?; - let new_id = commit(repo_path, "commit msg", None)?; + let new_id = commit(repo_path, "commit msg")?; tag_commit(repo_path, &new_id, "tag", Some("tag-message"))?; @@ -357,13 +385,13 @@ mod tests { repo.config()?.remove("user.email")?; - let error = commit(repo_path, "commit msg", None); + let error = commit(repo_path, "commit msg"); assert!(matches!(error, Err(_))); repo.config()?.set_str("user.email", "email")?; - let success = commit(repo_path, "commit msg", None); + let success = commit(repo_path, "commit msg"); assert!(matches!(success, Ok(_))); assert_eq!(count_commits(&repo, 10), 1); @@ -393,7 +421,7 @@ mod tests { repo.config()?.remove("user.name")?; - let mut success = commit(repo_path, "commit msg", None); + let mut success = commit(repo_path, "commit msg"); assert!(matches!(success, Ok(_))); assert_eq!(count_commits(&repo, 10), 1); @@ -406,7 +434,7 @@ mod tests { repo.config()?.set_str("user.name", "name")?; - success = commit(repo_path, "commit msg", None); + success = commit(repo_path, "commit msg"); assert!(matches!(success, Ok(_))); assert_eq!(count_commits(&repo, 10), 2); diff --git a/asyncgit/src/sync/commit_details.rs b/asyncgit/src/sync/commit_details.rs index 4b516b1f12..8de0894b71 100644 --- a/asyncgit/src/sync/commit_details.rs +++ b/asyncgit/src/sync/commit_details.rs @@ -144,7 +144,7 @@ mod tests { stage_add_file(repo_path, file_path).unwrap(); let msg = invalidstring::invalid_utf8("test msg"); - let id = commit(repo_path, msg.as_str(), None).unwrap(); + let id = commit(repo_path, msg.as_str()).unwrap(); let res = get_commit_details(repo_path, id).unwrap(); diff --git a/asyncgit/src/sync/commit_files.rs b/asyncgit/src/sync/commit_files.rs index 4d7f287134..d5927cc9ca 100644 --- a/asyncgit/src/sync/commit_files.rs +++ b/asyncgit/src/sync/commit_files.rs @@ -209,7 +209,7 @@ mod tests { stage_add_file(repo_path, file_path)?; - let id = commit(repo_path, "commit msg", None)?; + let id = commit(repo_path, "commit msg")?; let diff = get_commit_files(repo_path, id, None)?; @@ -251,7 +251,7 @@ mod tests { File::create(root.join(file_path1))?.write_all(b"test")?; stage_add_file(repo_path, file_path1)?; - commit(repo_path, "c1", None)?; + commit(repo_path, "c1")?; File::create(root.join(file_path1))? .write_all(b"modified")?; diff --git a/asyncgit/src/sync/commit_revert.rs b/asyncgit/src/sync/commit_revert.rs index 75faa54dc9..2d66a2a1d4 100644 --- a/asyncgit/src/sync/commit_revert.rs +++ b/asyncgit/src/sync/commit_revert.rs @@ -4,7 +4,6 @@ use crate::{ sync::{repository::repo, utils::read_file}, }; use scopetime::scope_time; -use ssh_key::PrivateKey; const GIT_REVERT_HEAD_FILE: &str = "REVERT_HEAD"; @@ -41,11 +40,10 @@ pub fn revert_head(repo_path: &RepoPath) -> Result { pub fn commit_revert( repo_path: &RepoPath, msg: &str, - sk: Option<&PrivateKey>, ) -> Result { scope_time!("commit_revert"); - let id = crate::sync::commit(repo_path, msg, sk)?; + let id = crate::sync::commit(repo_path, msg)?; repo(repo_path)?.cleanup_state()?; diff --git a/asyncgit/src/sync/commits_info.rs b/asyncgit/src/sync/commits_info.rs index f813fb7c10..1f049e9003 100644 --- a/asyncgit/src/sync/commits_info.rs +++ b/asyncgit/src/sync/commits_info.rs @@ -172,10 +172,10 @@ mod tests { File::create(root.join(file_path))?.write_all(b"a")?; stage_add_file(repo_path, file_path).unwrap(); - let c1 = commit(repo_path, "commit1", None).unwrap(); + let c1 = commit(repo_path, "commit1").unwrap(); File::create(root.join(file_path))?.write_all(b"a")?; stage_add_file(repo_path, file_path).unwrap(); - let c2 = commit(repo_path, "commit2", None).unwrap(); + let c2 = commit(repo_path, "commit2").unwrap(); let res = get_commits_info(repo_path, &[c2, c1], 50).unwrap(); @@ -197,7 +197,7 @@ mod tests { File::create(root.join(file_path))?.write_all(b"a")?; stage_add_file(repo_path, file_path).unwrap(); - let c1 = commit(repo_path, "subject\nbody", None).unwrap(); + let c1 = commit(repo_path, "subject\nbody").unwrap(); let res = get_commits_info(repo_path, &[c1], 50).unwrap(); @@ -219,7 +219,7 @@ mod tests { stage_add_file(repo_path, file_path).unwrap(); let msg = invalidstring::invalid_utf8("test msg"); - commit(repo_path, msg.as_str(), None).unwrap(); + commit(repo_path, msg.as_str()).unwrap(); let res = get_commits_info( repo_path, @@ -245,8 +245,7 @@ mod tests { let foo_file = Path::new("foo"); File::create(root.join(foo_file))?.write_all(b"a")?; stage_add_file(repo_path, foo_file).unwrap(); - let c1 = - commit(repo_path, "subject: foo\nbody", None).unwrap(); + let c1 = commit(repo_path, "subject: foo\nbody").unwrap(); let c1_rev = c1.get_short_string(); assert_eq!( diff --git a/asyncgit/src/sync/diff.rs b/asyncgit/src/sync/diff.rs index 50ba7dd035..60b8735ad3 100644 --- a/asyncgit/src/sync/diff.rs +++ b/asyncgit/src/sync/diff.rs @@ -597,7 +597,7 @@ mod tests { stage_add_file(repo_path, file_path).unwrap(); - commit(repo_path, "commit", None).unwrap(); + commit(repo_path, "commit").unwrap(); File::create(root.join(file_path))?.write_all(b"\x00\x02")?; @@ -653,13 +653,13 @@ mod tests { stage_add_file(repo_path, file_path).unwrap(); - commit(repo_path, "", None).unwrap(); + commit(repo_path, "").unwrap(); File::create(root.join(file_path))?.write_all(b"\x00\x02")?; stage_add_file(repo_path, file_path).unwrap(); - let id = commit(repo_path, "", None).unwrap(); + let id = commit(repo_path, "").unwrap(); let diff = get_diff_commit(repo_path, id, String::new(), None) diff --git a/asyncgit/src/sync/logwalker.rs b/asyncgit/src/sync/logwalker.rs index a0eb33b2d6..b13a9e5a26 100644 --- a/asyncgit/src/sync/logwalker.rs +++ b/asyncgit/src/sync/logwalker.rs @@ -135,10 +135,10 @@ mod tests { File::create(root.join(file_path))?.write_all(b"a")?; stage_add_file(repo_path, file_path).unwrap(); - commit(repo_path, "commit1", None).unwrap(); + commit(repo_path, "commit1").unwrap(); File::create(root.join(file_path))?.write_all(b"a")?; stage_add_file(repo_path, file_path).unwrap(); - let oid2 = commit(repo_path, "commit2", None).unwrap(); + let oid2 = commit(repo_path, "commit2").unwrap(); let mut items = Vec::new(); let mut walk = LogWalker::new(&repo, 1)?; @@ -160,10 +160,10 @@ mod tests { File::create(root.join(file_path))?.write_all(b"a")?; stage_add_file(repo_path, file_path).unwrap(); - commit(repo_path, "commit1", None).unwrap(); + commit(repo_path, "commit1").unwrap(); File::create(root.join(file_path))?.write_all(b"a")?; stage_add_file(repo_path, file_path).unwrap(); - let oid2 = commit(repo_path, "commit2", None).unwrap(); + let oid2 = commit(repo_path, "commit2").unwrap(); let mut items = Vec::new(); let mut walk = LogWalker::new(&repo, 100)?; @@ -195,20 +195,17 @@ mod tests { File::create(root.join(file_path))?.write_all(b"a")?; stage_add_file(&repo_path, file_path).unwrap(); - let _first_commit_id = - commit(&repo_path, "commit1", None).unwrap(); + let _first_commit_id = commit(&repo_path, "commit1").unwrap(); File::create(root.join(second_file_path))?.write_all(b"a")?; stage_add_file(&repo_path, second_file_path).unwrap(); - let second_commit_id = - commit(&repo_path, "commit2", None).unwrap(); + let second_commit_id = commit(&repo_path, "commit2").unwrap(); File::create(root.join(file_path))?.write_all(b"b")?; stage_add_file(&repo_path, file_path).unwrap(); - let _third_commit_id = - commit(&repo_path, "commit3", None).unwrap(); + let _third_commit_id = commit(&repo_path, "commit3").unwrap(); let diff_contains_baz = diff_contains_file("baz".into()); diff --git a/asyncgit/src/sync/mod.rs b/asyncgit/src/sync/mod.rs index 8285129de2..83683a9ea0 100644 --- a/asyncgit/src/sync/mod.rs +++ b/asyncgit/src/sync/mod.rs @@ -162,7 +162,6 @@ mod tests { commit( &repo.workdir().unwrap().to_str().unwrap().into(), commit_name, - None, ) .unwrap() } diff --git a/asyncgit/src/sync/remotes/push.rs b/asyncgit/src/sync/remotes/push.rs index a48c1d369a..37cdd4a9ca 100644 --- a/asyncgit/src/sync/remotes/push.rs +++ b/asyncgit/src/sync/remotes/push.rs @@ -226,7 +226,6 @@ mod tests { sync::commit( &tmp_repo_dir.path().to_str().unwrap().into(), "repo_1_commit", - None, ) .unwrap(); @@ -250,7 +249,6 @@ mod tests { sync::commit( &tmp_other_repo_dir.path().to_str().unwrap().into(), "repo_2_commit", - None, ) .unwrap(); @@ -325,7 +323,6 @@ mod tests { let repo_1_commit = sync::commit( &tmp_repo_dir.path().to_str().unwrap().into(), "repo_1_commit", - None, ) .unwrap(); @@ -370,7 +367,6 @@ mod tests { let repo_2_commit = sync::commit( &tmp_other_repo_dir.path().to_str().unwrap().into(), "repo_2_commit", - None, ) .unwrap(); diff --git a/asyncgit/src/sync/reset.rs b/asyncgit/src/sync/reset.rs index 518fd11e03..4142255954 100644 --- a/asyncgit/src/sync/reset.rs +++ b/asyncgit/src/sync/reset.rs @@ -189,7 +189,7 @@ mod tests { } stage_add_all(repo_path, "*", None).unwrap(); - commit(repo_path, "msg", None).unwrap(); + commit(repo_path, "msg").unwrap(); { File::create(root.join("foo/file1.txt"))? diff --git a/asyncgit/src/sync/stash.rs b/asyncgit/src/sync/stash.rs index da67e0ecfe..fc5d69b73d 100644 --- a/asyncgit/src/sync/stash.rs +++ b/asyncgit/src/sync/stash.rs @@ -222,7 +222,7 @@ mod tests { File::create(root.join(file_path1))?.write_all(b"test")?; stage_add_file(repo_path, file_path1)?; - commit(repo_path, "c1", None)?; + commit(repo_path, "c1")?; File::create(root.join(file_path1))? .write_all(b"modified")?; diff --git a/asyncgit/src/sync/utils.rs b/asyncgit/src/sync/utils.rs index fc82508524..a5ec1b3e9b 100644 --- a/asyncgit/src/sync/utils.rs +++ b/asyncgit/src/sync/utils.rs @@ -388,7 +388,7 @@ mod tests { stage_add_file(repo_path, file_path).unwrap(); - commit(repo_path, "commit msg", None).unwrap(); + commit(repo_path, "commit msg").unwrap(); // delete the file now assert_eq!(remove_file(full_path).is_ok(), true); diff --git a/src/app.rs b/src/app.rs index 57e39504cf..6fdfc42460 100644 --- a/src/app.rs +++ b/src/app.rs @@ -32,7 +32,6 @@ use crate::{ }; use anyhow::{bail, Result}; use asyncgit::{ - ssh_key::private::PrivateKey, sync::{ self, utils::{repo_work_dir, undo_last_commit}, @@ -122,7 +121,6 @@ pub struct Environment { pub options: SharedOptions, pub sender_git: Sender, pub sender_app: Sender, - pub ssh_secret_key: Option, } /// The need to construct a "whatever" environment only arises in testing right now @@ -138,7 +136,6 @@ impl Environment { options: Rc::new(RefCell::new(Options::test_env())), sender_git: unbounded().0, sender_app: unbounded().0, - ssh_secret_key: None, } } } @@ -154,7 +151,6 @@ impl App { input: Input, theme: Theme, key_config: KeyConfig, - ssh_secret_key: Option, ) -> Result { log::trace!("open repo at: {:?}", &repo); @@ -169,7 +165,6 @@ impl App { repo, sender_git, sender_app, - ssh_secret_key, }; let tab = env.options.borrow().current_tab(); diff --git a/src/args.rs b/src/args.rs index 6c56190e14..634318e8e8 100644 --- a/src/args.rs +++ b/src/args.rs @@ -1,6 +1,5 @@ use crate::bug_report; use anyhow::{anyhow, Result}; -use asyncgit::ssh_key::private::PrivateKey; use asyncgit::sync::RepoPath; use clap::{ crate_authors, crate_description, crate_name, crate_version, Arg, @@ -9,7 +8,7 @@ use clap::{ use simplelog::{Config, LevelFilter, WriteLogger}; use std::{ env, - fs::{self, read, File}, + fs::{self, File}, path::PathBuf, }; @@ -18,7 +17,6 @@ pub struct CliArgs { pub theme: PathBuf, pub repo_path: RepoPath, pub notify_watcher: bool, - pub ssh_secret_key: Option, } pub fn process_cmdline() -> Result { @@ -60,34 +58,10 @@ pub fn process_cmdline() -> Result { let notify_watcher: bool = *arg_matches.get_one("watcher").unwrap_or(&false); - let ssh_secret_key = { - let default_ssh_path = "~/.ssh/id_rsa".to_string(); - let arg_ssh_key_path = arg_matches - .get_one::("ssh_key_path") - .unwrap_or(&default_ssh_path); - let ssh_key_abs_path = - arg_ssh_key_path.strip_prefix('~').map_or_else( - || Some(PathBuf::from(&arg_ssh_key_path)), - |ssh_key_path| { - dirs::home_dir().map(|home| { - home.join( - ssh_key_path - .strip_prefix('/') - .unwrap_or(ssh_key_path), - ) - }) - }, - ); - ssh_key_abs_path - .and_then(|p| read(p).ok()) - .and_then(|bytes| PrivateKey::from_openssh(bytes).ok()) - }; - Ok(CliArgs { theme, repo_path, notify_watcher, - ssh_secret_key, }) } @@ -150,14 +124,6 @@ fn app() -> ClapApp { .env("GIT_WORK_TREE") .num_args(1), ) - .arg( - Arg::new("ssh_key_path") - .help("Set ssh secret key for sign commit") - .short('s') - .long("ssh-key-path") - .env("SSH_KEY_PATH") - .num_args(1), - ) } fn setup_logging() -> Result<()> { diff --git a/src/components/commit.rs b/src/components/commit.rs index ac8aa70c56..60365eee6f 100644 --- a/src/components/commit.rs +++ b/src/components/commit.rs @@ -14,7 +14,6 @@ use crate::{ use anyhow::{bail, Ok, Result}; use asyncgit::{ cached, message_prettify, - ssh_key::private::PrivateKey, sync::{ self, get_config_string, CommitId, HookResult, PrepareCommitMsgSource, RepoPathRef, RepoState, @@ -61,7 +60,6 @@ pub struct CommitComponent { commit_msg_history_idx: usize, options: SharedOptions, verify: bool, - ssh_secret_key: Option, } const FIRST_LINE_LIMIT: usize = 50; @@ -88,7 +86,6 @@ impl CommitComponent { commit_msg_history_idx: 0, options: env.options.clone(), verify: true, - ssh_secret_key: env.ssh_secret_key.clone(), } } @@ -287,22 +284,16 @@ impl CommitComponent { fn do_commit(&self, msg: &str) -> Result<()> { match &self.mode { - Mode::Normal => sync::commit( - &self.repo.borrow(), - msg, - self.ssh_secret_key.as_ref(), - )?, + Mode::Normal => sync::commit(&self.repo.borrow(), msg)?, Mode::Amend(amend) => { sync::amend(&self.repo.borrow(), *amend, msg)? } Mode::Merge(ids) => { sync::merge_commit(&self.repo.borrow(), msg, ids)? } - Mode::Revert => sync::commit_revert( - &self.repo.borrow(), - msg, - self.ssh_secret_key.as_ref(), - )?, + Mode::Revert => { + sync::commit_revert(&self.repo.borrow(), msg)? + } Mode::Reword(id) => { let commit = sync::reword(&self.repo.borrow(), *id, msg)?; diff --git a/src/main.rs b/src/main.rs index d46f59f264..bb8c53b6bc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -47,10 +47,7 @@ mod ui; mod version; mod watcher; -use crate::{ - app::App, - args::{process_cmdline, CliArgs}, -}; +use crate::{app::App, args::process_cmdline}; use anyhow::{bail, Result}; use app::QuitState; use asyncgit::{ @@ -130,6 +127,11 @@ fn main() -> Result<()> { asyncgit::register_tracing_logging(); + let key_config = KeyConfig::init() + .map_err(|e| eprintln!("KeyConfig loading error: {e}")) + .unwrap_or_default(); + let theme = Theme::init(&cliargs.theme); + if !valid_path(&cliargs.repo_path) { bail!("invalid path\nplease run gitui inside of a non-bare git repository"); } @@ -141,16 +143,24 @@ fn main() -> Result<()> { set_panic_handlers()?; let mut terminal = start_terminal(io::stdout())?; - let mut repo_path = cliargs.repo_path.clone(); + let mut repo_path = cliargs.repo_path; let input = Input::new(); + let updater = if cliargs.notify_watcher { + Updater::NotifyWatcher + } else { + Updater::Ticker + }; + loop { let quit_state = run_app( app_start, - repo_path, + repo_path.clone(), + theme.clone(), + key_config.clone(), &input, + updater, &mut terminal, - cliargs.clone(), )?; match quit_state { @@ -167,20 +177,12 @@ fn main() -> Result<()> { fn run_app( app_start: Instant, repo: RepoPath, + theme: Theme, + key_config: KeyConfig, input: &Input, + updater: Updater, terminal: &mut Terminal>, - cliargs: CliArgs, ) -> Result { - let key_config = KeyConfig::init() - .map_err(|e| eprintln!("KeyConfig loading error: {e}")) - .unwrap_or_default(); - let theme = Theme::init(&cliargs.theme); - let updater = if cliargs.notify_watcher { - Updater::NotifyWatcher - } else { - Updater::Ticker - }; - let (tx_git, rx_git) = unbounded(); let (tx_app, rx_app) = unbounded(); @@ -205,7 +207,6 @@ fn run_app( input.clone(), theme, key_config, - cliargs.ssh_secret_key, )?; let mut spinner = Spinner::default(); From 871424f650af6b27639c976ad0b4ad77da33c5fa Mon Sep 17 00:00:00 2001 From: Antonio Yang Date: Thu, 15 Feb 2024 22:34:56 +0800 Subject: [PATCH 10/22] update CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aec61fe202..aac94e0c92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * `theme.ron` now supports customizing line break symbol ([#1894](https://github.com/extrawurst/gitui/issues/1894)) * add confirmation for dialog for undo commit [[@TeFiLeDo](https://github.com/TeFiLeDo)] ([#1912](https://github.com/extrawurst/gitui/issues/1912)) * support `prepare-commit-msg` hook ([#1873](https://github.com/extrawurst/gitui/issues/1873)) -* support sign commit with ssh key by `GITUI_SSH_KEY_PATH` and `GITUI_SSH_PASSWORD`([#1149](https://github.com/extrawurst/gitui/issues/1149)) +* support sign commit with ssh key by `user.signingKey` of gitconfig ([#1149](https://github.com/extrawurst/gitui/issues/1149)) ### Changed * do not allow tag when `tag.gpgsign` enabled [[@TeFiLeDo](https://github.com/TeFiLeDo)] ([#1915](https://github.com/extrawurst/gitui/pull/1915)) From 1a0caddf893155fbebb046941ac9f4639a644f28 Mon Sep 17 00:00:00 2001 From: Antonio Yang Date: Thu, 15 Feb 2024 22:56:14 +0800 Subject: [PATCH 11/22] fix cargo deny config --- .cargo/audit.toml | 4 ---- deny.toml | 5 +++++ 2 files changed, 5 insertions(+), 4 deletions(-) delete mode 100644 .cargo/audit.toml diff --git a/.cargo/audit.toml b/.cargo/audit.toml deleted file mode 100644 index 37f7153733..0000000000 --- a/.cargo/audit.toml +++ /dev/null @@ -1,4 +0,0 @@ -[advisories] -# No fix for RSA, and this is a dependency from ssh_key crate to handle rsa ssh key. -# https://rustsec.org/advisories/RUSTSEC-2023-0071 -ignore = ["RUSTSEC-2023-0071"] diff --git a/deny.toml b/deny.toml index 87800fb0ea..cfe927f7d1 100644 --- a/deny.toml +++ b/deny.toml @@ -14,6 +14,11 @@ allow-osi-fsf-free = "neither" default = "deny" confidence-threshold = 0.9 +[advisories] +# No fix for RSA, and this is a dependency from ssh_key crate to handle rsa ssh key. +# https://rustsec.org/advisories/RUSTSEC-2023-0071 +ignore = ["RUSTSEC-2023-0071"] + [[licenses.exceptions]] allow = ["Unicode-DFS-2016"] name = "unicode-ident" From 9904ba070e5d1c07d1efe0067017cac136ccd28e Mon Sep 17 00:00:00 2001 From: Antonio Yang Date: Thu, 15 Feb 2024 23:04:59 +0800 Subject: [PATCH 12/22] clean up unnecessary changes --- src/args.rs | 1 - src/main.rs | 7 ++++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/args.rs b/src/args.rs index 634318e8e8..0a45fb2864 100644 --- a/src/args.rs +++ b/src/args.rs @@ -12,7 +12,6 @@ use std::{ path::PathBuf, }; -#[derive(Clone)] pub struct CliArgs { pub theme: PathBuf, pub repo_path: RepoPath, diff --git a/src/main.rs b/src/main.rs index bb8c53b6bc..0fb613911e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -127,14 +127,15 @@ fn main() -> Result<()> { asyncgit::register_tracing_logging(); + if !valid_path(&cliargs.repo_path) { + bail!("invalid path\nplease run gitui inside of a non-bare git repository"); + } + let key_config = KeyConfig::init() .map_err(|e| eprintln!("KeyConfig loading error: {e}")) .unwrap_or_default(); let theme = Theme::init(&cliargs.theme); - if !valid_path(&cliargs.repo_path) { - bail!("invalid path\nplease run gitui inside of a non-bare git repository"); - } setup_terminal()?; defer! { shutdown_terminal(); From 6df89c12ca73f77b38abdb61f94ae9712a9fb814 Mon Sep 17 00:00:00 2001 From: Antonio Yang Date: Thu, 15 Feb 2024 23:12:57 +0800 Subject: [PATCH 13/22] drop unnecessary export --- asyncgit/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/asyncgit/src/lib.rs b/asyncgit/src/lib.rs index c1149a4371..dc75de9d52 100644 --- a/asyncgit/src/lib.rs +++ b/asyncgit/src/lib.rs @@ -76,7 +76,6 @@ pub use crate::{ treefiles::AsyncTreeFilesJob, }; pub use git2::message_prettify; -pub use ssh_key; use std::{ collections::hash_map::DefaultHasher, hash::{Hash, Hasher}, From 491405b9c3bb41774489e2d05054e45bbcb28c0c Mon Sep 17 00:00:00 2001 From: Antonio Yang Date: Tue, 20 Feb 2024 10:12:14 +0800 Subject: [PATCH 14/22] update CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ee63efbb2..d304074de2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,7 @@ These defaults require some adoption from existing users but feel more natural t * support `prepare-commit-msg` hook ([#1873](https://github.com/extrawurst/gitui/issues/1873)) * support for new-line in text-input (e.g. commit message editor) [[@pm100]](https://github/pm100) ([#1662](https://github.com/extrawurst/gitui/issues/1662)). * new style `block_title_focused` to allow customizing title text of focused frame/block ([#2052](https://github.com/extrawurst/gitui/issues/2052)). -* support sign commit with ssh key by `user.signingKey` of gitconfig ([#1149](https://github.com/extrawurst/gitui/issues/1149)) +* support sign commit with ssh key in disk by `user.signingKey` of gitconfig (ssh-agent/`SSH_AUTH_SOCK` isn't yet supported) ([#1149](https://github.com/extrawurst/gitui/issues/1149)) ### Changed * do not allow tagging when `tag.gpgsign` enabled until gpg-signing is [supported](https://github.com/extrawurst/gitui/issues/97) [[@TeFiLeDo](https://github.com/TeFiLeDo)] ([#1915](https://github.com/extrawurst/gitui/pull/1915)) From ed46cb16acc90f38f3e19021b5ec8f5a88882911 Mon Sep 17 00:00:00 2001 From: Antonio Yang Date: Tue, 20 Feb 2024 10:46:30 +0800 Subject: [PATCH 15/22] allow BSD-3-Clause licenses --- deny.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deny.toml b/deny.toml index ca863ab88c..d42a3f8dae 100644 --- a/deny.toml +++ b/deny.toml @@ -1,6 +1,6 @@ [licenses] unlicensed = "deny" -allow = ["MIT", "Apache-2.0", "BSD-2-Clause", "CC0-1.0", "ISC", "MPL-2.0"] +allow = ["MIT", "Apache-2.0", "BSD-2-Clause", "BSD-3-Clause", "CC0-1.0", "ISC", "MPL-2.0"] copyleft = "warn" default = "deny" From b8b528448bc4958637c76db313286169a8394c74 Mon Sep 17 00:00:00 2001 From: Antonio Yang Date: Wed, 21 Feb 2024 00:06:07 +0800 Subject: [PATCH 16/22] split `fetch_ssh_key` into `fn` --- asyncgit/src/sync/commit.rs | 70 ++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/asyncgit/src/sync/commit.rs b/asyncgit/src/sync/commit.rs index 4c5f7a4ed5..f25c58bc67 100644 --- a/asyncgit/src/sync/commit.rs +++ b/asyncgit/src/sync/commit.rs @@ -3,7 +3,7 @@ use crate::{ error::Result, sync::{repository::repo, utils::get_head_repo}, }; -use git2::{ErrorCode, ObjectType, Repository, Signature}; +use git2::{Config, ErrorCode, ObjectType, Repository, Signature}; use scopetime::scope_time; use ssh_key::{HashAlg, LineEnding, PrivateKey}; use std::path::PathBuf; @@ -62,43 +62,43 @@ pub(crate) fn signature_allow_undefined_name( signature } +fn fetch_ssh_key(config: &Config) -> Option { + config + .get_entry("user.signingKey") + .ok() + .and_then(|entry| { + entry.value().map(|key_path| { + key_path.strip_prefix('~').map_or_else( + || Some(PathBuf::from(&key_path)), + |ssh_key_path| { + dirs::home_dir().map(|home| { + home.join( + ssh_key_path + .strip_prefix('/') + .unwrap_or(ssh_key_path), + ) + }) + }, + ) + }) + }) + .and_then(|key_file| { + key_file + .and_then(|mut p| { + p.set_extension(""); + std::fs::read(p).ok() + }) + .and_then(|bytes| { + PrivateKey::from_openssh(bytes).ok() + }) + }) +} + /// this does not run any git hooks, git-hooks have to be executed manually, checkout `hooks_commit_msg` for example pub fn commit(repo_path: &RepoPath, msg: &str) -> Result { scope_time!("commit"); let repo = repo(repo_path)?; - let ssh_secret_key = { - let config = repo.config()?; - config - .get_entry("user.signingKey") - .ok() - .and_then(|entry| { - entry.value().map(|key_path| { - key_path.strip_prefix('~').map_or_else( - || Some(PathBuf::from(&key_path)), - |ssh_key_path| { - dirs::home_dir().map(|home| { - home.join( - ssh_key_path - .strip_prefix('/') - .unwrap_or(ssh_key_path), - ) - }) - }, - ) - }) - }) - .and_then(|key_file| { - key_file - .and_then(|mut p| { - p.set_extension(""); - std::fs::read(p).ok() - }) - .and_then(|bytes| { - PrivateKey::from_openssh(bytes).ok() - }) - }) - }; let signature = signature_allow_undefined_name(&repo)?; let mut index = repo.index()?; @@ -111,8 +111,9 @@ pub fn commit(repo_path: &RepoPath, msg: &str) -> Result { Vec::new() }; + let config = repo.config()?; let parents = parents.iter().collect::>(); - if let Some(sk) = ssh_secret_key { + if let Some(sk) = fetch_ssh_key(&config) { let buffer = repo.commit_create_buffer( &signature, &signature, @@ -128,7 +129,6 @@ pub fn commit(repo_path: &RepoPath, msg: &str) -> Result { if let Ok(mut head) = repo.head() { head.set_target(commit_id, msg)?; } else { - let config = repo.config()?; let default_branch_name = config .get_str("init.defaultBranch") .unwrap_or("master"); From ceb2e68a1c7a15676546f7c8855b4c3cd91e739f Mon Sep 17 00:00:00 2001 From: Antonio Yang Date: Wed, 21 Feb 2024 01:49:22 +0800 Subject: [PATCH 17/22] check gpg.format --- asyncgit/src/sync/commit.rs | 62 ++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/asyncgit/src/sync/commit.rs b/asyncgit/src/sync/commit.rs index f25c58bc67..7fcf139bff 100644 --- a/asyncgit/src/sync/commit.rs +++ b/asyncgit/src/sync/commit.rs @@ -113,35 +113,40 @@ pub fn commit(repo_path: &RepoPath, msg: &str) -> Result { let config = repo.config()?; let parents = parents.iter().collect::>(); - if let Some(sk) = fetch_ssh_key(&config) { - let buffer = repo.commit_create_buffer( - &signature, - &signature, - msg, - &tree, - parents.as_slice(), - )?; - let content = String::from_utf8(buffer.to_vec())?; - let sig = sk - .sign("git", HashAlg::Sha256, &buffer)? - .to_pem(LineEnding::LF)?; - let commit_id = repo.commit_signed(&content, &sig, None)?; - if let Ok(mut head) = repo.head() { - head.set_target(commit_id, msg)?; - } else { - let default_branch_name = config - .get_str("init.defaultBranch") - .unwrap_or("master"); - repo.reference( - &format!("refs/heads/{default_branch_name}"), - commit_id, - true, + let id = match ( + config.get_entry("gpg.format").ok(), + fetch_ssh_key(&config), + ) { + (Some(f), Some(sk)) if f.value() == Some("ssh") => { + let buffer = repo.commit_create_buffer( + &signature, + &signature, msg, + &tree, + parents.as_slice(), )?; + let content = String::from_utf8(buffer.to_vec())?; + let sig = sk + .sign("git", HashAlg::Sha256, &buffer)? + .to_pem(LineEnding::LF)?; + let commit_id = + repo.commit_signed(&content, &sig, None)?; + if let Ok(mut head) = repo.head() { + head.set_target(commit_id, msg)?; + } else { + let default_branch_name = config + .get_str("init.defaultBranch") + .unwrap_or("master"); + repo.reference( + &format!("refs/heads/{default_branch_name}"), + commit_id, + true, + msg, + )?; + } + Ok(commit_id.into()) } - Ok(commit_id.into()) - } else { - Ok(repo + _ => Ok(repo .commit( Some("HEAD"), &signature, @@ -150,8 +155,9 @@ pub fn commit(repo_path: &RepoPath, msg: &str) -> Result { &tree, parents.as_slice(), )? - .into()) - } + .into()), + }; + id } /// Tag a commit. From 7c3c106626502982e6eed09f02f89dc138cdb3d4 Mon Sep 17 00:00:00 2001 From: Antonio Yang Date: Wed, 21 Feb 2024 01:57:43 +0800 Subject: [PATCH 18/22] update CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1bf7883e75..e2c2c5a9da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,7 @@ These defaults require some adoption from existing users but feel more natural t * new style `block_title_focused` to allow customizing title text of focused frame/block ([#2052](https://github.com/extrawurst/gitui/issues/2052)). * add syntax highlighting for blame view [[@tdtrung17693](https://github.com/tdtrung17693)] ([#745](https://github.com/extrawurst/gitui/issues/745)) * allow `fetch` command in both tabs of branchlist popup ([#2067](https://github.com/extrawurst/gitui/issues/2067)) -* support sign commit with ssh key in disk by `user.signingKey` of gitconfig (ssh-agent/`SSH_AUTH_SOCK` isn't yet supported) ([#1149](https://github.com/extrawurst/gitui/issues/1149)) +* support sign commit with ssh key in disk by `user.signingKey` and `gpg.format = ssh` of gitconfig (ssh-agent/`SSH_AUTH_SOCK` isn't yet supported) ([#1149](https://github.com/extrawurst/gitui/issues/1149)) ### Changed * do not allow tagging when `tag.gpgsign` enabled until gpg-signing is [supported](https://github.com/extrawurst/gitui/issues/97) [[@TeFiLeDo](https://github.com/TeFiLeDo)] ([#1915](https://github.com/extrawurst/gitui/pull/1915)) From 083294c5c6606f2e0e5d35f4707c8c268d6fc7fb Mon Sep 17 00:00:00 2001 From: Antonio Yang Date: Thu, 22 Feb 2024 21:30:31 +0800 Subject: [PATCH 19/22] fix commit.gpgsign=ture allert when sshsign set --- src/popups/commit.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/popups/commit.rs b/src/popups/commit.rs index 2511d8b8ef..535d2fc144 100644 --- a/src/popups/commit.rs +++ b/src/popups/commit.rs @@ -210,8 +210,14 @@ impl CommitPopup { .and_then(|path| path.parse::().ok()) .unwrap_or_default(); - if gpgsign { - anyhow::bail!("config commit.gpgsign=true detected.\ngpg signing not supported.\ndeactivate in your repo/gitconfig to be able to commit without signing."); + let sshsign = + get_config_string(&self.repo.borrow(), "gpg.format") + .ok() + .flatten() + .unwrap_or_default(); + + if gpgsign && sshsign != "ssh" { + anyhow::bail!("config commit.gpgsign=true detected.\nonly gpg signing with ssh format supported.\ndeactivate in your repo/gitconfig to be able to commit without signing."); } let msg = self.input.get_text().to_string(); From 43bea2106d302241f522f03a1893a8d55468775b Mon Sep 17 00:00:00 2001 From: Antonio Yang Date: Mon, 4 Mar 2024 23:46:30 +0800 Subject: [PATCH 20/22] fix CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62c76eba7f..cf4355a768 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,7 +30,7 @@ These defaults require some adoption from existing users but feel more natural t * new style `block_title_focused` to allow customizing title text of focused frame/block ([#2052](https://github.com/extrawurst/gitui/issues/2052)). * allow `fetch` command in both tabs of branchlist popup ([#2067](https://github.com/extrawurst/gitui/issues/2067)) * check branch name validity while typing [[@sainad2222](https://github.com/sainad2222)] ([#2062](https://github.com/extrawurst/gitui/issues/2062)) -* support sign commit with ssh key in disk by `user.signingKey` and `gpg.format = ssh` of gitconfig (ssh-agent/`SSH_AUTH_SOCK` isn't yet supported) ([#1149](https://github.com/extrawurst/gitui/issues/1149)) +* support sign commits with ssh key in the disk when `user.signingKey` and `gpg.format = ssh` of gitconfig are set(ssh-agent/`SSH_AUTH_SOCK` isn't yet supported) ([#1149](https://github.com/extrawurst/gitui/issues/1149)) ### Changed * do not allow tagging when `tag.gpgsign` enabled until gpg-signing is [supported](https://github.com/extrawurst/gitui/issues/97) [[@TeFiLeDo](https://github.com/TeFiLeDo)] ([#1915](https://github.com/extrawurst/gitui/pull/1915)) From 411b93629156291252265763bfff1351e8f47082 Mon Sep 17 00:00:00 2001 From: Antonio Yang Date: Thu, 7 Mar 2024 22:55:01 +0800 Subject: [PATCH 21/22] disallow commit when ssh sign set but the key is not found in the disk --- src/popups/commit.rs | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/src/popups/commit.rs b/src/popups/commit.rs index 535d2fc144..5b2ce85121 100644 --- a/src/popups/commit.rs +++ b/src/popups/commit.rs @@ -215,9 +215,44 @@ impl CommitPopup { .ok() .flatten() .unwrap_or_default(); - - if gpgsign && sshsign != "ssh" { - anyhow::bail!("config commit.gpgsign=true detected.\nonly gpg signing with ssh format supported.\ndeactivate in your repo/gitconfig to be able to commit without signing."); + let signing_key = + get_config_string(&self.repo.borrow(), "user.signingKey") + .ok() + .flatten(); + + if gpgsign { + if sshsign == "ssh" { + if !signing_key + .map(|key_path| { + key_path + .strip_prefix('~') + .map_or_else( + || Some(PathBuf::from(&key_path)), + |ssh_key_path| { + dirs::home_dir().map(|home| { + home.join( + ssh_key_path + .strip_prefix('/') + .unwrap_or( + ssh_key_path, + ), + ) + }) + }, + ) + .map(|mut p| { + p.set_extension(""); + p.is_file() + }) + .unwrap_or_default() + }) + .unwrap_or_default() + { + anyhow::bail!("Currently, we only support a pair of ssh key in disk."); + } + } else { + anyhow::bail!("config commit.gpgsign=true detected.\nonly gpg signing with ssh key in disk supported.\ndeactivate in your repo/gitconfig to be able to commit without signing."); + } } let msg = self.input.get_text().to_string(); From 4af7a608033f1184924a24afd143cb6cca2a9603 Mon Sep 17 00:00:00 2001 From: Antonio Yang Date: Thu, 14 Mar 2024 18:54:58 +0800 Subject: [PATCH 22/22] raise error if commit with a ssh setting but without key --- Cargo.lock | 24 ++++++++++++------------ asyncgit/src/error.rs | 4 ++++ asyncgit/src/sync/commit.rs | 5 ++++- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6f56f560c4..0a431f0742 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2433,12 +2433,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - [[package]] name = "tui-textarea" version = "0.4.0" @@ -2450,6 +2444,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + [[package]] name = "unicode-bidi" version = "0.3.15" @@ -2792,12 +2792,6 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" -[[package]] -name = "zeroize" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" - [[package]] name = "zerocopy" version = "0.7.32" @@ -2817,3 +2811,9 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/asyncgit/src/error.rs b/asyncgit/src/error.rs index 0cbaf28d96..248c13d395 100644 --- a/asyncgit/src/error.rs +++ b/asyncgit/src/error.rs @@ -88,6 +88,10 @@ pub enum Error { /// #[error("ssh key error: {0}")] SshKeyError(#[from] ssh_key::Error), + + /// + #[error("ssh key missing")] + SshKeyMissing, } /// diff --git a/asyncgit/src/sync/commit.rs b/asyncgit/src/sync/commit.rs index c1ce115720..472024397d 100644 --- a/asyncgit/src/sync/commit.rs +++ b/asyncgit/src/sync/commit.rs @@ -1,6 +1,6 @@ use super::{CommitId, RepoPath}; use crate::{ - error::Result, + error::{Error, Result}, sync::{repository::repo, utils::get_head_repo}, }; use git2::{Config, ErrorCode, ObjectType, Repository, Signature}; @@ -146,6 +146,9 @@ pub fn commit(repo_path: &RepoPath, msg: &str) -> Result { } Ok(commit_id.into()) } + (Some(f), None) if f.value() == Some("ssh") => { + Err(Error::SshKeyMissing) + } _ => Ok(repo .commit( Some("HEAD"),