Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
* `jj squash` has gained `--insert-before`, `--insert-after`, and `--destination`
options.

* Merge tools can use the `$path` argument to learn where the file they
are merging will end up in the repository.

### Fixed bugs

* `jj git clone` now correctly fetches all tags, unless `--fetch-tags` is
Expand Down
2 changes: 1 addition & 1 deletion cli/src/config/merge_tools.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ edit-args = ["$left", "$output", "$right", "-o", "$output"]
# algorithm doesn't always maintain comments and spacing in the merge output
# (even parts without conflicts), but you can remove it if you want to use a full structural merge.
program = "mergiraf"
merge-args = ["merge", "$base", "$left", "$right", "-o", "$output", "-l", "$marker_length", "--fast"]
merge-args = ["merge", "$base", "$left", "$right", "-o", "$output", "-l", "$marker_length", "-p", "$path", "--fast"]
merge-conflict-exit-codes = [1]
# Non-interactive merge tool
edit-args = []
Expand Down
1 change: 1 addition & 0 deletions cli/src/merge_tools/external.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ fn run_mergetool_external_single_file(
})
.try_collect()?;
variables.insert("marker_length", conflict_marker_len.to_string());
variables.insert("path", repo_path.as_internal_file_string().to_string());

let mut cmd = Command::new(&editor.program);
cmd.args(interpolate_variables(&editor.merge_args, &variables));
Expand Down
74 changes: 74 additions & 0 deletions cli/tests/test_resolve_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1364,6 +1364,80 @@ fn test_resolve_change_delete_executable() {
");
}

#[test]
fn test_pass_path_argument() {
let mut test_env = TestEnvironment::default();
let editor_script = test_env.set_up_fake_editor();
test_env.run_jj_in(".", ["git", "init", "repo"]).success();
let work_dir = test_env.work_dir("repo");

// Makes it easier to read the diffs between conflicts
test_env.add_config("ui.conflict-marker-style = 'snapshot'");

// Create a conflict
create_commit_with_files(&work_dir, "base", &[], &[("file", "base\n")]);
create_commit_with_files(&work_dir, "a", &["base"], &[("file", "a\n")]);
create_commit_with_files(&work_dir, "b", &["base"], &[("file", "b\n")]);
create_commit_with_files(&work_dir, "conflict", &["a", "b"], &[]);
insta::assert_snapshot!(work_dir.run_jj(["resolve", "--list"]), @r"
file 2-sided conflict
[EOF]
");
insta::assert_snapshot!(work_dir.read_file("file"), @r"
<<<<<<< Conflict 1 of 1
+++++++ Contents of side #1
a
------- Contents of base
base
+++++++ Contents of side #2
b
>>>>>>> Conflict 1 of 1 ends
"
);

// If the merge tool accepts the "$path" argument, then it should be passed
std::fs::write(
&editor_script,
indoc! {b"
expect-arg 0
file\0write
resolution
\0"},
)
.unwrap();
let output = work_dir.run_jj([
"resolve",
"file",
r#"--config=merge-tools.fake-editor.merge-args=["$output", "$path"]"#,
]);
insta::assert_snapshot!(output, @r###"
------- stderr -------
Resolving conflicts in: file
Working copy (@) now at: vruxwmqv 682816de conflict | conflict
Parent commit (@-) : zsuskuln 45537d53 a | a
Parent commit (@-) : royxmykx 89d1b299 b | b
Added 0 files, modified 1 files, removed 0 files
[EOF]
"###);
insta::assert_snapshot!(work_dir.run_jj(["diff", "--git"]), @r"
diff --git a/file b/file
index 0000000000..88425ec521 100644
--- a/file
+++ b/file
@@ -1,8 +1,1 @@
-<<<<<<< Conflict 1 of 1
-+++++++ Contents of side #1
-a
-------- Contents of base
-base
-+++++++ Contents of side #2
-b
->>>>>>> Conflict 1 of 1 ends
+resolution
[EOF]
");
}

#[test]
fn test_resolve_long_conflict_markers() {
let mut test_env = TestEnvironment::default();
Expand Down
4 changes: 4 additions & 0 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -1147,6 +1147,10 @@ merge-tool-edits-conflict-markers = true # See below for an explanation
and/or generates conflict markers. Usually, `jj` uses conflict markers of
length 7, but they can be longer if necessary to make parsing unambiguous.

- `$path` is replaced with the path in the repository at which the file
will be eventually stored. It is relative to the root directory of the
repository and uses `/` as separators.

Unlike `diff-args` or `edit-args`, there is no default value for `merge-args`.
If `merge-args` are not specified, the tool cannot be used for conflict
resolution.
Expand Down