ok/jj
1
0
Fork 0
forked from mirrors/jj

Change conflict hint depending on state of working commit.

To avoid always printing the rebase instructions to fix a conflict
even when a child commit to fix the conflict already exists, implement
the following:

* If working commit has conflicts:
  * Continue printing the same message we print today.

* If working commit has no conflicts:
  * If any parent has conflicts, we print: "Conflict in parent is resolved in working copy".
    Also explicitly not printing the "conflicting parent" here, since a merge commit
    could have conflict in multiple parents.
  * If no parent has any conflicts: exit quietly.
* Update unittests for conflict hinting update.
* Update CHANGELOG
This commit is contained in:
Essien Ita Essien 2024-07-25 09:10:41 +01:00 committed by Essien Ita Essien
parent d0f6f429e1
commit 7c4185cd41
3 changed files with 148 additions and 17 deletions

View file

@ -101,6 +101,11 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
### Fixed bugs ### Fixed bugs
* `jj status` will show different messages in a conflicted tree, depending
on the state of the working commit. In particular, if a child commit fixes
a conflict in the parent, this will be reflected in the hint provided
by `jj status`
* `jj diff --git` no longer shows the contents of binary files. * `jj diff --git` no longer shows the contents of binary files.
* Windows binaries no longer require `vcruntime140.dll` to be installed * Windows binaries no longer require `vcruntime140.dll` to be installed

View file

@ -92,21 +92,36 @@ pub(crate) fn cmd_status(
writeln!(formatter)?; writeln!(formatter)?;
} }
let wc_revset = RevsetExpression::commit(wc_commit.id().clone()); if wc_commit.has_conflict()? {
// Ancestors with conflicts, excluding the current working copy commit. let wc_revset = RevsetExpression::commit(wc_commit.id().clone());
let ancestors_conflicts = workspace_command
.attach_revset_evaluator( // Ancestors with conflicts, excluding the current working copy commit.
wc_revset let ancestors_conflicts = workspace_command
.parents() .attach_revset_evaluator(
.ancestors() wc_revset
.filtered(RevsetFilterPredicate::HasConflict) .parents()
.minus(&revset_util::parse_immutable_expression( .ancestors()
&workspace_command.revset_parse_context(), .filtered(RevsetFilterPredicate::HasConflict)
)?), .minus(&revset_util::parse_immutable_expression(
)? &workspace_command.revset_parse_context(),
.evaluate_to_commit_ids()? )?),
.collect(); )?
workspace_command.report_repo_conflicts(formatter, repo, ancestors_conflicts)?; .evaluate_to_commit_ids()?
.collect();
workspace_command.report_repo_conflicts(formatter, repo, ancestors_conflicts)?;
} else {
for parent in wc_commit.parents() {
let parent = parent?;
if parent.has_conflict()? {
writeln!(
formatter.labeled("hint"),
"Conflict in parent commit has been resolved in working copy"
)?;
break;
}
}
}
} else { } else {
writeln!(formatter, "No working copy")?; writeln!(formatter, "No working copy")?;
} }

View file

