Skip to content

Commit

Permalink
cli: print a hint about how to resolve conflicts
Browse files Browse the repository at this point in the history
This prints a hint about using `jj new <first conflicted commit>` and
`jj squash` to resolve conflicts. The hint is printed whenever there
are new or resolved conflicts.

I hope this hint will be useful especially for new users so they know
which commit to resolve conflicts in first. It may not be obvious that
they should start with the bottommost one. I hope the hint will also
be useful for more more experienced user by letting them just copy the
printed command without first running `jj log` to find the right
commit..
  • Loading branch information
martinvonz committed Dec 10, 2023
1 parent 2dae5f5 commit a88b3dd
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 1 deletion.
58 changes: 57 additions & 1 deletion cli/src/cli_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1580,7 +1580,63 @@ See https://github.com/martinvonz/jj/blob/main/docs/working-copy.md#stale-workin
}
}

// TODO: Hint about doing `jj new <first commit with conflicts>`.
// Hint that the user might want to `jj new` to the first conflict commit to
// resolve conflicts. Only show the hints if there were any new or resolved
// conflicts, and only if there are still some conflicts.
if !(added_conflict_commits.is_empty()
|| resolved_conflicts_by_change_id.is_empty() && new_conflicts_by_change_id.is_empty())
{
// If the user just resolved some conflict and squashed them in, there won't be
// any new conflicts. Clarify to them that there are still some other conflicts
// to resolve. (We don't mention conflicts in commits that weren't affected by
// the operation, however.)
if new_conflicts_by_change_id.is_empty() {
writeln!(
fmt,
"There are still unresolved conflicts in rebased descendants.",
)?;
}
let root_conflicts_revset = RevsetExpression::commits(
added_conflict_commits
.iter()
.map(|commit| commit.id().clone())
.collect(),
)
.roots()
.evaluate_programmatic(new_repo)?;

let root_conflict_commits: Vec<_> = root_conflicts_revset
.iter()
.commits(new_repo.store())
.try_collect()?;
if !root_conflict_commits.is_empty() {
fmt.push_label("hint")?;
if added_conflict_commits.len() == 1 {
writeln!(fmt, "To resolve the conflicts, start by updating to it:",)?;
} else if root_conflict_commits.len() == 1 {
writeln!(
fmt,
"To resolve the conflicts, start by updating to the first one:",
)?;
} else {
writeln!(
fmt,
"To resolve the conflicts, start by updating to one of the first ones:",
)?;
}
for commit in root_conflict_commits {
writeln!(fmt, " jj new {}", short_change_hash(commit.change_id()))?;
}
writeln!(
fmt,
r#"Then use `jj resolve`, or edit the conflict markers in the file directly.
Once the conflicts are resolved, you may want inspect the result with `jj diff`.
Then run `jj squash` to move the resolution into the conflicted commit."#,
)?;
fmt.pop_label()?;
}
}

