diff --git a/src/commands/diff.rs b/src/commands/diff.rs
index df0eb1f..250be60 100644
--- a/src/commands/diff.rs
+++ b/src/commands/diff.rs
@@ -18,7 +18,7 @@ use crate::{
PullRequestUpdate,
},
message::{MessageSection, validate_commit_message},
- output::{output, write_commit_title},
+ output::{output, write_commit_info, write_commit_title},
utils::{parse_name_list, remove_all_parens, slugify},
};
use git2::Oid;
@@ -435,6 +435,49 @@ async fn diff_impl(
}
}
+ if let Some(ref pull_request) = pull_request
+ && config.check_for_commits_from_others
+ {
+ let last_pr_commit = git.repo().find_commit(pull_request.head_oid)?;
+ let last_pr_committer = last_pr_commit.committer();
+ let local_commit = git.repo().find_commit(local_commit.oid)?;
+ let local_committer = local_commit.committer();
+ if local_committer.name() != last_pr_committer.name() {
+ let commit_id = last_pr_commit.id().to_string();
+ let summary = last_pr_commit.summary().unwrap_or("
");
+ let pr_committer = last_pr_committer.name().unwrap_or("unknown");
+ output("⚠️", "The last PR commit is not from you:")?;
+ write_commit_info(&commit_id[0..7], &summary, &pr_committer)?;
+ let pr_branch_name = pull_request.head.branch_name().to_string();
+ let input = tokio::task::spawn_blocking(move || {
+ dialoguer::Input::::new()
+ .with_prompt(formatdoc!(
+ "
+
+ Please select what you want do:
+ 1) Type 'yes' to continue (risks losing changes from others)
+ 2) Hit Enter to stop
+
+ Then manually merge in the changes from the PR:
+
+ git fetch origin {pr_branch_name}
+ git merge --squash origin/{pr_branch_name}
+ git commit --amend
+
+ Then run `spr diff` again.
+
+ ",
+ ))
+ .allow_empty(true)
+ .interact_text()
+ })
+ .await??;
+ if input.is_empty() || input != "yes" {
+ bail!("Aborted as per user request");
+ }
+ }
+ }
+
// Check if there is a base branch on GitHub already. That's the case when
// there is an existing Pull Request, and its base is not the master branch.
let base_branch = if let Some(ref pr) = pull_request {
diff --git a/src/config.rs b/src/config.rs
index f054c61..cee1033 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -18,6 +18,7 @@ pub struct Config {
pub auth_token: String,
pub require_approval: bool,
pub require_test_plan: bool,
+ pub check_for_commits_from_others: bool,
}
impl Config {
@@ -30,6 +31,7 @@ impl Config {
auth_token: String,
require_approval: bool,
require_test_plan: bool,
+ check_for_commits_from_others: bool,
) -> Self {
let master_ref =
GitHubBranch::new_from_branch_name(&master_branch, &master_branch);
@@ -41,6 +43,7 @@ impl Config {
auth_token,
require_approval,
require_test_plan,
+ check_for_commits_from_others,
}
}
@@ -106,6 +109,7 @@ mod tests {
"xyz".into(),
false,
true,
+ false,
)
}
diff --git a/src/main.rs b/src/main.rs
index 2d77961..6e7f1a3 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -138,6 +138,10 @@ pub async fn spr() -> Result<()> {
.get_bool("spr.requireTestPlan")
.ok()
.unwrap_or(true);
+ let check_for_commits_from_others = git_config
+ .get_bool("spr.checkForCommitsFromOthers")
+ .ok()
+ .unwrap_or(false);
let github_auth_token = match cli.github_auth_token {
Some(v) => Ok(v),
@@ -152,6 +156,7 @@ pub async fn spr() -> Result<()> {
github_auth_token.clone(),
require_approval,
require_test_plan,
+ check_for_commits_from_others,
);
debug!("config: {:?}", config);
diff --git a/src/output.rs b/src/output.rs
index e8e54c8..28dffa2 100644
--- a/src/output.rs
+++ b/src/output.rs
@@ -42,3 +42,18 @@ pub fn write_commit_title(prepared_commit: &PreparedCommit) -> Result<()> {
))?;
Ok(())
}
+
+pub fn write_commit_info(
+ short_id: &str,
+ title: &str,
+ committer: &str,
+) -> Result<()> {
+ let term = console::Term::stdout();
+ term.write_line(&format!(
+ "{} {} (from {})",
+ console::style(short_id).italic(),
+ console::style(title).yellow(),
+ console::style(committer)
+ ))?;
+ Ok(())
+}