Skip to content

Commit

Permalink
conflicts: add "snapshot" conflict marker style
Browse files Browse the repository at this point in the history
Adds a new "snapshot" conflict marker style which returns a series of
snapshots, similar to Git's "diff3" conflict style. The "snapshot"
option uses a subset of the conflict hunk headers as the "diff" option
(it just doesn't use "%%%%%%%"), meaning that the two options are
trivially compatible with each other (i.e. a file materialized with
"snapshot" can be parsed with "diff" and vice versa).

Example of "snapshot" conflict markers:

```
<<<<<<< Conflict 1 of 1
+++++++ Contents of side #1
fn example(word: String) {
    println!("word is {word}");
------- Contents of base
fn example(w: String) {
    println!("word is {w}");
+++++++ Contents of side #2
fn example(w: &str) {
    println!("word is {w}");
>>>>>>> Conflict 1 of 1 ends
}
```
  • Loading branch information
scott2000 committed Nov 23, 2024
1 parent 863cba3 commit d2b06b9
Show file tree
Hide file tree
Showing 4 changed files with 367 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
* New `ui.conflict-marker-style` config option to change how conflicts are
materialized in the working copy. The default option ("diff") renders
conflicts as a snapshot with a list of diffs to apply to the snapshot.
The new "snapshot" option renders conflicts as a series of snapshots, showing
each side and base of the conflict.

### Fixed bugs

Expand Down
3 changes: 2 additions & 1 deletion cli/src/config-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,8 @@
"type": "string",
"description": "Conflict marker style to use when materializing conflicts in the working copy",
"enum": [
"diff"
"diff",
"snapshot"
],
"default": "diff"
}
Expand Down
13 changes: 12 additions & 1 deletion lib/src/conflicts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ pub enum ConflictMarkerStyle {
/// Style which shows a snapshot and a series of diffs to apply.
#[default]
Diff,
/// Style which shows a snapshot for each base and side.
Snapshot,
}

pub fn materialize_merge_result<T: AsRef<[u8]>>(
Expand Down Expand Up @@ -274,7 +276,7 @@ pub fn materialize_merge_result_to_bytes<T: AsRef<[u8]>>(

fn materialize_conflict_hunks(
hunks: &[Merge<BString>],
_conflict_marker_style: ConflictMarkerStyle,
conflict_marker_style: ConflictMarkerStyle,
output: &mut dyn Write,
) -> io::Result<()> {
// Write a positive snapshot (side) of a conflict
Expand Down Expand Up @@ -338,6 +340,15 @@ fn materialize_conflict_hunks(
write_base(&base_str, left, output)?;
continue;
};

// For any style other than "diff", always emit sides and bases separately
if conflict_marker_style != ConflictMarkerStyle::Diff {
write_side(add_index, right1, output)?;
write_base(&base_str, left, output)?;
add_index += 1;
continue;
}

let diff1 = Diff::by_line([&left, &right1]).hunks().collect_vec();
// Check if the diff against the next positive term is better. Since
// we want to preserve the order of the terms, we don't match against
Expand Down
Loading

0 comments on commit d2b06b9

Please sign in to comment.