11use gix_hash:: ObjectId ;
2- use gix_object:: { bstr:: BStr , tree, tree:: EntryMode } ;
2+ use gix_object:: { tree, tree:: EntryMode } ;
3+
4+ /// A way to recognize and associate different [`Change`] instances.
5+ ///
6+ /// These are unique only within one diff operation.
7+ pub type ChangeId = u32 ;
8+
9+ /// Identifies a relationship between this instance and another one.
10+ #[ derive( Debug , Copy , Clone , PartialOrd , PartialEq , Ord , Eq , Hash ) ]
11+ pub enum Relation {
12+ /// This is a parent with the given ID, which will always have at least one child
13+ /// assuming that empty directories are not allowed in valid trees.
14+ /// It's also always a tree which is the start of a recursive deletion or addition.
15+ ///
16+ /// The change with this relation is always emitted first.
17+ Parent ( ChangeId ) ,
18+ /// This is a direct or indirect child, tree or not tree, of the parent with the given ID.
19+ ChildOfParent ( ChangeId ) ,
20+ }
321
422/// Represents any possible change in order to turn one tree into another.
523#[ derive( Debug , Clone , PartialOrd , PartialEq , Ord , Eq , Hash ) ]
@@ -10,13 +28,17 @@ pub enum Change {
1028 entry_mode : tree:: EntryMode ,
1129 /// The object id of the added entry.
1230 oid : ObjectId ,
31+ /// Possibly associate this change with another for hierarchical rename tracking.
32+ relation : Option < Relation > ,
1333 } ,
1434 /// An entry was deleted, like the deletion of a file or directory.
1535 Deletion {
1636 /// The mode of the deleted entry.
1737 entry_mode : tree:: EntryMode ,
1838 /// The object id of the deleted entry.
1939 oid : ObjectId ,
40+ /// Possibly associate this change with another for hierarchical rename tracking.
41+ relation : Option < Relation > ,
2042 } ,
2143 /// An entry was modified, e.g. changing the contents of a file adjusts its object id and turning
2244 /// a file into a symbolic link adjusts its mode.
@@ -51,8 +73,16 @@ impl Change {
5173 /// Return the current object id and tree entry mode of a change.
5274 pub fn oid_and_entry_mode ( & self ) -> ( & gix_hash:: oid , EntryMode ) {
5375 match self {
54- Change :: Addition { oid, entry_mode }
55- | Change :: Deletion { oid, entry_mode }
76+ Change :: Addition {
77+ oid,
78+ entry_mode,
79+ relation : _,
80+ }
81+ | Change :: Deletion {
82+ oid,
83+ entry_mode,
84+ relation : _,
85+ }
5686 | Change :: Modification { oid, entry_mode, .. } => ( oid, * entry_mode) ,
5787 }
5888 }
@@ -75,23 +105,6 @@ impl Action {
75105 }
76106}
77107
78- /// A trait to allow responding to a traversal designed to figure out the [changes][Change]
79- /// to turn tree A into tree B.
80- pub trait Visit {
81- /// Sets the full path path in front of the queue so future calls to push and pop components affect it instead.
82- fn pop_front_tracked_path_and_set_current ( & mut self ) ;
83- /// Append a `component` to the end of a path, which may be empty.
84- fn push_back_tracked_path_component ( & mut self , component : & BStr ) ;
85- /// Append a `component` to the end of a path, which may be empty.
86- fn push_path_component ( & mut self , component : & BStr ) ;
87- /// Removes the last component from the path, which may leave it empty.
88- fn pop_path_component ( & mut self ) ;
89- /// Record a `change` and return an instruction whether to continue or not.
90- ///
91- /// The implementation may use the current path to lean where in the tree the change is located.
92- fn visit ( & mut self , change : Change ) -> Action ;
93- }
94-
95108#[ cfg( feature = "blob" ) ]
96109mod change_impls {
97110 use gix_hash:: oid;
@@ -140,8 +153,8 @@ mod tests {
140153 fn size_of_change ( ) {
141154 let actual = std:: mem:: size_of :: < Change > ( ) ;
142155 assert ! (
143- actual <= 46 ,
144- "{actual} <= 46 : this type shouldn't grow without us knowing"
156+ actual <= 48 ,
157+ "{actual} <= 48 : this type shouldn't grow without us knowing"
145158 ) ;
146159 }
147160}
0 commit comments