Skip to content

Commit

Permalink
Merge pull request #1612 from Byron/merge
Browse files Browse the repository at this point in the history
octopus-merge (part 4: tree-merge-ORT three-way)
  • Loading branch information
Byron authored Oct 8, 2024
2 parents f35b109 + 3745212 commit 37c1e4c
Show file tree
Hide file tree
Showing 209 changed files with 6,204 additions and 2,817 deletions.
49 changes: 47 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,9 @@ serde_derive = ">=1.0.185"

once_cell = "1.18.0"
document-features = { version = "0.2.0", optional = true }

[profile.dev.package]
insta.opt-level = 3
similar.opt-level = 3
gix-object = { opt-level = 3 }
gix-ref = { opt-level = 3 }
#gix-pack = { opt-level = 3 }
Expand Down
28 changes: 18 additions & 10 deletions crate-status.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,17 +304,24 @@ Check out the [performance discussion][gix-diff-performance] as well.

* **tree**
* [x] changes needed to obtain _other tree_
* **patches**
* There are various ways to generate a patch from two blobs.
* [ ] text
* [ ] binary
* **lines**
* [x] Simple line-by-line diffs powered by the `imara-diff` crate.
* **blobs**
* **patches**
* There are various ways to generate a patch from two blobs.
* [ ] text
* [ ] binary
* [ ] `git-apply` compatibility
* [ ] merge hunks that are close enough based on line-setting (`interhunk-lines`)
* [ ] white-space related settings
* **lines**
* [x] Simple line-by-line diffs powered by the `imara-diff` crate.
* **generic rename tracker to find renames and copies**
* [x] find by exact match
* [x] find by similarity check
* [x] find blobs by exact match
* [x] find blobs by similarity check
* [ ] heuristics to find best candidate
* [ ] find by basename to help detecting simple moves
* [ ] find by basename to support similarity check
* [x] directory tracking
- [x] by identity
- [ ] by similarity
* **blob**
* [x] a choice of to-worktree, to-git and to-worktree-if-needed conversions
* [x] `textconv` filters
Expand All @@ -332,12 +339,13 @@ Check out the [performance discussion][gix-diff-performance] as well.

### gix-merge

