Skip to content

Commit 0762846

Browse files
committed
Implement text and binary merge algorithms, also with baseline tests for correctness.
1 parent 9efa09f commit 0762846

File tree

16 files changed

+1788
-168
lines changed

16 files changed

+1788
-168
lines changed

Cargo.lock

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crate-status.md

+10-6
Original file line numberDiff line numberDiff line change
@@ -324,19 +324,23 @@ Check out the [performance discussion][gix-diff-performance] as well.
324324
* [x] prepare invocation of external diff program
325325
- [ ] pass meta-info
326326
* [ ] working with hunks of data
327+
* [ ] diff-heuristics match Git perfectly
327328
* [x] API documentation
328329
* [ ] Examples
329330

331+
[gix-diff-performance]: https://github.com/Byron/gitoxide/discussions/74
332+
330333
### gix-merge
331334

332-
* [ ] three-way merge analysis of blobs with choice of how to resolve conflicts
335+
* [x] three-way merge analysis of blobs with choice of how to resolve conflicts
333336
- [ ] choose how to resolve conflicts on the data-structure
334337
- [ ] produce a new blob based on data-structure containing possible resolutions
335-
- [ ] `merge` style
336-
- [ ] `diff3` style
337-
- [ ] `zdiff` style
338-
339-
[gix-diff-performance]: https://github.com/Byron/gitoxide/discussions/74
338+
- [x] `merge` style
339+
- [x] `diff3` style
340+
- [x] `zdiff` style
341+
* [ ] diff-heuristics match Git perfectly
342+
* [x] API documentation
343+
* [ ] Examples
340344

341345
### gix-traverse
342346

gix-merge/Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ serde = { version = "1.0.114", optional = true, default-features = false, featur
3939

4040
document-features = { version = "0.2.0", optional = true }
4141

42+
[dev-dependencies]
43+
gix-testtools = { path = "../tests/tools" }
44+
pretty_assertions = "1.4.0"
45+
4246
[package.metadata.docs.rs]
4347
all-features = true
4448
features = ["document-features"]

gix-merge/src/blob/builtin_driver.rs

-156
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/// What to do when having to pick a side to resolve a conflict.
2+
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
3+
pub enum ResolveWith {
4+
/// Chose the ancestor to resolve a conflict.
5+
Ancestor,
6+
/// Chose our side to resolve a conflict.
7+
Ours,
8+
/// Chose their side to resolve a conflict.
9+
Theirs,
10+
}
11+
12+
/// Tell the caller of [`merge()`](function::merge) which side was picked.
13+
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
14+
pub enum Pick {
15+
/// Chose the ancestor.
16+
Ancestor,
17+
/// Chose our side.
18+
Ours,
19+
/// Chose their side.
20+
Theirs,
21+
}
22+
23+
pub(super) mod function {
24+
use crate::blob::builtin_driver::binary::{Pick, ResolveWith};
25+
use crate::blob::Resolution;
26+
27+
/// As this algorithm doesn't look at the actual data, it returns a choice solely based on logic.
28+
///
29+
/// It always results in a conflict with `current` being picked unless `on_conflict` is not `None`.
30+
pub fn merge(on_conflict: Option<ResolveWith>) -> (Pick, Resolution) {
31+
match on_conflict {
32+
None => (Pick::Ours, Resolution::Conflict),
33+
Some(resolve) => (
34+
match resolve {
35+
ResolveWith::Ours => Pick::Ours,
36+
ResolveWith::Theirs => Pick::Theirs,
37+
ResolveWith::Ancestor => Pick::Ancestor,
38+
},
39+
Resolution::Complete,
40+
),
41+
}
42+
}
43+
}
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use crate::blob::BuiltinDriver;
2+
3+
impl BuiltinDriver {
4+
/// Return the name of this instance.
5+
pub fn as_str(&self) -> &str {
6+
match self {
7+
BuiltinDriver::Text => "text",
8+
BuiltinDriver::Binary => "binary",
9+
BuiltinDriver::Union => "union",
10+
}
11+
}
12+
13+
/// Get all available built-in drivers.
14+
pub fn all() -> &'static [Self] {
15+
&[BuiltinDriver::Text, BuiltinDriver::Binary, BuiltinDriver::Union]
16+
}
17+
18+
/// Try to match one of our variants to `name`, case-sensitive, and return its instance.
19+
pub fn by_name(name: &str) -> Option<Self> {
20+
Self::all().iter().find(|variant| variant.as_str() == name).copied()
21+
}
22+
}
23+
24+
///
25+
pub mod binary;
26+
pub use binary::function::merge as binary;
27+
28+
///
29+
pub mod text;
30+
pub use text::function::merge as text;

0 commit comments

Comments
 (0)