diff options
Diffstat (limited to 'asyncgit/src/sync/commit.rs')
-rw-r--r-- | asyncgit/src/sync/commit.rs | 460 |
1 files changed, 230 insertions, 230 deletions
diff --git a/asyncgit/src/sync/commit.rs b/asyncgit/src/sync/commit.rs index 6b0c4fba..0d5f7847 100644 --- a/asyncgit/src/sync/commit.rs +++ b/asyncgit/src/sync/commit.rs @@ -5,29 +5,29 @@ use scopetime::scope_time; /// pub fn amend( - repo_path: &str, - id: CommitId, - msg: &str, + repo_path: &str, + id: CommitId, + msg: &str, ) -> Result<CommitId> { - scope_time!("amend"); + scope_time!("amend"); - let repo = repo(repo_path)?; - let commit = repo.find_commit(id.into())?; + let repo = repo(repo_path)?; + let commit = repo.find_commit(id.into())?; - let mut index = repo.index()?; - let tree_id = index.write_tree()?; - let tree = repo.find_tree(tree_id)?; + let mut index = repo.index()?; + let tree_id = index.write_tree()?; + let tree = repo.find_tree(tree_id)?; - let new_id = commit.amend( - Some("HEAD"), - None, - None, - None, - Some(msg), - Some(&tree), - )?; + let new_id = commit.amend( + Some("HEAD"), + None, + None, + None, + Some(msg), + Some(&tree), + )?; - Ok(CommitId::new(new_id)) + Ok(CommitId::new(new_id)) } /// Wrap `Repository::signature` to allow unknown user.name. @@ -35,57 +35,57 @@ pub fn amend( /// See <https://github.com/extrawurst/gitui/issues/79>. #[allow(clippy::redundant_pub_crate)] pub(crate) fn signature_allow_undefined_name( - repo: &Repository, + repo: &Repository, ) -> std::result::Result<Signature<'_>, git2::Error> { - let signature = repo.signature(); - - if let Err(ref e) = signature { - if e.code() == ErrorCode::NotFound { - let config = repo.config()?; - - if let (Err(_), Ok(email_entry)) = ( - config.get_entry("user.name"), - config.get_entry("user.email"), - ) { - if let Some(email) = email_entry.value() { - return Signature::now("unknown", email); - } - }; - } - } - - signature + let signature = repo.signature(); + + if let Err(ref e) = signature { + if e.code() == ErrorCode::NotFound { + let config = repo.config()?; + + if let (Err(_), Ok(email_entry)) = ( + config.get_entry("user.name"), + config.get_entry("user.email"), + ) { + if let Some(email) = email_entry.value() { + return Signature::now("unknown", email); + } + }; + } + } + + signature } /// this does not run any git hooks pub fn commit(repo_path: &str, msg: &str) -> Result<CommitId> { - scope_time!("commit"); - - let repo = repo(repo_path)?; - - let signature = signature_allow_undefined_name(&repo)?; - let mut index = repo.index()?; - let tree_id = index.write_tree()?; - let tree = repo.find_tree(tree_id)?; - - let parents = if let Ok(id) = get_head_repo(&repo) { - vec![repo.find_commit(id.into())?] - } else { - Vec::new() - }; - - let parents = parents.iter().collect::<Vec<_>>(); - - Ok(repo - .commit( - Some("HEAD"), - &signature, - &signature, - msg, - &tree, - parents.as_slice(), - )? - .into()) + scope_time!("commit"); + + let repo = repo(repo_path)?; + + let signature = signature_allow_undefined_name(&repo)?; + let mut index = repo.index()?; + let tree_id = index.write_tree()?; + let tree = repo.find_tree(tree_id)?; + + let parents = if let Ok(id) = get_head_repo(&repo) { + vec![repo.find_commit(id.into())?] + } else { + Vec::new() + }; + + let parents = parents.iter().collect::<Vec<_>>(); + + Ok(repo + .commit( + Some("HEAD"), + &signature, + &signature, + msg, + &tree, + parents.as_slice(), + )? + .into()) } /// Tag a commit. @@ -93,246 +93,246 @@ pub fn commit(repo_path: &str, msg: &str) -> Result<CommitId> { /// This function will return an `Err(…)` variant if the tag’s name is refused /// by git or if the tag already exists. pub fn tag( - repo_path: &str, - commit_id: &CommitId, - tag: &str, + repo_path: &str, + commit_id: &CommitId, + tag: &str, ) -> Result<CommitId> { - scope_time!("tag"); + scope_time!("tag"); - let repo = repo(repo_path)?; + let repo = repo(repo_path)?; - let signature = signature_allow_undefined_name(&repo)?; - let object_id = commit_id.get_oid(); - let target = - repo.find_object(object_id, Some(ObjectType::Commit))?; + let signature = signature_allow_undefined_name(&repo)?; + let object_id = commit_id.get_oid(); + let target = + repo.find_object(object_id, Some(ObjectType::Commit))?; - Ok(repo.tag(tag, &target, &signature, "", false)?.into()) + Ok(repo.tag(tag, &target, &signature, "", false)?.into()) } #[cfg(test)] mod tests { - use crate::error::Result; - use crate::sync::{ - commit, get_commit_details, get_commit_files, stage_add_file, - tags::get_tags, - tests::{get_statuses, repo_init, repo_init_empty}, - utils::get_head, - LogWalker, - }; - use commit::{amend, tag}; - use git2::Repository; - use std::{fs::File, io::Write, path::Path}; + use crate::error::Result; + use crate::sync::{ + commit, get_commit_details, get_commit_files, stage_add_file, + tags::get_tags, + tests::{get_statuses, repo_init, repo_init_empty}, + utils::get_head, + LogWalker, + }; + use commit::{amend, tag}; + use git2::Repository; + use std::{fs::File, io::Write, path::Path}; - fn count_commits(repo: &Repository, max: usize) -> usize { - let mut items = Vec::new(); - let mut walk = LogWalker::new(&repo, max).unwrap(); - walk.read(&mut items).unwrap(); - items.len() - } + fn count_commits(repo: &Repository, max: usize) -> usize { + let mut items = Vec::new(); + let mut walk = LogWalker::new(&repo, max).unwrap(); + walk.read(&mut items).unwrap(); + items.len() + } - #[test] - fn test_commit() { - let file_path = Path::new("foo"); - let (_td, repo) = repo_init().unwrap(); - let root = repo.path().parent().unwrap(); - let repo_path = root.as_os_str().to_str().unwrap(); + #[test] + fn test_commit() { + let file_path = Path::new("foo"); + let (_td, repo) = repo_init().unwrap(); + let root = repo.path().parent().unwrap(); + let repo_path = root.as_os_str().to_str().unwrap(); - File::create(&root.join(file_path)) - .unwrap() - .write_all(b"test\nfoo") - .unwrap(); + File::create(&root.join(file_path)) + .unwrap() + .write_all(b"test\nfoo") + .unwrap(); - assert_eq!(get_statuses(repo_path), (1, 0)); + assert_eq!(get_statuses(repo_path), (1, 0)); - stage_add_file(repo_path, file_path).unwrap(); + stage_add_file(repo_path, file_path).unwrap(); - assert_eq!(get_statuses(repo_path), (0, 1)); + assert_eq!(get_statuses(repo_path), (0, 1)); - commit(repo_path, "commit msg").unwrap(); + commit(repo_path, "commit msg").unwrap(); - assert_eq!(get_statuses(repo_path), (0, 0)); - } + assert_eq!(get_statuses(repo_path), (0, 0)); + } - #[test] - fn test_commit_in_empty_repo() { - let file_path = Path::new("foo"); - let (_td, repo) = repo_init_empty().unwrap(); - let root = repo.path().parent().unwrap(); - let repo_path = root.as_os_str().to_str().unwrap(); + #[test] + fn test_commit_in_empty_repo() { + let file_path = Path::new("foo"); + let (_td, repo) = repo_init_empty().unwrap(); + let root = repo.path().parent().unwrap(); + let repo_path = root.as_os_str().to_str().unwrap(); - assert_eq!(get_statuses(repo_path), (0, 0)); + assert_eq!(get_statuses(repo_path), (0, 0)); - File::create(&root.join(file_path)) - .unwrap() - .write_all(b"test\nfoo") - .unwrap(); + File::create(&root.join(file_path)) + .unwrap() + .write_all(b"test\nfoo") + .unwrap(); - assert_eq!(get_statuses(repo_path), (1, 0)); + assert_eq!(get_statuses(repo_path), (1, 0)); - stage_add_file(repo_path, file_path).unwrap(); + stage_add_file(repo_path, file_path).unwrap(); - assert_eq!(get_statuses(repo_path), (0, 1)); + assert_eq!(get_statuses(repo_path), (0, 1)); - commit(repo_path, "commit msg").unwrap(); + commit(repo_path, "commit msg").unwrap(); - assert_eq!(get_statuses(repo_path), (0, 0)); - } + assert_eq!(get_statuses(repo_path), (0, 0)); + } - #[test] - fn test_amend() -> Result<()> { - let file_path1 = Path::new("foo"); - let file_path2 = Path::new("foo2"); - let (_td, repo) = repo_init_empty()?; - let root = repo.path().parent().unwrap(); - let repo_path = root.as_os_str().to_str().unwrap(); + #[test] + fn test_amend() -> Result<()> { + let file_path1 = Path::new("foo"); + let file_path2 = Path::new("foo2"); + let (_td, repo) = repo_init_empty()?; + let root = repo.path().parent().unwrap(); + let repo_path = root.as_os_str().to_str().unwrap(); - File::create(&root.join(file_path1))?.write_all(b"test1")?; + File::create(&root.join(file_path1))?.write_all(b"test1")?; - stage_add_file(repo_path, file_path1)?; - let id = commit(repo_path, "commit msg")?; + stage_add_file(repo_path, file_path1)?; + let id = commit(repo_path, "commit msg")?; - assert_eq!(count_commits(&repo, 10), 1); + assert_eq!(count_commits(&repo, 10), 1); - File::create(&root.join(file_path2))?.write_all(b"test2")?; + File::create(&root.join(file_path2))?.write_all(b"test2")?; - stage_add_file(repo_path, file_path2)?; + stage_add_file(repo_path, file_path2)?; - let new_id = amend(repo_path, id, "amended")?; + let new_id = amend(repo_path, id, "amended")?; - assert_eq!(count_commits(&repo, 10), 1); + assert_eq!(count_commits(&repo, 10), 1); - let details = get_commit_details(repo_path, new_id)?; - assert_eq!(details.message.unwrap().subject, "amended"); + let details = get_commit_details(repo_path, new_id)?; + assert_eq!(details.message.unwrap().subject, "amended"); - let files = get_commit_files(repo_path, new_id)?; + let files = get_commit_files(repo_path, new_id)?; - assert_eq!(files.len(), 2); + assert_eq!(files.len(), 2); - let head = get_head(repo_path)?; + let head = get_head(repo_path)?; - assert_eq!(head, new_id); + assert_eq!(head, new_id); - Ok(()) - } + Ok(()) + } - #[test] - fn test_tag() -> Result<()> { - let file_path = Path::new("foo"); - let (_td, repo) = repo_init_empty().unwrap(); - let root = repo.path().parent().unwrap(); - let repo_path = root.as_os_str().to_str().unwrap(); + #[test] + fn test_tag() -> Result<()> { + let file_path = Path::new("foo"); + let (_td, repo) = repo_init_empty().unwrap(); + let root = repo.path().parent().unwrap(); + let repo_path = root.as_os_str().to_str().unwrap(); - File::create(&root.join(file_path))? - .write_all(b"test\nfoo")?; + File::create(&root.join(file_path))? + .write_all(b"test\nfoo")?; - stage_add_file(repo_path, file_path)?; + stage_add_file(repo_path, file_path)?; - let new_id = commit(repo_path, "commit msg")?; + let new_id = commit(repo_path, "commit msg")?; - tag(repo_path, &new_id, "tag")?; + tag(repo_path, &new_id, "tag")?; - assert_eq!( - get_tags(repo_path).unwrap()[&new_id], - vec!["tag"] - ); + assert_eq!( + get_tags(repo_path).unwrap()[&new_id], + vec!["tag"] + ); - assert!(matches!(tag(repo_path, &new_id, "tag"), Err(_))); + assert!(matches!(tag(repo_path, &new_id, "tag"), Err(_))); - assert_eq!( - get_tags(repo_path).unwrap()[&new_id], - vec!["tag"] - ); + assert_eq!( + get_tags(repo_path).unwrap()[&new_id], + vec!["tag"] + ); - tag(repo_path, &new_id, "second-tag")?; + tag(repo_path, &new_id, "second-tag")?; - assert_eq!( - get_tags(repo_path).unwrap()[&new_id], - vec!["second-tag", "tag"] - ); + assert_eq!( + get_tags(repo_path).unwrap()[&new_id], + vec!["second-tag", "tag"] + ); - Ok(()) - } + Ok(()) + } - /// Beware: this test has to be run with a `$HOME/.gitconfig` that has - /// `user.email` not set. Otherwise, git falls back to the value of - /// `user.email` in `$HOME/.gitconfig` and this test fails. - /// - /// As of February 2021, `repo_init_empty` sets all git config locations - /// to an empty temporary directory, so this constraint is met. - #[test] - fn test_empty_email() -> Result<()> { - let file_path = Path::new("foo"); - let (_td, repo) = repo_init_empty().unwrap(); - let root = repo.path().parent().unwrap(); - let repo_path = root.as_os_str().to_str().unwrap(); + /// Beware: this test has to be run with a `$HOME/.gitconfig` that has + /// `user.email` not set. Otherwise, git falls back to the value of + /// `user.email` in `$HOME/.gitconfig` and this test fails. + /// + /// As of February 2021, `repo_init_empty` sets all git config locations + /// to an empty temporary directory, so this constraint is met. + #[test] + fn test_empty_email() -> Result<()> { + let file_path = Path::new("foo"); + let (_td, repo) = repo_init_empty().unwrap(); + let root = repo.path().parent().unwrap(); + let repo_path = root.as_os_str().to_str().unwrap(); - File::create(&root.join(file_path))? - .write_all(b"test\nfoo")?; + File::create(&root.join(file_path))? + .write_all(b"test\nfoo")?; - stage_add_file(repo_path, file_path)?; + stage_add_file(repo_path, file_path)?; - repo.config()?.remove("user.email")?; + repo.config()?.remove("user.email")?; - let error = commit(repo_path, "commit msg"); + let error = commit(repo_path, "commit msg"); - assert!(matches!(error, Err(_))); + assert!(matches!(error, Err(_))); - repo.config()?.set_str("user.email", "email")?; + repo.config()?.set_str("user.email", "email")?; - let success = commit(repo_path, "commit msg"); + let success = commit(repo_path, "commit msg"); - assert!(matches!(success, Ok(_))); - assert_eq!(count_commits(&repo, 10), 1); + assert!(matches!(success, Ok(_))); + assert_eq!(count_commits(&repo, 10), 1); - let details = - get_commit_details(repo_path, success.unwrap()).unwrap(); + let details = + get_commit_details(repo_path, success.unwrap()).unwrap(); - assert_eq!(details.author.name, "name"); - assert_eq!(details.author.email, "email"); + assert_eq!(details.author.name, "name"); + assert_eq!(details.author.email, "email"); - Ok(()) - } + Ok(()) + } - /// See comment to `test_empty_email`. - #[test] - fn test_empty_name() -> Result<()> { - let file_path = Path::new("foo"); - let (_td, repo) = repo_init_empty().unwrap(); - let root = repo.path().parent().unwrap(); - let repo_path = root.as_os_str().to_str().unwrap(); + /// See comment to `test_empty_email`. + #[test] + fn test_empty_name() -> Result<()> { + let file_path = Path::new("foo"); + let (_td, repo) = repo_init_empty().unwrap(); + let root = repo.path().parent().unwrap(); + let repo_path = root.as_os_str().to_str().unwrap(); - File::create(&root.join(file_path))? - .write_all(b"test\nfoo")?; + File::create(&root.join(file_path))? + .write_all(b"test\nfoo")?; - stage_add_file(repo_path, file_path)?; + stage_add_file(repo_path, file_path)?; - repo.config()?.remove("user.name")?; + repo.config()?.remove("user.name")?; - let mut success = commit(repo_path, "commit msg"); + let mut success = commit(repo_path, "commit msg"); - assert!(matches!(success, Ok(_))); - assert_eq!(count_commits(&repo, 10), 1); + assert!(matches!(success, Ok(_))); + assert_eq!(count_commits(&repo, 10), 1); - let mut details = - get_commit_details(repo_path, success.unwrap()).unwrap(); + let mut details = + get_commit_details(repo_path, success.unwrap()).unwrap(); - assert_eq!(details.author.name, "unknown"); - assert_eq!(details.author.email, "email"); + assert_eq!(details.author.name, "unknown"); + assert_eq!(details.author.email, "email"); - repo.config()?.set_str("user.name", "name")?; + repo.config()?.set_str("user.name", "name")?; - success = commit(repo_path, "commit msg"); + success = commit(repo_path, "commit msg"); - assert!(matches!(success, Ok(_))); - assert_eq!(count_commits(&repo, 10), 2); + assert!(matches!(success, Ok(_))); + assert_eq!(count_commits(&repo, 10), 2); - details = - get_commit_details(repo_path, success.unwrap()).unwrap(); + details = + get_commit_details(repo_path, success.unwrap()).unwrap(); - assert_eq!(details.author.name, "name"); - assert_eq!(details.author.email, "email"); + assert_eq!(details.author.name, "name"); + assert_eq!(details.author.email, "email"); - Ok(()) - } + Ok(()) + } } |