From 3bfeb7f238a2e53de35fcd7b6281369c047ebd48 Mon Sep 17 00:00:00 2001
From: Willian Mori <wmrmrx@gmail.com>
Date: Sat, 9 Sep 2023 19:47:27 -0300
Subject: [PATCH] cli: hint for conflicted branches

---
 cli/src/cli_util.rs | 51 +++++++++++++++++++++++++++++++++------------
 1 file changed, 38 insertions(+), 13 deletions(-)

diff --git a/cli/src/cli_util.rs b/cli/src/cli_util.rs
index c73ac8e141..c0d715bfbc 100644
--- a/cli/src/cli_util.rs
+++ b/cli/src/cli_util.rs
@@ -51,9 +51,9 @@ use jj_lib::repo::{
 };
 use jj_lib::repo_path::{FsPathParseError, RepoPath};
 use jj_lib::revset::{
-    DefaultSymbolResolver, Revset, RevsetAliasesMap, RevsetEvaluationError, RevsetExpression,
-    RevsetIteratorExt, RevsetParseContext, RevsetParseError, RevsetParseErrorKind,
-    RevsetResolutionError, RevsetWorkspaceContext,
+    DefaultSymbolResolver, Revset, RevsetAliasesMap, RevsetCommitRef, RevsetEvaluationError,
+    RevsetExpression, RevsetIteratorExt, RevsetParseContext, RevsetParseError,
+    RevsetParseErrorKind, RevsetResolutionError, RevsetWorkspaceContext,
 };
 use jj_lib::settings::{ConfigResultExt as _, UserSettings};
 use jj_lib::transaction::Transaction;
@@ -1006,7 +1006,7 @@ impl WorkspaceCommandHelper {
         ui: &mut Ui,
     ) -> Result<Commit, CommandError> {
         let revset_expression = self.parse_revset(revision_str, Some(ui))?;
-        let revset = self.evaluate_revset(revset_expression)?;
+        let revset = self.evaluate_revset(revset_expression.clone())?;
         let mut iter = revset.iter().commits(self.repo().store()).fuse();
         match (iter.next(), iter.next()) {
             (Some(commit), None) => Ok(commit?),
@@ -1017,15 +1017,40 @@ impl WorkspaceCommandHelper {
                 let mut iter = [commit0, commit1].into_iter().chain(iter);
                 let commits: Vec<_> = iter.by_ref().take(5).try_collect()?;
                 let elided = iter.next().is_some();
-                let hint = format!(
-                    r#"The revset "{revision_str}" resolved to these revisions:{eol}{commits}{ellipsis}"#,
-                    eol = "\n",
-                    commits = commits
-                        .iter()
-                        .map(|c| self.format_commit_summary(c))
-                        .join("\n"),
-                    ellipsis = elided.then_some("\n...").unwrap_or_default()
-                );
+                // Separate hint if the conflict is due to a branch conflict
+                let hint = if let RevsetExpression::CommitRef(RevsetCommitRef::Symbol(
+                    branch_name,
+                )) = revset_expression.as_ref()
+                {
+                    let suggestion = if commits[0].change_id() == commits[1].change_id() {
+                        r#"Abandon the problematic commit with a conflicting change id with "jj abandon -r <REVISION>"."#.to_string()
+                    } else {
+                        format!(
+                            r#"Set which revision the branch points to with "jj branch set {branch_name} -r <REVISION>"."#
+                        )
+                    };
+                    format!(
+                        r#"Branch {branch_name} resolved to multiple revisions because it's conflicted.
+It resolved to these revisions:
+{commits}{ellipsis}
+{suggestion}"#,
+                        commits = commits
+                            .iter()
+                            .map(|c| self.format_commit_summary(c))
+                            .join("\n"),
+                        ellipsis = elided.then_some("\n...").unwrap_or_default()
+                    )
+                } else {
+                    format!(
+                        r#"The revset "{revision_str}" resolved to these revisions:{eol}{commits}{ellipsis}"#,
+                        eol = "\n",
+                        commits = commits
+                            .iter()
+                            .map(|c| self.format_commit_summary(c))
+                            .join("\n"),
+                        ellipsis = elided.then_some("\n...").unwrap_or_default()
+                    )
+                };
                 Err(user_error_with_hint(
                     format!(r#"Revset "{revision_str}" resolved to more than one revision"#),
                     hint,