@ -105,8 +105,9 @@ fn test_status_filtered() {
} }
// See <https://github.com/martinvonz/jj/issues/3108> // See <https://github.com/martinvonz/jj/issues/3108>
// See <https://github.com/martinvonz/jj/issues/4147>
#[test] #[test]
fn test_status_display_rebase_instructions() { fn test_status_display_relevant_working_commit_conflict_hints() {
let test_env = TestEnvironment::default(); let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]); test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]);
@ -143,7 +144,7 @@ fn test_status_display_rebase_instructions() {
test_env.jj_cmd_ok(&repo_path, &["new", "--message", "boom-cont"]); test_env.jj_cmd_ok(&repo_path, &["new", "--message", "boom-cont"]);
test_env.jj_cmd_ok(&repo_path, &["new", "--message", "boom-cont-2"]); test_env.jj_cmd_ok(&repo_path, &["new", "--message", "boom-cont-2"]);
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-r", "::@"]); let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-r", "::"]);
insta::assert_snapshot!(stdout, @r###" insta::assert_snapshot!(stdout, @r###"
@ yqosqzyt test.user@example.com 2001-02-03 08:05:13 65143fef conflict @ yqosqzyt test.user@example.com 2001-02-03 08:05:13 65143fef conflict
@ -175,6 +176,116 @@ fn test_status_display_rebase_instructions() {
Once the conflicts are resolved, you may want to inspect the result with `jj diff`. Once the conflicts are resolved, you may want to inspect the result with `jj diff`.
Then run `jj squash` to move the resolution into the conflicted commit. Then run `jj squash` to move the resolution into the conflicted commit.
"###); "###);
// Resolve conflict
test_env.jj_cmd_ok(&repo_path, &["new", "--message", "fixed 1"]);
std::fs::write(&conflicted_path, "first commit to fix conflict").unwrap();
// Add one more commit atop the commit that resolves the conflict.
test_env.jj_cmd_ok(&repo_path, &["new", "--message", "fixed 2"]);
std::fs::write(&conflicted_path, "edit not conflict").unwrap();
// wc is now conflict free, parent is also conflict free
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-r", "::"]);
insta::assert_snapshot!(stdout, @r###"
@ kpqxywon test.user@example.com 2001-02-03 08:05:18 3432159f
fixed 2
znkkpsqq test.user@example.com 2001-02-03 08:05:17 897d589f
fixed 1
× yqosqzyt test.user@example.com 2001-02-03 08:05:13 65143fef conflict
(empty) boom-cont-2
× royxmykx test.user@example.com 2001-02-03 08:05:12 a4e88714 conflict
(empty) boom-cont
× mzvwutvl test.user@example.com 2001-02-03 08:05:11 538415e7 conflict
(empty) boom
kkmpptxz test.user@example.com 2001-02-03 08:05:10 1e8c2956
First part of conflicting change
zsuskuln test.user@example.com 2001-02-03 08:05:11 2c8b19fd
Second part of conflicting change
qpvuntsm test.user@example.com 2001-02-03 08:05:08 aade7195
Initial contents
zzzzzzzz root() 00000000
"###);
let stdout = test_env.jj_cmd_success(&repo_path, &["status"]);
insta::assert_snapshot!(stdout, @r###"
Working copy changes:
M conflicted.txt
Working copy : kpqxywon 3432159f fixed 2
Parent commit: znkkpsqq 897d589f fixed 1
"###);
// Step back one.
// wc is still conflict free, parent has a conflict.
test_env.jj_cmd_ok(&repo_path, &["edit", "@-"]);
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-r", "::"]);
insta::assert_snapshot!(stdout, @r###"
kpqxywon test.user@example.com 2001-02-03 08:05:18 3432159f
fixed 2
@ znkkpsqq test.user@example.com 2001-02-03 08:05:17 897d589f
fixed 1
× yqosqzyt test.user@example.com 2001-02-03 08:05:13 65143fef conflict
(empty) boom-cont-2
× royxmykx test.user@example.com 2001-02-03 08:05:12 a4e88714 conflict
(empty) boom-cont
× mzvwutvl test.user@example.com 2001-02-03 08:05:11 538415e7 conflict
(empty) boom
kkmpptxz test.user@example.com 2001-02-03 08:05:10 1e8c2956
First part of conflicting change
zsuskuln test.user@example.com 2001-02-03 08:05:11 2c8b19fd
Second part of conflicting change
qpvuntsm test.user@example.com 2001-02-03 08:05:08 aade7195
Initial contents
zzzzzzzz root() 00000000
"###);
let stdout = test_env.jj_cmd_success(&repo_path, &["status"]);
insta::assert_snapshot!(stdout, @r###"
Working copy changes:
M conflicted.txt
Working copy : znkkpsqq 897d589f fixed 1
Parent commit: yqosqzyt 65143fef (conflict) (empty) boom-cont-2
Conflict in parent commit has been resolved in working copy
"###);
// Step back to all the way to `root()+` so that wc has no conflict, even though
// there is a conflict later in the tree. So that we can confirm
// our hinting logic doesn't get confused.
test_env.jj_cmd_ok(&repo_path, &["edit", "root()+"]);
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-r", "::"]);
insta::assert_snapshot!(stdout, @r###"
kpqxywon test.user@example.com 2001-02-03 08:05:18 3432159f
fixed 2
znkkpsqq test.user@example.com 2001-02-03 08:05:17 897d589f
fixed 1
× yqosqzyt test.user@example.com 2001-02-03 08:05:13 65143fef conflict
(empty) boom-cont-2
× royxmykx test.user@example.com 2001-02-03 08:05:12 a4e88714 conflict
(empty) boom-cont
× mzvwutvl test.user@example.com 2001-02-03 08:05:11 538415e7 conflict
(empty) boom
kkmpptxz test.user@example.com 2001-02-03 08:05:10 1e8c2956
First part of conflicting change
zsuskuln test.user@example.com 2001-02-03 08:05:11 2c8b19fd
Second part of conflicting change
@ qpvuntsm test.user@example.com 2001-02-03 08:05:08 aade7195
Initial contents
zzzzzzzz root() 00000000
"###);
let stdout = test_env.jj_cmd_success(&repo_path, &["status"]);
insta::assert_snapshot!(stdout, @r###"
Working copy changes:
A conflicted.txt
Working copy : qpvuntsm aade7195 Initial contents
Parent commit: zzzzzzzz 00000000 (empty) (no description set)
"###);
} }
#[test] #[test]