@@ -73,10 +73,17 @@ void move_cache_to_base_index(struct index_state *istate)
73
73
int i ;
74
74
75
75
/*
76
- * do not delete old si->base, its index entries may be shared
77
- * with istate->cache[]. Accept a bit of leaking here because
78
- * this code is only used by short-lived update-index .
76
+ * If "si" is shared with another index_state (e.g. by
77
+ * unpack-trees code), we will need to duplicate split_index
78
+ * struct. It's not happening now though, luckily .
79
79
*/
80
+ assert (si -> refcount <= 1 );
81
+
82
+ unshare_split_index (istate , 0 );
83
+ if (si -> base ) {
84
+ discard_index (si -> base );
85
+ free (si -> base );
86
+ }
80
87
si -> base = xcalloc (1 , sizeof (* si -> base ));
81
88
si -> base -> version = istate -> version ;
82
89
/* zero timestamp disables racy test in ce_write_index() */
@@ -275,11 +282,41 @@ void finish_writing_split_index(struct index_state *istate)
275
282
istate -> cache_nr = si -> saved_cache_nr ;
276
283
}
277
284
285
+ void unshare_split_index (struct index_state * istate , int discard )
286
+ {
287
+ struct split_index * si = istate -> split_index ;
288
+ int i ;
289
+
290
+ if (!si || !si -> base )
291
+ return ;
292
+
293
+ for (i = 0 ; i < istate -> cache_nr ; i ++ ) {
294
+ struct cache_entry * ce = istate -> cache [i ];
295
+ struct cache_entry * new = NULL ;
296
+
297
+ if (!ce -> index ||
298
+ ce -> index > si -> base -> cache_nr ||
299
+ ce != si -> base -> cache [ce -> index - 1 ])
300
+ continue ;
301
+
302
+ if (!discard ) {
303
+ int len = ce_namelen (ce );
304
+ new = xcalloc (1 , cache_entry_size (len ));
305
+ copy_cache_entry (new , ce );
306
+ memcpy (new -> name , ce -> name , len );
307
+ new -> index = 0 ;
308
+ }
309
+ istate -> cache [i ] = new ;
310
+ }
311
+ }
312
+
313
+
278
314
void discard_split_index (struct index_state * istate )
279
315
{
280
316
struct split_index * si = istate -> split_index ;
281
317
if (!si )
282
318
return ;
319
+ unshare_split_index (istate , 0 );
283
320
istate -> split_index = NULL ;
284
321
si -> refcount -- ;
285
322
if (si -> refcount )
@@ -328,14 +365,8 @@ void add_split_index(struct index_state *istate)
328
365
329
366
void remove_split_index (struct index_state * istate )
330
367
{
331
- if (istate -> split_index ) {
332
- /*
333
- * can't discard_split_index(&the_index); because that
334
- * will destroy split_index->base->cache[], which may
335
- * be shared with the_index.cache[]. So yeah we're
336
- * leaking a bit here.
337
- */
338
- istate -> split_index = NULL ;
339
- istate -> cache_changed |= SOMETHING_CHANGED ;
340
- }
368
+ if (!istate -> split_index )
369
+ return ;
370
+ discard_split_index (istate );
371
+ istate -> cache_changed |= SOMETHING_CHANGED ;
341
372
}
0 commit comments