Skip to content

Commit a57192c

Browse files
committed
fix: when binary merges are performed, adjust the returned resolution to indicate auto-resolution.
Previously it wasn't possible to detect auto-resolution, even though it can be assumed if a resolution mode was provided.
1 parent 1435193 commit a57192c

File tree

4 files changed

+73
-14
lines changed

4 files changed

+73
-14
lines changed

gix-merge/src/blob/builtin_driver/binary.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ pub(super) mod function {
2525
use crate::blob::Resolution;
2626

2727
/// As this algorithm doesn't look at the actual data, it returns a choice solely based on logic.
28+
/// This also means that the caller has to assure this only gets called if the input *doesn't* match.
2829
///
29-
/// It always results in a conflict with `current` being picked unless `on_conflict` is not `None`.
30+
/// It always results in a conflict with `current` being picked unless `on_conflict` is not `None`,
31+
/// which is when we always return [`Resolution::CompleteWithAutoResolvedConflict`].
3032
pub fn merge(on_conflict: Option<ResolveWith>) -> (Pick, Resolution) {
3133
match on_conflict {
3234
None => (Pick::Ours, Resolution::Conflict),
@@ -36,7 +38,7 @@ pub(super) mod function {
3638
ResolveWith::Theirs => Pick::Theirs,
3739
ResolveWith::Ancestor => Pick::Ancestor,
3840
},
39-
Resolution::Complete,
41+
Resolution::CompleteWithAutoResolvedConflict,
4042
),
4143
}
4244
}

gix-merge/src/blob/platform/merge.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -329,13 +329,21 @@ pub(super) mod inner {
329329
(Pick::Buffer, resolution)
330330
}
331331
BuiltinDriver::Binary => {
332-
let (pick, resolution) = builtin_driver::binary(self.options.resolve_binary_with);
333-
let pick = match pick {
334-
builtin_driver::binary::Pick::Ours => Pick::Ours,
335-
builtin_driver::binary::Pick::Theirs => Pick::Theirs,
336-
builtin_driver::binary::Pick::Ancestor => Pick::Ancestor,
337-
};
338-
(pick, resolution)
332+
// easier to reason about the 'split' compared to merging both conditions
333+
#[allow(clippy::if_same_then_else)]
334+
if !(self.current.id.is_null() || self.other.id.is_null()) && self.current.id == self.other.id {
335+
(Pick::Ours, Resolution::Complete)
336+
} else if (self.current.id.is_null() || self.other.id.is_null()) && ours == theirs {
337+
(Pick::Ours, Resolution::Complete)
338+
} else {
339+
let (pick, resolution) = builtin_driver::binary(self.options.resolve_binary_with);
340+
let pick = match pick {
341+
builtin_driver::binary::Pick::Ours => Pick::Ours,
342+
builtin_driver::binary::Pick::Theirs => Pick::Theirs,
343+
builtin_driver::binary::Pick::Ancestor => Pick::Ancestor,
344+
};
345+
(pick, resolution)
346+
}
339347
}
340348
BuiltinDriver::Union => {
341349
let resolution = builtin_driver::text(

gix-merge/tests/merge/blob/builtin_driver.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@ fn binary() {
1010
);
1111
assert_eq!(
1212
builtin_driver::binary(Some(ResolveWith::Ancestor)),
13-
(Pick::Ancestor, Resolution::Complete),
13+
(Pick::Ancestor, Resolution::CompleteWithAutoResolvedConflict),
1414
"Otherwise we can pick anything and it will mark it as complete"
1515
);
1616
assert_eq!(
1717
builtin_driver::binary(Some(ResolveWith::Ours)),
18-
(Pick::Ours, Resolution::Complete)
18+
(Pick::Ours, Resolution::CompleteWithAutoResolvedConflict)
1919
);
2020
assert_eq!(
2121
builtin_driver::binary(Some(ResolveWith::Theirs)),
22-
(Pick::Theirs, Resolution::Complete)
22+
(Pick::Theirs, Resolution::CompleteWithAutoResolvedConflict)
2323
);
2424
}
2525

gix-merge/tests/merge/blob/platform.rs

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,61 @@ mod merge {
5959
let res = platform_ref.merge(&mut buf, default_labels(), &Default::default())?;
6060
assert_eq!(
6161
res,
62-
(Pick::Theirs, Resolution::Complete),
62+
(Pick::Theirs, Resolution::CompleteWithAutoResolvedConflict),
6363
"the auto-binary driver respects its own options"
6464
);
6565
Ok(())
6666
}
6767

68+
#[test]
69+
fn same_binaries_do_not_count_as_conflicted() -> crate::Result {
70+
let mut platform = new_platform(None, pipeline::Mode::ToGit);
71+
platform.set_resource(
72+
gix_hash::Kind::Sha1.null(),
73+
EntryKind::Blob,
74+
"a".into(),
75+
ResourceKind::CommonAncestorOrBase,
76+
&gix_object::find::Never,
77+
)?;
78+
79+
let mut db = ObjectDb::default();
80+
for (content, kind) in [
81+
("any\0", ResourceKind::CurrentOrOurs),
82+
("any\0", ResourceKind::OtherOrTheirs),
83+
] {
84+
let id = db.insert(content);
85+
platform.set_resource(
86+
id,
87+
EntryKind::Blob,
88+
"path matters only for attribute lookup".into(),
89+
kind,
90+
&db,
91+
)?;
92+
}
93+
let platform_ref = platform.prepare_merge(&db, Default::default())?;
94+
assert_eq!(
95+
platform_ref.driver,
96+
DriverChoice::BuiltIn(BuiltinDriver::Text),
97+
"it starts out at the default text driver"
98+
);
99+
100+
let mut buf = Vec::new();
101+
let res = platform_ref.merge(&mut buf, default_labels(), &Default::default())?;
102+
assert_eq!(
103+
res,
104+
(Pick::Ours, Resolution::Complete),
105+
"as both are the same, it just picks ours, declaring it non-conflicting"
106+
);
107+
108+
let mut input = imara_diff::intern::InternedInput::new(&[][..], &[]);
109+
assert_eq!(
110+
platform_ref.builtin_merge(BuiltinDriver::Binary, &mut buf, &mut input, default_labels()),
111+
res,
112+
"no way to work around it - calling the built-in binary merge is the same"
113+
);
114+
Ok(())
115+
}
116+
68117
#[test]
69118
fn builtin_with_conflict() -> crate::Result {
70119
let mut platform = new_platform(None, pipeline::Mode::ToGit);
@@ -192,7 +241,7 @@ theirs
192241
] {
193242
platform_ref.options.resolve_binary_with = Some(resolve);
194243
let res = platform_ref.merge(&mut buf, default_labels(), &Default::default())?;
195-
assert_eq!(res, (expected_pick, Resolution::Complete));
244+
assert_eq!(res, (expected_pick, Resolution::CompleteWithAutoResolvedConflict));
196245
assert_eq!(platform_ref.buffer_by_pick(res.0).unwrap().unwrap().as_bstr(), expected);
197246

198247
assert_eq!(

0 commit comments

Comments
 (0)