@@ -85,85 +85,41 @@ pub struct IndexEntry {
85
85
pub path : Vec < u8 > ,
86
86
}
87
87
88
- // We cannot return raw::git_index_entry instances directly, as they rely on
89
- // a CString which is owned by the function. To make the pointer to the CString
90
- // valid during usage of raw::git_index_entry, we supply the index entry in a
91
- // callback where pointers to the CString are valid.
92
- fn try_raw_entries < const N : usize > (
93
- entries : & [ Option < & IndexEntry > ; N ] ,
94
- cb : impl FnOnce ( & [ * const raw:: git_index_entry ; N ] ) -> Result < ( ) , Error > ,
95
- ) -> Result < ( ) , Error > {
96
- let mut paths: [ Option < CString > ; N ] = unsafe { std:: mem:: MaybeUninit :: uninit ( ) . assume_init ( ) } ;
97
- for ( path, entry) in paths. iter_mut ( ) . zip ( entries. iter ( ) ) {
98
- let c_path = if let Some ( entry) = entry {
99
- Some ( CString :: new ( & entry. path [ ..] ) ?)
88
+ impl IndexEntry {
89
+ // Expecting c_path to contain a CString with the contents of self.path
90
+ fn to_raw ( & self , c_path : & CString ) -> raw:: git_index_entry {
91
+ // libgit2 encodes the length of the path in the lower bits of the
92
+ // `flags` entry, so mask those out and recalculate here to ensure we
93
+ // don't corrupt anything.
94
+ let mut flags = self . flags & !raw:: GIT_INDEX_ENTRY_NAMEMASK ;
95
+
96
+ if self . path . len ( ) < raw:: GIT_INDEX_ENTRY_NAMEMASK as usize {
97
+ flags |= self . path . len ( ) as u16 ;
100
98
} else {
101
- None
102
- } ;
103
-
104
- let path_ptr: * mut Option < CString > = path;
105
- unsafe {
106
- path_ptr. write ( c_path) ;
99
+ flags |= raw:: GIT_INDEX_ENTRY_NAMEMASK ;
107
100
}
108
- }
109
-
110
- let mut raw_entries: [ Option < raw:: git_index_entry > ; N ] =
111
- unsafe { std:: mem:: MaybeUninit :: uninit ( ) . assume_init ( ) } ;
112
- for ( raw_entry, ( entry, path) ) in raw_entries. iter_mut ( ) . zip ( entries. iter ( ) . zip ( & paths) ) {
113
- let c_raw_entry = if let Some ( entry) = entry {
114
- // libgit2 encodes the length of the path in the lower bits of the
115
- // `flags` entry, so mask those out and recalculate here to ensure we
116
- // don't corrupt anything.
117
- let mut flags = entry. flags & !raw:: GIT_INDEX_ENTRY_NAMEMASK ;
118
-
119
- if entry. path . len ( ) < raw:: GIT_INDEX_ENTRY_NAMEMASK as usize {
120
- flags |= entry. path . len ( ) as u16 ;
121
- } else {
122
- flags |= raw:: GIT_INDEX_ENTRY_NAMEMASK ;
123
- }
124
101
125
- Some ( raw:: git_index_entry {
126
- dev : entry. dev ,
127
- ino : entry. ino ,
128
- mode : entry. mode ,
129
- uid : entry. uid ,
130
- gid : entry. gid ,
131
- file_size : entry. file_size ,
132
- id : unsafe { * entry. id . raw ( ) } ,
133
- flags,
134
- flags_extended : entry. flags_extended ,
135
- path : path. as_ref ( ) . unwrap ( ) . as_ptr ( ) ,
136
- mtime : raw:: git_index_time {
137
- seconds : entry. mtime . seconds ( ) ,
138
- nanoseconds : entry. mtime . nanoseconds ( ) ,
139
- } ,
140
- ctime : raw:: git_index_time {
141
- seconds : entry. ctime . seconds ( ) ,
142
- nanoseconds : entry. ctime . nanoseconds ( ) ,
143
- } ,
144
- } )
145
- } else {
146
- None
147
- } ;
148
-
149
- let raw_entry_ptr: * mut Option < raw:: git_index_entry > = raw_entry;
150
- unsafe {
151
- raw_entry_ptr. write ( c_raw_entry) ;
152
- }
153
- }
154
-
155
- let mut raw_entry_ptrs: [ * const raw:: git_index_entry ; N ] =
156
- unsafe { std:: mem:: MaybeUninit :: uninit ( ) . assume_init ( ) } ;
157
- for ( raw_entry_ptr, raw_entry) in raw_entry_ptrs. iter_mut ( ) . zip ( raw_entries. iter ( ) ) {
158
- let c_raw_entry_ptr = raw_entry. as_ref ( ) . map_or_else ( std:: ptr:: null, |ptr| ptr) ;
159
-
160
- let raw_entry_ptr_ptr: * mut * const raw:: git_index_entry = raw_entry_ptr;
161
- unsafe {
162
- raw_entry_ptr_ptr. write ( c_raw_entry_ptr) ;
102
+ raw:: git_index_entry {
103
+ dev : self . dev ,
104
+ ino : self . ino ,
105
+ mode : self . mode ,
106
+ uid : self . uid ,
107
+ gid : self . gid ,
108
+ file_size : self . file_size ,
109
+ id : unsafe { * self . id . raw ( ) } ,
110
+ flags,
111
+ flags_extended : self . flags_extended ,
112
+ path : c_path. as_ptr ( ) ,
113
+ mtime : raw:: git_index_time {
114
+ seconds : self . mtime . seconds ( ) ,
115
+ nanoseconds : self . mtime . nanoseconds ( ) ,
116
+ } ,
117
+ ctime : raw:: git_index_time {
118
+ seconds : self . ctime . seconds ( ) ,
119
+ nanoseconds : self . ctime . nanoseconds ( ) ,
120
+ } ,
163
121
}
164
122
}
165
-
166
- cb ( & raw_entry_ptrs)
167
123
}
168
124
169
125
impl Index {
@@ -226,12 +182,13 @@ impl Index {
226
182
/// given 'source_entry', it will be replaced. Otherwise, the 'source_entry'
227
183
/// will be added.
228
184
pub fn add ( & mut self , entry : & IndexEntry ) -> Result < ( ) , Error > {
229
- try_raw_entries ( & [ Some ( entry) ] , |raws| {
230
- unsafe {
231
- try_call ! ( raw:: git_index_add( self . raw, raws[ 0 ] ) ) ;
232
- }
233
- Ok ( ( ) )
234
- } )
185
+ let c_path = CString :: new ( & entry. path [ ..] ) ?;
186
+ let raw_entry = entry. to_raw ( & c_path) ;
187
+
188
+ unsafe {
189
+ try_call ! ( raw:: git_index_add( self . raw, & raw_entry) ) ;
190
+ }
191
+ Ok ( ( ) )
235
192
}
236
193
237
194
/// Add or update an index entry from a buffer in memory
@@ -252,14 +209,17 @@ impl Index {
252
209
/// no longer be marked as conflicting. The data about the conflict will be
253
210
/// moved to the "resolve undo" (REUC) section.
254
211
pub fn add_frombuffer ( & mut self , entry : & IndexEntry , data : & [ u8 ] ) -> Result < ( ) , Error > {
255
- try_raw_entries ( & [ Some ( entry) ] , |raws| {
256
- unsafe {
257
- let ptr = data. as_ptr ( ) as * const c_void ;
258
- let len = data. len ( ) as size_t ;
259
- try_call ! ( raw:: git_index_add_frombuffer( self . raw, raws[ 0 ] , ptr, len) ) ;
260
- }
261
- Ok ( ( ) )
262
- } )
212
+ let c_path = CString :: new ( & entry. path [ ..] ) ?;
213
+ let raw_entry = entry. to_raw ( & c_path) ;
214
+
215
+ unsafe {
216
+ let ptr = data. as_ptr ( ) as * const c_void ;
217
+ let len = data. len ( ) as size_t ;
218
+ try_call ! ( raw:: git_index_add_frombuffer(
219
+ self . raw, & raw_entry, ptr, len
220
+ ) ) ;
221
+ }
222
+ Ok ( ( ) )
263
223
}
264
224
265
225
/// Add or update an index entry from a file on disk
@@ -443,18 +403,58 @@ impl Index {
443
403
our_entry : Option < & IndexEntry > ,
444
404
their_entry : Option < & IndexEntry > ,
445
405
) -> Result < ( ) , Error > {
446
- try_raw_entries (
447
- & [ ancestor_entry, our_entry, their_entry] ,
448
- |raw_entries| unsafe {
449
- try_call ! ( raw:: git_index_conflict_add(
450
- self . raw,
451
- raw_entries[ 0 ] ,
452
- raw_entries[ 1 ] ,
453
- raw_entries[ 2 ]
454
- ) ) ;
455
- Ok ( ( ) )
456
- } ,
457
- )
406
+ let ancestor_c_path = if let Some ( entry) = ancestor_entry {
407
+ Some ( CString :: new ( & entry. path [ ..] ) ?)
408
+ } else {
409
+ None
410
+ } ;
411
+ let our_c_path = if let Some ( entry) = our_entry {
412
+ Some ( CString :: new ( & entry. path [ ..] ) ?)
413
+ } else {
414
+ None
415
+ } ;
416
+ let their_c_path = if let Some ( entry) = their_entry {
417
+ Some ( CString :: new ( & entry. path [ ..] ) ?)
418
+ } else {
419
+ None
420
+ } ;
421
+
422
+ let mut raw_ancestor_entry = None ;
423
+ let mut raw_our_entry = None ;
424
+ let mut raw_their_entry = None ;
425
+
426
+ if let Some ( entry) = ancestor_entry {
427
+ let c_path = ancestor_c_path. as_ref ( ) . unwrap ( ) ;
428
+ raw_ancestor_entry = Some ( entry. to_raw ( & c_path) ) ;
429
+ }
430
+ if let Some ( entry) = our_entry {
431
+ let c_path = our_c_path. as_ref ( ) . unwrap ( ) ;
432
+ raw_our_entry = Some ( entry. to_raw ( & c_path) ) ;
433
+ }
434
+ if let Some ( entry) = their_entry {
435
+ let c_path = their_c_path. as_ref ( ) . unwrap ( ) ;
436
+ raw_their_entry = Some ( entry. to_raw ( & c_path) ) ;
437
+ }
438
+
439
+ let raw_ancestor_entry_ptr = raw_ancestor_entry
440
+ . as_ref ( )
441
+ . map_or_else ( std:: ptr:: null, |ptr| ptr) ;
442
+ let raw_our_entry_ptr = raw_our_entry
443
+ . as_ref ( )
444
+ . map_or_else ( std:: ptr:: null, |ptr| ptr) ;
445
+ let raw_their_entry_ptr = raw_their_entry
446
+ . as_ref ( )
447
+ . map_or_else ( std:: ptr:: null, |ptr| ptr) ;
448
+
449
+ unsafe {
450
+ try_call ! ( raw:: git_index_conflict_add(
451
+ self . raw,
452
+ raw_ancestor_entry_ptr,
453
+ raw_our_entry_ptr,
454
+ raw_their_entry_ptr
455
+ ) ) ;
456
+ }
457
+ Ok ( ( ) )
458
458
}
459
459
460
460
/// Remove all conflicts in the index (entries with a stage greater than 0).
0 commit comments