@@ -65,22 +65,126 @@ impl<'repo> Tree<'repo> {
65
65
#[ allow( missing_docs) ]
66
66
///
67
67
pub mod diff {
68
- use crate :: Tree ;
68
+ use crate :: bstr:: BStr ;
69
+ use crate :: ext:: ObjectIdExt ;
70
+ use crate :: { Id , Repository , Tree } ;
71
+ use git_object:: TreeRefIter ;
72
+ use git_odb:: FindExt ;
69
73
74
+ /// Represents any possible change in order to turn one tree into another.
75
+ #[ derive( Debug , Clone , Copy ) ]
76
+ pub enum Event < ' repo , ' other_repo > {
77
+ /// An entry was added, like the addition of a file or directory.
78
+ Addition {
79
+ /// The mode of the added entry.
80
+ entry_mode : git_object:: tree:: EntryMode ,
81
+ /// The object id of the added entry.
82
+ id : Id < ' other_repo > ,
83
+ } ,
84
+ /// An entry was deleted, like the deletion of a file or directory.
85
+ Deletion {
86
+ /// The mode of the deleted entry.
87
+ entry_mode : git_object:: tree:: EntryMode ,
88
+ /// The object id of the deleted entry.
89
+ id : Id < ' repo > ,
90
+ } ,
91
+ /// An entry was modified, e.g. changing the contents of a file adjusts its object id and turning
92
+ /// a file into a symbolic link adjusts its mode.
93
+ Modification {
94
+ /// The mode of the entry before the modification.
95
+ previous_entry_mode : git_object:: tree:: EntryMode ,
96
+ /// The object id of the entry before the modification.
97
+ previous_id : Id < ' repo > ,
98
+
99
+ /// The mode of the entry after the modification.
100
+ entry_mode : git_object:: tree:: EntryMode ,
101
+ /// The object id after the modification.
102
+ id : Id < ' other_repo > ,
103
+ } ,
104
+ }
105
+
106
+ /// Diffing
70
107
impl < ' repo > Tree < ' repo > {
108
+ /// Return a platform to see the changes needed to create other trees, for instance.
71
109
pub fn changes < ' other_repo , ' a > ( & ' a self ) -> Platform < ' a , ' repo > {
72
- Platform { lhs : self }
110
+ Platform {
111
+ state : Default :: default ( ) ,
112
+ lhs : self ,
113
+ }
73
114
}
74
115
}
75
116
76
- #[ allow( dead_code) ]
77
117
pub struct Platform < ' a , ' repo > {
118
+ state : git_diff:: tree:: State ,
78
119
lhs : & ' a Tree < ' repo > ,
79
120
}
80
121
122
+ /// Add the item to compare to.
81
123
impl < ' a , ' repo > Platform < ' a , ' repo > {
82
- pub fn to_obtain_tree ( & self , _other : & Tree < ' _ > ) {
83
- todo ! ( )
124
+ pub fn to_obtain_tree < ' other_repo > (
125
+ & mut self ,
126
+ other : & Tree < ' other_repo > ,
127
+ for_each : impl FnMut ( Event < ' repo , ' other_repo > ) -> git_diff:: tree:: visit:: Action ,
128
+ ) -> Result < ( ) , git_diff:: tree:: changes:: Error > {
129
+ let repo = self . lhs . repo ;
130
+ let mut delegate = Delegate {
131
+ repo : self . lhs . repo ,
132
+ other_repo : other. repo ,
133
+ visit : for_each,
134
+ } ;
135
+ git_diff:: tree:: Changes :: from ( TreeRefIter :: from_bytes ( & self . lhs . data ) ) . needed_to_obtain (
136
+ TreeRefIter :: from_bytes ( & other. data ) ,
137
+ & mut self . state ,
138
+ |oid, buf| repo. objects . find_tree_iter ( oid, buf) ,
139
+ & mut delegate,
140
+ )
141
+ }
142
+ }
143
+
144
+ struct Delegate < ' repo , ' other_repo , VisitFn > {
145
+ repo : & ' repo Repository ,
146
+ other_repo : & ' other_repo Repository ,
147
+ visit : VisitFn ,
148
+ }
149
+
150
+ impl < ' repo , ' other_repo , VisitFn > git_diff:: tree:: Visit for Delegate < ' repo , ' other_repo , VisitFn >
151
+ where
152
+ VisitFn : FnMut ( Event < ' repo , ' other_repo > ) -> git_diff:: tree:: visit:: Action ,
153
+ {
154
+ fn pop_front_tracked_path_and_set_current ( & mut self ) { }
155
+
156
+ fn push_back_tracked_path_component ( & mut self , _component : & BStr ) {
157
+ { }
158
+ }
159
+
160
+ fn push_path_component ( & mut self , _component : & BStr ) { }
161
+
162
+ fn pop_path_component ( & mut self ) { }
163
+
164
+ fn visit ( & mut self , change : git_diff:: tree:: visit:: Change ) -> git_diff:: tree:: visit:: Action {
165
+ use git_diff:: tree:: visit:: Change :: * ;
166
+ let event = match change {
167
+ Addition { entry_mode, oid } => Event :: Addition {
168
+ entry_mode,
169
+ id : oid. attach ( self . other_repo ) ,
170
+ } ,
171
+ Deletion { entry_mode, oid } => Event :: Deletion {
172
+ entry_mode,
173
+ id : oid. attach ( self . repo ) ,
174
+ } ,
175
+ Modification {
176
+ previous_entry_mode,
177
+ previous_oid,
178
+ entry_mode,
179
+ oid,
180
+ } => Event :: Modification {
181
+ previous_entry_mode,
182
+ entry_mode,
183
+ previous_id : previous_oid. attach ( self . repo ) ,
184
+ id : oid. attach ( self . other_repo ) ,
185
+ } ,
186
+ } ;
187
+ ( self . visit ) ( event)
84
188
}
85
189
}
86
190
}
0 commit comments