Ok(())
}
}
Expand Down
5 changes: 5 additions & 0 deletions cli/tests/test_chmod_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,11 @@ fn test_chmod_file_dir_deletion_conflicts() {
insta::assert_snapshot!(stderr, @r###"
New conflicts appeared in these commits:
kmkuslsw 4cc432b5 file_deletion | (conflict) file_deletion
To resolve the conflicts, start by updating to it:
jj new kmkuslswpqwq
Then use `jj resolve`, or edit the conflict markers in the file directly.
Once the conflicts are resolved, you may want inspect the result with `jj diff`.
Then run `jj squash` to move the resolution into the conflicted commit.
Working copy now at: kmkuslsw 4cc432b5 file_deletion | (conflict) file_deletion
Parent commit : zsuskuln c51c9c55 file | file
Parent commit : royxmykx 6b18b3c1 deletion | deletion
Expand Down
58 changes: 58 additions & 0 deletions cli/tests/test_repo_change_report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ fn test_report_conflicts() {
New conflicts appeared in these commits:
kkmpptxz a2593769 (conflict) C
rlvkpnrz 727244df (conflict) B
To resolve the conflicts, start by updating to the first one:
jj new rlvkpnrzqnoo
Then use `jj resolve`, or edit the conflict markers in the file directly.
Once the conflicts are resolved, you may want inspect the result with `jj diff`.
Then run `jj squash` to move the resolution into the conflicted commit.
Working copy now at: zsuskuln 30928080 (conflict) (empty) (no description set)
Parent commit : kkmpptxz a2593769 (conflict) C
Added 0 files, modified 1 files, removed 0 files
Expand All @@ -53,6 +58,44 @@ fn test_report_conflicts() {
Parent commit : kkmpptxz ed071401 C
Added 0 files, modified 1 files, removed 0 files
"###);

// Can get hint about multiple root commits
let (stdout, stderr) =
test_env.jj_cmd_ok(&repo_path, &["rebase", "-r=description(B)", "-d=root()"]);
insta::assert_snapshot!(stdout, @"");
insta::assert_snapshot!(stderr, @r###"
Also rebased 2 descendant commits onto parent of rebased commit
New conflicts appeared in these commits:
rlvkpnrz 9df65f08 (conflict) B
kkmpptxz 7530822d (conflict) C
To resolve the conflicts, start by updating to one of the first ones:
jj new rlvkpnrzqnoo
jj new kkmpptxzrspx
Then use `jj resolve`, or edit the conflict markers in the file directly.
Once the conflicts are resolved, you may want inspect the result with `jj diff`.
Then run `jj squash` to move the resolution into the conflicted commit.
Working copy now at: zsuskuln 203be58b (conflict) (empty) (no description set)
Parent commit : kkmpptxz 7530822d (conflict) C
Added 0 files, modified 1 files, removed 0 files
"###);

// Resolve one of the conflicts by (mostly) following the instructions
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["new", "rlvkpnrzqnoo"]);
insta::assert_snapshot!(stdout, @"");
insta::assert_snapshot!(stderr, @r###"
Working copy now at: vruxwmqv 406f84d0 (conflict) (empty) (no description set)
Parent commit : rlvkpnrz 9df65f08 (conflict) B
Added 0 files, modified 1 files, removed 0 files
"###);
std::fs::write(repo_path.join("file"), "resolved\n").unwrap();
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["squash"]);
insta::assert_snapshot!(stdout, @"");
insta::assert_snapshot!(stderr, @r###"
Existing conflicts were resolved or abandoned from these commits:
rlvkpnrz hidden 9df65f08 (conflict) B
Working copy now at: yostqsxw 8e160bc4 (empty) (no description set)
Parent commit : rlvkpnrz c5319490 B
"###);
}

#[test]
Expand Down Expand Up @@ -80,6 +123,11 @@ fn test_report_conflicts_with_divergent_commits() {
zsuskuln?? 76c40a95 (conflict) C3
zsuskuln?? e92329f2 (conflict) C2
kkmpptxz aed319ec (conflict) B
To resolve the conflicts, start by updating to the first one:
jj new kkmpptxzrspx
Then use `jj resolve`, or edit the conflict markers in the file directly.
Once the conflicts are resolved, you may want inspect the result with `jj diff`.
Then run `jj squash` to move the resolution into the conflicted commit.
Working copy now at: zsuskuln?? e92329f2 (conflict) C2
Parent commit : kkmpptxz aed319ec (conflict) B
Added 0 files, modified 1 files, removed 0 files
Expand All @@ -106,6 +154,11 @@ fn test_report_conflicts_with_divergent_commits() {
Rebased 1 commits
New conflicts appeared in these commits:
zsuskuln?? 0d6cb6b7 (conflict) C2
To resolve the conflicts, start by updating to it:
jj new zsuskulnrvyr
Then use `jj resolve`, or edit the conflict markers in the file directly.
Once the conflicts are resolved, you may want inspect the result with `jj diff`.
Then run `jj squash` to move the resolution into the conflicted commit.
Working copy now at: zsuskuln?? 0d6cb6b7 (conflict) C2
Parent commit : zzzzzzzz 00000000 (empty) (no description set)
Added 0 files, modified 1 files, removed 0 files
Expand All @@ -118,6 +171,11 @@ fn test_report_conflicts_with_divergent_commits() {
Rebased 1 commits
New conflicts appeared in these commits:
zsuskuln?? 9652a362 (conflict) C3
To resolve the conflicts, start by updating to it:
jj new zsuskulnrvyr
Then use `jj resolve`, or edit the conflict markers in the file directly.
Once the conflicts are resolved, you may want inspect the result with `jj diff`.
Then run `jj squash` to move the resolution into the conflicted commit.
"###);

let (stdout, stderr) = test_env.jj_cmd_ok(
Expand Down
15 changes: 15 additions & 0 deletions cli/tests/test_resolve_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,11 @@ conflict
insta::assert_snapshot!(stderr, @r###"
New conflicts appeared in these commits:
vruxwmqv ff4e8c6b conflict | (conflict) conflict
To resolve the conflicts, start by updating to it:
jj new vruxwmqvtpmx
Then use `jj resolve`, or edit the conflict markers in the file directly.
Once the conflicts are resolved, you may want inspect the result with `jj diff`.
Then run `jj squash` to move the resolution into the conflicted commit.
Working copy now at: vruxwmqv ff4e8c6b conflict | (conflict) conflict
Parent commit : zsuskuln aa493daf a | a
Parent commit : royxmykx db6a4daf b | b
Expand Down Expand Up @@ -639,6 +644,11 @@ fn test_multiple_conflicts() {
insta::assert_snapshot!(stderr, @r###"
New conflicts appeared in these commits:
vruxwmqv c3c25bce conflict | (conflict) conflict
To resolve the conflicts, start by updating to it:
jj new vruxwmqvtpmx
Then use `jj resolve`, or edit the conflict markers in the file directly.
Once the conflicts are resolved, you may want inspect the result with `jj diff`.
Then run `jj squash` to move the resolution into the conflicted commit.
Working copy now at: vruxwmqv c3c25bce conflict | (conflict) conflict
Parent commit : zsuskuln de7553ef a | a
Parent commit : royxmykx f68bc2f0 b | b
Expand Down Expand Up @@ -670,6 +680,11 @@ fn test_multiple_conflicts() {
insta::assert_snapshot!(stderr, @r###"
New conflicts appeared in these commits:
vruxwmqv fd3874cd conflict | (conflict) conflict
To resolve the conflicts, start by updating to it:
jj new vruxwmqvtpmx
Then use `jj resolve`, or edit the conflict markers in the file directly.
Once the conflicts are resolved, you may want inspect the result with `jj diff`.
Then run `jj squash` to move the resolution into the conflicted commit.
Working copy now at: vruxwmqv fd3874cd conflict | (conflict) conflict
Parent commit : zsuskuln de7553ef a | a
Parent commit : royxmykx f68bc2f0 b | b
Expand Down
5 changes: 5 additions & 0 deletions cli/tests/test_restore_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ fn test_restore() {
Rebased 1 descendant commits
New conflicts appeared in these commits:
kkmpptxz e301deb3 (conflict) (no description set)
To resolve the conflicts, start by updating to it:
jj new kkmpptxzrspx
Then use `jj resolve`, or edit the conflict markers in the file directly.
Once the conflicts are resolved, you may want inspect the result with `jj diff`.
Then run `jj squash` to move the resolution into the conflicted commit.
Working copy now at: kkmpptxz e301deb3 (conflict) (no description set)
Parent commit : rlvkpnrz e25100af (empty) (no description set)
Added 0 files, modified 1 files, removed 0 files
Expand Down

0 comments on commit a88b3dd

Please sign in to comment.