Skip to content

Commit 0b7abfb

Browse files
authored
Merge pull request #1661 from GitoxideLabs/merge
more merge features
2 parents cb3149f + 71b0cea commit 0b7abfb

File tree

33 files changed

+1302
-760
lines changed

33 files changed

+1302
-760
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crate-status.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,8 @@ Check out the [performance discussion][gix-diff-performance] as well.
318318
* [x] find blobs by similarity check
319319
* [ ] heuristics to find best candidate
320320
* [ ] find by basename to support similarity check
321+
- Not having it can lead to issues when files with the same or similar content are part of a move
322+
as files can be lost that way.
321323
* [x] directory tracking
322324
- [x] by identity
323325
- [ ] by similarity
@@ -349,9 +351,9 @@ Check out the [performance discussion][gix-diff-performance] as well.
349351
- [ ] various newlines-related options during the merge (see https://git-scm.com/docs/git-merge#Documentation/git-merge.txt-ignore-space-change).
350352
- [ ] a way to control inter-hunk merging based on proximity (maybe via `gix-diff` feature which could use the same)
351353
* [x] **tree**-diff-heuristics match Git for its test-cases
352-
- [ ] a way to generate an index with stages
353-
- *currently the data it provides won't generate index entries, and possibly can't be used for it yet*
354+
- [x] a way to generate an index with stages, mostly conforming with Git.
354355
- [ ] submodule merges (*right now they count as conflicts if they differ*)
356+
- [ ] assure sparse indices are handled correctly during application - right now we refuse.
355357
* [x] **commits** - with handling of multiple merge bases by recursive merge-base merge
356358
* [x] API documentation
357359
* [ ] Examples
@@ -462,6 +464,7 @@ Check out the [performance discussion][gix-traverse-performance] as well.
462464
* [x] delegate can support for all fetch features, including shallow, deepen, etc.
463465
* [x] receive parsed shallow refs
464466
* [ ] push
467+
* [ ] remote helper protocol and integration
465468
* [x] API documentation
466469
* [ ] Some examples
467470

gitoxide-core/src/repository/merge/commit.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::OutputFormat;
22
use anyhow::{anyhow, bail, Context};
33
use gix::bstr::BString;
44
use gix::bstr::ByteSlice;
5-
use gix::merge::tree::UnresolvedConflict;
5+
use gix::merge::tree::TreatAsUnresolved;
66
use gix::prelude::Write;
77

88
use super::tree::Options;
@@ -18,6 +18,7 @@ pub fn commit(
1818
format,
1919
file_favor,
2020
in_memory,
21+
debug,
2122
}: Options,
2223
) -> anyhow::Result<()> {
2324
if format != OutputFormat::Human {
@@ -48,7 +49,7 @@ pub fn commit(
4849
.merge_commits(ours_id, theirs_id, labels, options.into())?
4950
.tree_merge;
5051
let has_conflicts = res.conflicts.is_empty();
51-
let has_unresolved_conflicts = res.has_unresolved_conflicts(UnresolvedConflict::Renames);
52+
let has_unresolved_conflicts = res.has_unresolved_conflicts(TreatAsUnresolved::Renames);
5253
{
5354
let _span = gix::trace::detail!("Writing merged tree");
5455
let mut written = 0;
@@ -63,6 +64,9 @@ pub fn commit(
6364
writeln!(out, "{tree_id} (wrote {written} trees)")?;
6465
}
6566

67+
if debug {
68+
writeln!(err, "{:#?}", &res.conflicts)?;
69+
}
6670
if !has_conflicts {
6771
writeln!(err, "{} possibly resolved conflicts", res.conflicts.len())?;
6872
}

gitoxide-core/src/repository/merge/tree.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ pub struct Options {
44
pub format: OutputFormat,
55
pub file_favor: Option<gix::merge::tree::FileFavor>,
66
pub in_memory: bool,
7+
pub debug: bool,
78
}
89

910
pub(super) mod function {
@@ -12,7 +13,7 @@ pub(super) mod function {
1213
use anyhow::{anyhow, bail, Context};
1314
use gix::bstr::BString;
1415
use gix::bstr::ByteSlice;
15-
use gix::merge::tree::UnresolvedConflict;
16+
use gix::merge::tree::TreatAsUnresolved;
1617
use gix::prelude::Write;
1718

1819
use super::Options;
@@ -29,6 +30,7 @@ pub(super) mod function {
2930
format,
3031
file_favor,
3132
in_memory,
33+
debug,
3234
}: Options,
3335
) -> anyhow::Result<()> {
3436
if format != OutputFormat::Human {
@@ -62,7 +64,7 @@ pub(super) mod function {
6264
};
6365
let res = repo.merge_trees(base_id, ours_id, theirs_id, labels, options)?;
6466
let has_conflicts = res.conflicts.is_empty();
65-
let has_unresolved_conflicts = res.has_unresolved_conflicts(UnresolvedConflict::Renames);
67+
let has_unresolved_conflicts = res.has_unresolved_conflicts(TreatAsUnresolved::Renames);
6668
{
6769
let _span = gix::trace::detail!("Writing merged tree");
6870
let mut written = 0;
@@ -77,6 +79,9 @@ pub(super) mod function {
7779
writeln!(out, "{tree_id} (wrote {written} trees)")?;
7880
}
7981

82+
if debug {
83+
writeln!(err, "{:#?}", &res.conflicts)?;
84+
}
8085
if !has_conflicts {
8186
writeln!(err, "{} possibly resolved conflicts", res.conflicts.len())?;
8287
}

gix-diff/src/tree/function.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ fn handle_lhs_and_rhs_with_equal_filenames(
377377
(false, false) => {
378378
delegate.push_path_component(lhs.filename);
379379
debug_assert!(lhs.mode.is_no_tree() && lhs.mode.is_no_tree());
380-
if lhs.oid != rhs.oid
380+
if (lhs.oid != rhs.oid || lhs.mode != rhs.mode)
381381
&& delegate
382382
.visit(Change::Modification {
383383
previous_entry_mode: lhs.mode,

gix-diff/src/tree_with_rewrites/change.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,34 @@ impl<'a> ChangeRef<'a> {
434434
}
435435
}
436436

437+
/// Return the current mode of this instance, along with its object id.
438+
pub fn entry_mode_and_id(&self) -> (gix_object::tree::EntryMode, &gix_hash::oid) {
439+
match self {
440+
ChangeRef::Addition { entry_mode, id, .. }
441+
| ChangeRef::Deletion { entry_mode, id, .. }
442+
| ChangeRef::Modification { entry_mode, id, .. }
443+
| ChangeRef::Rewrite { entry_mode, id, .. } => (*entry_mode, id),
444+
}
445+
}
446+
447+
/// Return the *previous* mode and id of the resource where possible, i.e. the source of a rename or copy, or a modification.
448+
pub fn source_entry_mode_and_id(&self) -> (gix_object::tree::EntryMode, &gix_hash::oid) {
449+
match self {
450+
ChangeRef::Addition { entry_mode, id, .. }
451+
| ChangeRef::Deletion { entry_mode, id, .. }
452+
| ChangeRef::Modification {
453+
previous_entry_mode: entry_mode,
454+
previous_id: id,
455+
..
456+
}
457+
| ChangeRef::Rewrite {
458+
source_entry_mode: entry_mode,
459+
source_id: id,
460+
..
461+
} => (*entry_mode, id),
462+
}
463+
}
464+
437465
/// Return the *current* location of the resource, i.e. the destination of a rename or copy, or the
438466
/// location at which an addition, deletion or modification took place.
439467
pub fn location(&self) -> &'a BStr {
@@ -478,6 +506,34 @@ impl Change {
478506
}
479507
}
480508

509+
/// Return the current mode of this instance, along with its object id.
510+
pub fn entry_mode_and_id(&self) -> (gix_object::tree::EntryMode, &gix_hash::oid) {
511+
match self {
512+
Change::Addition { entry_mode, id, .. }
513+
| Change::Deletion { entry_mode, id, .. }
514+
| Change::Modification { entry_mode, id, .. }
515+
| Change::Rewrite { entry_mode, id, .. } => (*entry_mode, id),
516+
}
517+
}
518+
519+
/// Return the *previous* mode and id of the resource where possible, i.e. the source of a rename or copy, or a modification.
520+
pub fn source_entry_mode_and_id(&self) -> (gix_object::tree::EntryMode, &gix_hash::oid) {
521+
match self {
522+
Change::Addition { entry_mode, id, .. }
523+
| Change::Deletion { entry_mode, id, .. }
524+
| Change::Modification {
525+
previous_entry_mode: entry_mode,
526+
previous_id: id,
527+
..
528+
}
529+
| Change::Rewrite {
530+
source_entry_mode: entry_mode,
531+
source_id: id,
532+
..
533+
} => (*entry_mode, id),
534+
}
535+
}
536+
481537
/// Return the *current* location of the resource, i.e. the destination of a rename or copy, or the
482538
/// location at which an addition, deletion or modification took place.
483539
pub fn location(&self) -> &BStr {

0 commit comments

Comments
 (0)