@@ -121,13 +121,18 @@ impl Outcome<'_> {
121121
122122 /// Returns `true` if `index` changed as we applied conflicting stages to it, using `how` to determine if a
123123 /// conflict should be considered unresolved.
124+ /// `removal_mode` decides how unconflicted entries should be removed if they are superseded by
125+ /// their conflicted counterparts.
124126 /// It's important that `index` is at the state of [`Self::tree`].
125127 ///
126128 /// Note that in practice, whenever there is a single [conflict](Conflict), this function will return `true`.
127- /// Also, the unconflicted stage of such entries will be removed merely by setting a flag, so the
128- /// in-memory entry is still present.
129- pub fn index_changed_after_applying_conflicts ( & self , index : & mut gix_index:: State , how : TreatAsUnresolved ) -> bool {
130- apply_index_entries ( & self . conflicts , how, index)
129+ pub fn index_changed_after_applying_conflicts (
130+ & self ,
131+ index : & mut gix_index:: State ,
132+ how : TreatAsUnresolved ,
133+ removal_mode : apply_index_entries:: RemovalMode ,
134+ ) -> bool {
135+ apply_index_entries ( & self . conflicts , how, index, removal_mode)
131136 }
132137}
133138
@@ -456,7 +461,24 @@ mod utils;
456461///
457462pub mod apply_index_entries {
458463
464+ /// Determines how we deal with the removal of unconflicted entries if these are superseded by their conflicted counterparts,
465+ /// i.e. stage 1, 2 and 3.
466+ #[ derive( Copy , Clone , Debug , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
467+ pub enum RemovalMode {
468+ /// Add the [`gix_index::entry::Flags::REMOVE`] flag to entries that are to be removed.
469+ ///
470+ /// **Note** that this also means that unconflicted and conflicted stages will be visible in the same index.
471+ /// When written, entries marked for removal will automatically be ignored. However, this also means that
472+ /// one must not use the in-memory index or take specific care of entries that are marked for removal.
473+ Mark ,
474+ /// Entries marked for removal (even those that were already marked) will be removed from memory at the end.
475+ ///
476+ /// This is an expensive step that leaves a consistent index, ready for use.
477+ Prune ,
478+ }
479+
459480 pub ( super ) mod function {
481+ use crate :: tree:: apply_index_entries:: RemovalMode ;
460482 use crate :: tree:: { Conflict , ConflictIndexEntryPathHint , Resolution , ResolutionFailure , TreatAsUnresolved } ;
461483 use bstr:: { BStr , ByteSlice } ;
462484 use std:: collections:: { hash_map, HashMap } ;
@@ -465,8 +487,9 @@ pub mod apply_index_entries {
465487 /// conflict should be considered unresolved.
466488 /// Once a stage of a path conflicts, the unconflicting stage is removed even though it might be the one
467489 /// that is currently checked out.
468- /// This removal, however, is only done by flagging it with [gix_index::entry::Flags::REMOVE], which means
469- /// these entries won't be written back to disk but will still be present in the index.
490+ /// This removal is only done by flagging it with [gix_index::entry::Flags::REMOVE], which means
491+ /// these entries won't be written back to disk but will still be present in the index if `removal_mode`
492+ /// is [`RemovalMode::Mark`]. For proper removal, choose [`RemovalMode::Prune`].
470493 /// It's important that `index` matches the tree that was produced as part of the merge that also
471494 /// brought about `conflicts`, or else this function will fail if it cannot find the path matching
472495 /// the conflicting entries.
@@ -477,6 +500,7 @@ pub mod apply_index_entries {
477500 conflicts : & [ Conflict ] ,
478501 how : TreatAsUnresolved ,
479502 index : & mut gix_index:: State ,
503+ removal_mode : RemovalMode ,
480504 ) -> bool {
481505 if index. is_sparse ( ) {
482506 gix_trace:: error!( "Refusing to apply index entries to sparse index - it's not tested yet" ) ;
@@ -585,8 +609,15 @@ pub mod apply_index_entries {
585609 }
586610 }
587611
612+ let res = index. entries ( ) . len ( ) != len;
613+ match removal_mode {
614+ RemovalMode :: Mark => { }
615+ RemovalMode :: Prune => {
616+ index. remove_entries ( |_, _, e| e. flags . contains ( gix_index:: entry:: Flags :: REMOVE ) ) ;
617+ }
618+ }
588619 index. sort_entries ( ) ;
589- index . entries ( ) . len ( ) != len
620+ res
590621 }
591622 }
592623}
0 commit comments