Skip to content

Commit f795177

Browse files
committed
conflicts: propagate conflict labels down to materialization functions
1 parent 5773148 commit f795177

File tree

15 files changed

+205
-68
lines changed

15 files changed

+205
-68
lines changed

cli/src/commands/file/show.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use jj_lib::conflicts::materialize_tree_value;
2424
use jj_lib::file_util::copy_async_to_sync;
2525
use jj_lib::fileset::FilePattern;
2626
use jj_lib::fileset::FilesetExpression;
27+
use jj_lib::merged_tree::MergedTree;
2728
use jj_lib::repo::Repo as _;
2829
use jj_lib::repo_path::RepoPath;
2930
use pollster::FutureExt as _;
@@ -117,7 +118,7 @@ pub(crate) fn cmd_file_show(
117118
path: path.to_owned(),
118119
value,
119120
};
120-
write_tree_entries(ui, &workspace_command, &template, [Ok(entry)])?;
121+
write_tree_entries(ui, &workspace_command, &template, &tree, [Ok(entry)])?;
121122
return Ok(());
122123
}
123124
}
@@ -128,6 +129,7 @@ pub(crate) fn cmd_file_show(
128129
ui,
129130
&workspace_command,
130131
&template,
132+
&tree,
131133
tree.entries_matching(matcher.as_ref())
132134
.map(|(path, value)| Ok((path, value?)))
133135
.map_ok(|(path, value)| TreeEntry { path, value }),
@@ -152,14 +154,16 @@ fn write_tree_entries(
152154
ui: &Ui,
153155
workspace_command: &WorkspaceCommandHelper,
154156
template: &TemplateRenderer<TreeEntry>,
157+
tree: &MergedTree,
155158
entries: impl IntoIterator<Item = BackendResult<TreeEntry>>,
156159
) -> Result<(), CommandError> {
157160
let repo = workspace_command.repo();
158161
for entry in entries {
159162
let entry = entry?;
160163
template.format(&entry, ui.stdout_formatter().as_mut())?;
161164
let materialized =
162-
materialize_tree_value(repo.store(), &entry.path, entry.value).block_on()?;
165+
materialize_tree_value(repo.store(), &entry.path, entry.value, tree.labels())
166+
.block_on()?;
163167
match materialized {
164168
MaterializedTreeValue::Absent => panic!("absent values should be excluded"),
165169
MaterializedTreeValue::AccessDenied(err) => {
@@ -178,7 +182,12 @@ fn write_tree_entries(
178182
marker_len: None,
179183
merge: repo.store().merge_options().clone(),
180184
};
181-
materialize_merge_result(&file.contents, &mut ui.stdout_formatter(), &options)?;
185+
materialize_merge_result(
186+
&file.contents,
187+
&file.labels,
188+
&mut ui.stdout_formatter(),
189+
&options,
190+
)?;
182191
}
183192
MaterializedTreeValue::OtherConflict { id } => {
184193
ui.stdout_formatter().write_all(id.describe().as_bytes())?;

cli/src/commit_templater.rs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,7 +2146,12 @@ impl TreeDiff {
21462146

21472147
fn into_formatted<F, E>(self, show: F) -> TreeDiffFormatted<F>
21482148
where
2149-
F: Fn(&mut dyn Formatter, &Store, BoxStream<CopiesTreeDiffEntry>) -> Result<(), E>,
2149+
F: Fn(
2150+
&mut dyn Formatter,
2151+
&Store,
2152+
Diff<&MergedTree>,
2153+
BoxStream<CopiesTreeDiffEntry>,
2154+
) -> Result<(), E>,
21502155
E: Into<TemplatePropertyError>,
21512156
{
21522157
TreeDiffFormatted { diff: self, show }
@@ -2161,14 +2166,21 @@ struct TreeDiffFormatted<F> {
21612166

21622167
impl<F, E> Template for TreeDiffFormatted<F>
21632168
where
2164-
F: Fn(&mut dyn Formatter, &Store, BoxStream<CopiesTreeDiffEntry>) -> Result<(), E>,
2169+
F: Fn(
2170+
&mut dyn Formatter,
2171+
&Store,
2172+
Diff<&MergedTree>,
2173+
BoxStream<CopiesTreeDiffEntry>,
2174+
) -> Result<(), E>,
21652175
E: Into<TemplatePropertyError>,
21662176
{
21672177
fn format(&self, formatter: &mut TemplateFormatter) -> io::Result<()> {
21682178
let show = &self.show;
21692179
let store = self.diff.from_tree.store();
2180+
let trees = Diff::new(&self.diff.from_tree, &self.diff.to_tree);
21702181
let tree_diff = self.diff.diff_stream();
2171-
show(formatter.as_mut(), store, tree_diff).or_else(|err| formatter.handle_error(err.into()))
2182+
show(formatter.as_mut(), store, trees, tree_diff)
2183+
.or_else(|err| formatter.handle_error(err.into()))
21722184
}
21732185
}
21742186

@@ -2214,10 +2226,11 @@ fn builtin_tree_diff_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, T
22142226
if let Some(context) = context {
22152227
options.context = context;
22162228
}
2217-
diff.into_formatted(move |formatter, store, tree_diff| {
2229+
diff.into_formatted(move |formatter, store, trees, tree_diff| {
22182230
diff_util::show_color_words_diff(
22192231
formatter,
22202232
store,
2233+
trees,
22212234
tree_diff,
22222235
path_converter,
22232236
&options,
@@ -2256,10 +2269,11 @@ fn builtin_tree_diff_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, T
22562269
if let Some(context) = context {
22572270
options.context = context;
22582271
}
2259-
diff.into_formatted(move |formatter, store, tree_diff| {
2272+
diff.into_formatted(move |formatter, store, trees, tree_diff| {
22602273
diff_util::show_git_diff(
22612274
formatter,
22622275
store,
2276+
trees,
22632277
tree_diff,
22642278
&options,
22652279
conflict_marker_style,
@@ -2312,7 +2326,7 @@ fn builtin_tree_diff_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, T
23122326
let path_converter = language.path_converter;
23132327
let template = self_property
23142328
.map(move |diff| {
2315-
diff.into_formatted(move |formatter, _store, tree_diff| {
2329+
diff.into_formatted(move |formatter, _store, _trees, tree_diff| {
23162330
diff_util::show_diff_summary(formatter, tree_diff, path_converter)
23172331
.block_on()
23182332
})

cli/src/diff_util.rs

Lines changed: 64 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use jj_lib::backend::CopyRecord;
3535
use jj_lib::backend::TreeValue;
3636
use jj_lib::commit::Commit;
3737
use jj_lib::config::ConfigGetError;
38+
use jj_lib::conflict_labels::ConflictLabels;
3839
use jj_lib::conflicts::ConflictMarkerStyle;
3940
use jj_lib::conflicts::ConflictMaterializeOptions;
4041
use jj_lib::conflicts::MaterializedTreeDiffEntry;
@@ -463,6 +464,7 @@ impl<'a> DiffRenderer<'a> {
463464
width: usize,
464465
) -> Result<(), DiffRenderError> {
465466
let store = self.repo.store();
467+
let trees = Diff::new(from_tree, to_tree);
466468
let path_converter = self.path_converter;
467469
for format in &self.formats {
468470
match format {
@@ -495,6 +497,7 @@ impl<'a> DiffRenderer<'a> {
495497
show_git_diff(
496498
formatter,
497499
store,
500+
trees,
498501
tree_diff,
499502
options,
500503
self.conflict_marker_style,
@@ -507,6 +510,7 @@ impl<'a> DiffRenderer<'a> {
507510
show_color_words_diff(
508511
formatter,
509512
store,
513+
trees,
510514
tree_diff,
511515
path_converter,
512516
options,
@@ -523,6 +527,7 @@ impl<'a> DiffRenderer<'a> {
523527
ui,
524528
formatter,
525529
store,
530+
trees,
526531
tree_diff,
527532
path_converter,
528533
tool,
@@ -587,7 +592,8 @@ impl<'a> DiffRenderer<'a> {
587592
writeln!(formatter.labeled("header"), "Modified commit description:")?;
588593
show_color_words_diff_hunks(
589594
formatter,
590-
[from_description, to_description],
595+
Diff::new(from_description, to_description)
596+
.map(|description| (description, ConflictLabels::unlabeled())),
591597
options,
592598
&materialize_options,
593599
)?;
@@ -753,10 +759,14 @@ impl ColorWordsDiffOptions {
753759

754760
fn show_color_words_diff_hunks<T: AsRef<[u8]>>(
755761
formatter: &mut dyn Formatter,
756-
[lefts, rights]: [&Merge<T>; 2],
762+
contents: Diff<(&Merge<T>, ConflictLabels)>,
757763
options: &ColorWordsDiffOptions,
758764
materialize_options: &ConflictMaterializeOptions,
759765
) -> io::Result<()> {
766+
let Diff {
767+
before: (lefts, left_labels),
768+
after: (rights, right_labels),
769+
} = contents;
760770
let line_number = DiffLineNumber { left: 1, right: 1 };
761771
let labels = ["removed", "added"];
762772
if let (Some(left), Some(right)) = (lefts.as_resolved(), rights.as_resolved()) {
@@ -766,8 +776,9 @@ fn show_color_words_diff_hunks<T: AsRef<[u8]>>(
766776
}
767777
match options.conflict {
768778
ConflictDiffMethod::Materialize => {
769-
let left = materialize_merge_result_to_bytes(lefts, materialize_options);
770-
let right = materialize_merge_result_to_bytes(rights, materialize_options);
779+
let left = materialize_merge_result_to_bytes(lefts, &left_labels, materialize_options);
780+
let right =
781+
materialize_merge_result_to_bytes(rights, &right_labels, materialize_options);
771782
let contents = [&left, &right].map(BStr::new);
772783
show_color_words_resolved_hunks(formatter, contents, line_number, labels, options)?;
773784
}
@@ -1204,22 +1215,29 @@ fn diff_content(
12041215
path,
12051216
value,
12061217
|content| content,
1207-
|contents| materialize_merge_result_to_bytes(&contents, materialize_options),
1218+
|contents, labels| {
1219+
materialize_merge_result_to_bytes(&contents, &labels, materialize_options)
1220+
},
12081221
)
12091222
}
12101223

12111224
fn diff_content_as_merge(
12121225
path: &RepoPath,
12131226
value: MaterializedTreeValue,
1214-
) -> BackendResult<FileContent<Merge<BString>>> {
1215-
diff_content_with(path, value, Merge::resolved, |contents| contents)
1227+
) -> BackendResult<FileContent<(Merge<BString>, ConflictLabels)>> {
1228+
diff_content_with(
1229+
path,
1230+
value,
1231+
|contents| (Merge::resolved(contents), ConflictLabels::unlabeled()),
1232+
|contents, labels| (contents, labels),
1233+
)
12161234
}
12171235

12181236
fn diff_content_with<T>(
12191237
path: &RepoPath,
12201238
value: MaterializedTreeValue,
12211239
map_resolved: impl FnOnce(BString) -> T,
1222-
map_conflict: impl FnOnce(Merge<BString>) -> T,
1240+
map_conflict: impl FnOnce(Merge<BString>, ConflictLabels) -> T,
12231241
) -> BackendResult<FileContent<T>> {
12241242
match value {
12251243
MaterializedTreeValue::Absent => Ok(FileContent {
@@ -1245,7 +1263,7 @@ fn diff_content_with<T>(
12451263
// TODO: are we sure this is never binary?
12461264
MaterializedTreeValue::FileConflict(file) => Ok(FileContent {
12471265
is_binary: false,
1248-
contents: map_conflict(file.contents),
1266+
contents: map_conflict(file.contents, file.labels),
12491267
}),
12501268
MaterializedTreeValue::OtherConflict { id } => Ok(FileContent {
12511269
is_binary: false,
@@ -1282,6 +1300,7 @@ fn basic_diff_file_type(value: &MaterializedTreeValue) -> &'static str {
12821300
pub async fn show_color_words_diff(
12831301
formatter: &mut dyn Formatter,
12841302
store: &Store,
1303+
trees: Diff<&MergedTree>,
12851304
tree_diff: BoxStream<'_, CopiesTreeDiffEntry>,
12861305
path_converter: &RepoPathUiConverter,
12871306
options: &ColorWordsDiffOptions,
@@ -1292,8 +1311,9 @@ pub async fn show_color_words_diff(
12921311
marker_len: None,
12931312
merge: store.merge_options().clone(),
12941313
};
1314+
let conflict_labels = trees.map(|tree| tree.labels());
12951315
let empty_content = || Merge::resolved(BString::default());
1296-
let mut diff_stream = materialized_diff_stream(store, tree_diff);
1316+
let mut diff_stream = materialized_diff_stream(store, tree_diff, conflict_labels);
12971317
while let Some(MaterializedTreeDiffEntry { path, values }) = diff_stream.next().await {
12981318
let left_path = path.source();
12991319
let right_path = path.target();
@@ -1334,7 +1354,10 @@ pub async fn show_color_words_diff(
13341354
} else {
13351355
show_color_words_diff_hunks(
13361356
formatter,
1337-
[&empty_content(), &right_content.contents],
1357+
Diff::new(
1358+
(&empty_content(), ConflictLabels::unlabeled()),
1359+
(&right_content.contents.0, right_content.contents.1),
1360+
),
13381361
options,
13391362
&materialize_options,
13401363
)?;
@@ -1401,7 +1424,10 @@ pub async fn show_color_words_diff(
14011424
} else if left_content.contents != right_content.contents {
14021425
show_color_words_diff_hunks(
14031426
formatter,
1404-
[&left_content.contents, &right_content.contents],
1427+
Diff::new(
1428+
(&left_content.contents.0, left_content.contents.1),
1429+
(&right_content.contents.0, right_content.contents.1),
1430+
),
14051431
options,
14061432
&materialize_options,
14071433
)?;
@@ -1420,7 +1446,10 @@ pub async fn show_color_words_diff(
14201446
} else {
14211447
show_color_words_diff_hunks(
14221448
formatter,
1423-
[&left_content.contents, &empty_content()],
1449+
Diff::new(
1450+
(&left_content.contents.0, left_content.contents.1),
1451+
(&empty_content(), ConflictLabels::unlabeled()),
1452+
),
14241453
options,
14251454
&materialize_options,
14261455
)?;
@@ -1435,6 +1464,7 @@ pub async fn show_file_by_file_diff(
14351464
ui: &Ui,
14361465
formatter: &mut dyn Formatter,
14371466
store: &Store,
1467+
trees: Diff<&MergedTree>,
14381468
tree_diff: BoxStream<'_, CopiesTreeDiffEntry>,
14391469
path_converter: &RepoPathUiConverter,
14401470
tool: &ExternalMergeTool,
@@ -1457,10 +1487,11 @@ pub async fn show_file_by_file_diff(
14571487
Ok(fs_path)
14581488
};
14591489

1490+
let conflict_labels = trees.map(|tree| tree.labels());
14601491
let temp_dir = new_utf8_temp_dir("jj-diff-")?;
14611492
let left_wc_dir = temp_dir.path().join("left");
14621493
let right_wc_dir = temp_dir.path().join("right");
1463-
let mut diff_stream = materialized_diff_stream(store, tree_diff);
1494+
let mut diff_stream = materialized_diff_stream(store, tree_diff, conflict_labels);
14641495
while let Some(MaterializedTreeDiffEntry { path, values }) = diff_stream.next().await {
14651496
let (left_value, right_value) = values?;
14661497
let left_path = path.source();
@@ -1598,6 +1629,7 @@ fn show_diff_line_tokens(
15981629
pub async fn show_git_diff(
15991630
formatter: &mut dyn Formatter,
16001631
store: &Store,
1632+
trees: Diff<&MergedTree>,
16011633
tree_diff: BoxStream<'_, CopiesTreeDiffEntry>,
16021634
options: &UnifiedDiffOptions,
16031635
marker_style: ConflictMarkerStyle,
@@ -1607,7 +1639,8 @@ pub async fn show_git_diff(
16071639
marker_len: None,
16081640
merge: store.merge_options().clone(),
16091641
};
1610-
let mut diff_stream = materialized_diff_stream(store, tree_diff);
1642+
let conflict_labels = trees.map(|tree| tree.labels());
1643+
let mut diff_stream = materialized_diff_stream(store, tree_diff, conflict_labels);
16111644
while let Some(MaterializedTreeDiffEntry { path, values }) = diff_stream.next().await {
16121645
let left_path = path.source();
16131646
let right_path = path.target();
@@ -1708,6 +1741,7 @@ fn show_git_diff_texts<T: AsRef<[u8]>>(
17081741
Some(text) => Cow::Borrowed(BStr::new(text)),
17091742
None => Cow::Owned(materialize_merge_result_to_bytes(
17101743
content,
1744+
&ConflictLabels::unlabeled(),
17111745
materialize_options,
17121746
)),
17131747
});
@@ -1782,16 +1816,21 @@ impl DiffStats {
17821816
marker_len: None,
17831817
merge: store.merge_options().clone(),
17841818
};
1785-
let entries = materialized_diff_stream(store, tree_diff)
1786-
.map(|MaterializedTreeDiffEntry { path, values }| {
1787-
let (left, right) = values?;
1788-
let left_content = diff_content(path.source(), left, &materialize_options)?;
1789-
let right_content = diff_content(path.target(), right, &materialize_options)?;
1790-
let stat = get_diff_stat_entry(path, [&left_content, &right_content], options);
1791-
BackendResult::Ok(stat)
1792-
})
1793-
.try_collect()
1794-
.await?;
1819+
let conflict_labels = ConflictLabels::unlabeled();
1820+
let entries = materialized_diff_stream(
1821+
store,
1822+
tree_diff,
1823+
Diff::new(&conflict_labels, &conflict_labels),
1824+
)
1825+
.map(|MaterializedTreeDiffEntry { path, values }| {
1826+
let (left, right) = values?;
1827+
let left_content = diff_content(path.source(), left, &materialize_options)?;
1828+
let right_content = diff_content(path.target(), right, &materialize_options)?;
1829+
let stat = get_diff_stat_entry(path, [&left_content, &right_content], options);
1830+
BackendResult::Ok(stat)
1831+
})
1832+
.try_collect()
1833+
.await?;
17951834
Ok(Self { entries })
17961835
}
17971836

0 commit comments

Comments
 (0)