From d2270fcad3a6b818a5f6c73e78e8500fbc092748 Mon Sep 17 00:00:00 2001 From: Paul Delafosse Date: Fri, 25 Sep 2020 08:54:46 +0200 Subject: [PATCH] fix: fix error: 'parent index out of bounds' (#18) --- src/commit.rs | 17 ++++++++-- src/error.rs | 3 +- src/lib.rs | 90 +++++++++++++++++++++++++++++---------------------- 3 files changed, 67 insertions(+), 43 deletions(-) diff --git a/src/commit.rs b/src/commit.rs index a7446b8c..d274ab77 100644 --- a/src/commit.rs +++ b/src/commit.rs @@ -83,19 +83,30 @@ impl Commit { date, }), Err(err) => { - let message = git2_message.replace("\n", ""); + let additional_info = if commit.parent_count() == 0 { + format!( + "{} Init commit or commit with no parent cannot be edited", + "warning:".yellow() + ) + } else { + "".to_string() + }; + + let message = git2_message.trim_end(); let commit_message = if message.len() > 80 { format!("{}{}", &message[0..80], "...").red() } else { - git2_message.red() + message.red() } .to_string(); - let cause = format!("{} {}", "cause:".red(), err); + + let cause = format!("{} {}", "cause:".magenta(), err); let level = "ERROR".red().bold().to_string(); Err(anyhow!(CommitFormat { level, shorthand, commit_message, + additional_info, cause })) } diff --git a/src/error.rs b/src/error.rs index 716da74e..aaa171f5 100644 --- a/src/error.rs +++ b/src/error.rs @@ -2,12 +2,13 @@ use thiserror::Error; #[derive(Error, Debug)] pub(crate) enum ErrorKind { - #[error("{level} - {commit_message} - ({shorthand})\n\t{cause}\n")] + #[error("{level} - {commit_message} - ({shorthand})\n\t{cause}\n\t{additional_info}")] CommitFormat { level: String, shorthand: String, commit_message: String, cause: String, + additional_info: String, }, #[error("{level}:\n\t{cause}\n")] Semver { level: String, cause: String }, diff --git a/src/lib.rs b/src/lib.rs index 72d47e79..4ba05d73 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -160,7 +160,7 @@ impl CocoGitto { let editor = std::env::var("EDITOR")?; let dir = TempDir::new("cocogito")?; - let errored_commits: Vec = commits + let mut errored_commits: Vec = commits .iter() .map(|commit| { let conv_commit = Commit::from_git_commit(&commit); @@ -170,49 +170,61 @@ impl CocoGitto { .map(|commit| commit.0) .collect(); - let last_errored_commit = errored_commits.last(); - println!("{:?}", last_errored_commit); - let commit = self - .repository - .0 - .find_commit(last_errored_commit.unwrap().to_owned())?; - let rebase_start = commit.parent_id(0)?; - let commit = self.repository.0.find_annotated_commit(rebase_start)?; - let mut options = RebaseOptions::new(); - let mut rebase = self - .repository - .0 - .rebase(None, Some(&commit), None, Some(&mut options))?; - - while let Some(op) = rebase.next() { - if let Ok(rebase_operation) = op { - let oid = rebase_operation.id(); - let original_commit = self.repository.0.find_commit(oid)?; - println!("rebasing {}", oid); - if errored_commits.contains(&oid) { - println!("\tmatch found in errored commits"); - let file_path = dir.path().join(&commit.id().to_string()); - let mut file = File::create(&file_path)?; - file.write_all(original_commit.message_bytes())?; - - Command::new(&editor) - .arg(&file_path) - .stdout(Stdio::inherit()) - .stdin(Stdio::inherit()) - .stderr(Stdio::inherit()) - .output()?; - - let new_message = std::fs::read_to_string(&file_path)?; - rebase.commit(None, &original_commit.committer(), Some(&new_message))?; + // Get the last commit oid on the list as a starting point for our rebase + let last_errored_commit = errored_commits.pop(); + if let Some(last_errored_commit) = last_errored_commit { + let commit = self + .repository + .0 + .find_commit(last_errored_commit.to_owned())?; + + let rebase_start = if commit.parent_count() == 0 { + commit.id() + } else { + commit.parent_id(0)? + }; + + let commit = self.repository.0.find_annotated_commit(rebase_start)?; + let mut options = RebaseOptions::new(); + let mut rebase = + self.repository + .0 + .rebase(None, Some(&commit), None, Some(&mut options))?; + + while let Some(op) = rebase.next() { + if let Ok(rebase_operation) = op { + let oid = rebase_operation.id(); + let original_commit = self.repository.0.find_commit(oid)?; + if errored_commits.contains(&oid) { + println!("Found errored commits : {}", &oid.to_string()[0..7]); + let file_path = dir.path().join(&commit.id().to_string()); + let mut file = File::create(&file_path)?; + file.write_all(original_commit.message_bytes())?; + + Command::new(&editor) + .arg(&file_path) + .stdout(Stdio::inherit()) + .stdin(Stdio::inherit()) + .stderr(Stdio::inherit()) + .output()?; + + let new_message = std::fs::read_to_string(&file_path)?; + rebase.commit(None, &original_commit.committer(), Some(&new_message))?; + println!( + "Changed commit message to : \"{}\"", + &new_message.trim_end() + ); + } else { + rebase.commit(None, &original_commit.committer(), None)?; + } } else { - rebase.commit(None, &original_commit.committer(), None)?; + eprintln!("{:?}", op); } - } else { - eprintln!("{:?}", op); } + + rebase.finish(None)?; } - rebase.finish(None)?; Ok(()) }