Skip to content

Commit

Permalink
next/prev: Fetch descendants with more correctness.
Browse files Browse the repository at this point in the history
See context in [this discussion](#3935 (comment))

Fixes #3947
  • Loading branch information
essiene committed Sep 17, 2024
1 parent 6d0a092 commit e25ec53
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 16 deletions.
32 changes: 16 additions & 16 deletions cli/src/movement_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,27 +121,27 @@ impl Direction {
start_revset: &Rc<RevsetExpression>,
args: &MovementArgsInternal,
) -> Result<Rc<RevsetExpression>, CommandError> {
let target_revset = match (self, args.conflict) {
(Direction::Next, true) => start_revset
let nth = match (self, args.should_edit) {
(Direction::Next, true) => start_revset.descendants_at(args.offset),
(Direction::Next, false) => start_revset
.children()
.minus(working_revset)
.descendants_at(args.offset - 1),
(Direction::Prev, _) => start_revset.ancestors_at(args.offset),
};

let target_revset = match (self, args.conflict) {
(_, false) => nth,
(Direction::Next, true) => nth
.descendants()
.filtered(RevsetFilterPredicate::HasConflict)
.roots()
.minus(working_revset),
(Direction::Next, false) => start_revset
.descendants_at(args.offset)
.minus(working_revset),
(Direction::Prev, true) =>
.roots(),
// If people desire to move to the root conflict, replace the `heads()` below
// with `roots(). But let's wait for feedback.
{
start_revset
.parents()
.ancestors()
.filtered(RevsetFilterPredicate::HasConflict)
.heads()
}
(Direction::Prev, false) => start_revset.ancestors_at(args.offset),
(Direction::Prev, true) => nth
.ancestors()
.filtered(RevsetFilterPredicate::HasConflict)
.heads(),
};

Ok(target_revset)
Expand Down
75 changes: 75 additions & 0 deletions cli/tests/test_next_prev_commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1112,6 +1112,81 @@ fn test_movement_edit_mode_false() {
"###);
}

#[test]
fn test_next_offset_when_wc_has_descendants() {
let test_env = TestEnvironment::default();
test_env.add_config(r#"ui.movement.edit = false"#);

test_env.jj_cmd_ok(test_env.env_root(), &["init", "repo", "--git"]);
let repo_path = test_env.env_root().join("repo");

test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "base"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "right-wc"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "right-1"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "right-2"]);

test_env.jj_cmd_ok(&repo_path, &["new", "description(base)"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "left-wc"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "left-1"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "left-2"]);

test_env.jj_cmd_ok(&repo_path, &["edit", "description(right-wc)"]);
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
○ vruxwmqvtpmx left-2
○ yqosqzytrlsw left-1
○ royxmykxtrkr left-wc
│ ○ zsuskulnrvyr right-2
│ ○ kkmpptxzrspx right-1
│ @ rlvkpnrzqnoo right-wc
├─╯
○ qpvuntsmwlqt base
◆ zzzzzzzzzzzz
"###);

test_env.jj_cmd_ok(&repo_path, &["next", "2"]);
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
@ kmkuslswpqwq
│ ○ vruxwmqvtpmx left-2
├─╯
○ yqosqzytrlsw left-1
○ royxmykxtrkr left-wc
│ ○ zsuskulnrvyr right-2
│ ○ kkmpptxzrspx right-1
│ ○ rlvkpnrzqnoo right-wc
├─╯
○ qpvuntsmwlqt base
◆ zzzzzzzzzzzz
"###);

test_env.jj_cmd_ok(&repo_path, &["edit", "description(left-wc)"]);
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
○ vruxwmqvtpmx left-2
○ yqosqzytrlsw left-1
@ royxmykxtrkr left-wc
│ ○ zsuskulnrvyr right-2
│ ○ kkmpptxzrspx right-1
│ ○ rlvkpnrzqnoo right-wc
├─╯
○ qpvuntsmwlqt base
◆ zzzzzzzzzzzz
"###);

test_env.jj_cmd_ok(&repo_path, &["next"]);
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
@ nkmrtpmomlro
│ ○ zsuskulnrvyr right-2
│ ○ kkmpptxzrspx right-1
├─╯
○ rlvkpnrzqnoo right-wc
│ ○ vruxwmqvtpmx left-2
│ ○ yqosqzytrlsw left-1
│ ○ royxmykxtrkr left-wc
├─╯
○ qpvuntsmwlqt base
◆ zzzzzzzzzzzz
"###);
}

fn get_log_output(test_env: &TestEnvironment, cwd: &Path) -> String {
let template = r#"separate(" ", change_id.short(), local_bookmarks, if(conflict, "conflict"), description)"#;
test_env.jj_cmd_success(cwd, &["log", "-T", template])
Expand Down

0 comments on commit e25ec53

Please sign in to comment.