* [x] three-way merge analysis of blobs with choice of how to resolve conflicts
* [x] three-way merge analysis of **blobs** with choice of how to resolve conflicts
- [ ] choose how to resolve conflicts on the data-structure
- [ ] produce a new blob based on data-structure containing possible resolutions
- [x] `merge` style
- [x] `diff3` style
- [x] `zdiff` style
- [ ] a way to control inter-hunk merging based on proximity (maybe via `gix-diff` feature which could use the same)
* [ ] diff-heuristics match Git perfectly
* [x] API documentation
* [ ] Examples
Expand Down
14 changes: 8 additions & 6 deletions gitoxide-core/src/hours/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,22 +125,23 @@ pub fn spawn_tree_delta_threads<'scope>(
None => continue,
};
from.changes()?
.track_filename()
.track_rewrites(None)
.options(|opts| {
opts.track_filename().track_rewrites(None);
})
.for_each_to_obtain_tree(&to, |change| {
use gix::object::tree::diff::change::Event::*;
use gix::object::tree::diff::Change::*;
changes.fetch_add(1, Ordering::Relaxed);
match change.event {
match change {
Rewrite { .. } => {
unreachable!("we turned that off")
}
Addition { entry_mode, id } => {
Addition { entry_mode, id, .. } => {
if entry_mode.is_no_tree() {
files.added += 1;
add_lines(line_stats, &lines_count, &mut lines, id);
}
}
Deletion { entry_mode, id } => {
Deletion { entry_mode, id, .. } => {
if entry_mode.is_no_tree() {
files.removed += 1;
remove_lines(line_stats, &lines_count, &mut lines, id);
Expand All @@ -151,6 +152,7 @@ pub fn spawn_tree_delta_threads<'scope>(
previous_entry_mode,
id,
previous_id,
..
} => match (previous_entry_mode.is_blob(), entry_mode.is_blob()) {
(false, false) => {}
(false, true) => {
Expand Down
4 changes: 2 additions & 2 deletions gitoxide-core/src/hours/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ pub struct WorkByPerson {
pub lines: LineStats,
}

impl<'a> WorkByPerson {
pub fn merge(&mut self, other: &'a WorkByEmail) {
impl WorkByPerson {
pub fn merge(&mut self, other: &WorkByEmail) {
if !self.name.contains(&other.name) {
self.name.push(other.name);
}
Expand Down
44 changes: 26 additions & 18 deletions gitoxide-core/src/query/engine/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,34 +207,36 @@ pub fn update(
rewrite_cache.clear_resource_cache_keep_allocation();
diff_cache.clear_resource_cache_keep_allocation();
from.changes()?
.track_path()
.track_rewrites(Some(rewrites))
.options(|opts| {
opts.track_path().track_rewrites(Some(rewrites));
})
.for_each_to_obtain_tree_with_cache(&to, &mut rewrite_cache, |change| {
use gix::object::tree::diff::change::Event::*;
use gix::object::tree::diff::Change::*;
change_counter.fetch_add(1, Ordering::SeqCst);
match change.event {
Addition { entry_mode, id } => {
match change {
Addition {
entry_mode,
id,
location,
..
} => {
if entry_mode.is_blob_or_symlink() {
add_lines(&mut out, change.location, &lines_counter, id);
add_lines(&mut out, location, &lines_counter, id);
}
}
Modification {
entry_mode,
previous_entry_mode,
id,
previous_id,
location,
} => match (previous_entry_mode.is_blob(), entry_mode.is_blob()) {
(false, false) => {}
(false, true) => {
add_lines(&mut out, change.location, &lines_counter, id);
add_lines(&mut out, location, &lines_counter, id);
}
(true, false) => {
add_lines(
&mut out,
change.location,
&lines_counter,
previous_id,
);
add_lines(&mut out, location, &lines_counter, previous_id);
}
(true, true) => {
if let Ok(cache) =
Expand Down Expand Up @@ -266,7 +268,7 @@ pub fn update(
lines_counter
.fetch_add(nl, Ordering::SeqCst);
out.push(FileChange {
relpath: change.location.to_owned(),
relpath: location.to_owned(),
mode: FileMode::Modified,
source_relpath: None,
lines: Some(lines),
Expand All @@ -281,19 +283,25 @@ pub fn update(
}
}
},
Deletion { entry_mode, id } => {
Deletion {
entry_mode,
id,
location,
..
} => {
if entry_mode.is_blob_or_symlink() {
remove_lines(&mut out, change.location, &lines_counter, id);
remove_lines(&mut out, location, &lines_counter, id);
}
}
Rewrite {
source_location,
diff,
copy,
location,
..
} => {
out.push(FileChange {
relpath: change.location.to_owned(),
relpath: location.to_owned(),
source_relpath: Some(source_location.to_owned()),
mode: if copy { FileMode::Copy } else { FileMode::Rename },
lines: diff.map(|d| LineStats {
Expand Down Expand Up @@ -369,7 +377,7 @@ pub fn update(
}
}

impl<'a, Find> gix::prelude::Find for Db<'a, Find>
impl<Find> gix::prelude::Find for Db<'_, Find>
where
Find: gix::prelude::Find + Clone,
{
Expand Down
8 changes: 4 additions & 4 deletions gitoxide-core/src/repository/revision/explain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ impl<'a> Explain<'a> {
}
}

impl<'a> delegate::Revision for Explain<'a> {
impl delegate::Revision for Explain<'_> {
fn find_ref(&mut self, name: &BStr) -> Option<()> {
self.prefix()?;
self.ref_name = Some(name.into());
Expand Down Expand Up @@ -121,7 +121,7 @@ impl<'a> delegate::Revision for Explain<'a> {
}
}

impl<'a> delegate::Navigate for Explain<'a> {
impl delegate::Navigate for Explain<'_> {
fn traverse(&mut self, kind: Traversal) -> Option<()> {
self.prefix()?;
let name = self.revision_name();
Expand Down Expand Up @@ -194,7 +194,7 @@ impl<'a> delegate::Navigate for Explain<'a> {
}
}

impl<'a> delegate::Kind for Explain<'a> {
impl delegate::Kind for Explain<'_> {
fn kind(&mut self, kind: spec::Kind) -> Option<()> {
self.prefix()?;
self.call = 0;
Expand All @@ -215,7 +215,7 @@ impl<'a> delegate::Kind for Explain<'a> {
}
}

impl<'a> Delegate for Explain<'a> {
impl Delegate for Explain<'_> {
fn done(&mut self) {
if !self.has_implicit_anchor && self.ref_name.is_none() && self.oid_prefix.is_none() {
self.err = Some("Incomplete specification lacks its anchor, like a reference or object name".into());
Expand Down
2 changes: 1 addition & 1 deletion gitoxide-core/src/repository/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ mod entries {
}
}

impl<'repo, 'a> gix::traverse::tree::Visit for Traverse<'repo, 'a> {
impl gix::traverse::tree::Visit for Traverse<'_, '_> {
fn pop_front_tracked_path_and_set_current(&mut self) {
self.path = self.path_deque.pop_front().expect("every parent is set only once");
}
Expand Down
2 changes: 1 addition & 1 deletion gix-actor/src/identity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ mod write {
}
}

impl<'a> IdentityRef<'a> {
impl IdentityRef<'_> {
/// Serialize this instance to `out` in the git serialization format for signatures (but without timestamp).
pub fn write_to(&self, out: &mut dyn std::io::Write) -> std::io::Result<()> {
out.write_all(validated_token(self.name)?)?;
Expand Down
2 changes: 1 addition & 1 deletion gix-actor/src/signature/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ pub(crate) mod write {
}
}

impl<'a> SignatureRef<'a> {
impl SignatureRef<'_> {
/// Serialize this instance to `out` in the git serialization format for actors.
pub fn write_to(&self, out: &mut dyn std::io::Write) -> std::io::Result<()> {
out.write_all(validated_token(self.name)?)?;
Expand Down
2 changes: 1 addition & 1 deletion gix-attributes/src/name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::{Name, NameRef};
use bstr::{BStr, BString, ByteSlice};
use kstring::KStringRef;

impl<'a> NameRef<'a> {
impl NameRef<'_> {
/// Turn this ref into its owned counterpart.
pub fn to_owned(self) -> Name {
Name(self.0.into())
Expand Down
2 changes: 1 addition & 1 deletion gix-attributes/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ impl<'a> StateRef<'a> {
}

/// Access
impl<'a> StateRef<'a> {
impl StateRef<'_> {
/// Turn ourselves into our owned counterpart.
pub fn to_owned(self) -> State {
self.into()
Expand Down
Loading

0 comments on commit 37c1e4c

Please sign in to comment.