@@ -16,13 +16,27 @@ int read_link_extension(struct index_state *istate,
1616{
1717 const unsigned char * data = data_ ;
1818 struct split_index * si ;
19+ int ret ;
20+
1921 if (sz < 20 )
2022 return error ("corrupt link extension (too short)" );
2123 si = init_split_index (istate );
2224 hashcpy (si -> base_sha1 , data );
2325 data += 20 ;
2426 sz -= 20 ;
25- if (sz )
27+ if (!sz )
28+ return 0 ;
29+ si -> delete_bitmap = ewah_new ();
30+ ret = ewah_read_mmap (si -> delete_bitmap , data , sz );
31+ if (ret < 0 )
32+ return error ("corrupt delete bitmap in link extension" );
33+ data += ret ;
34+ sz -= ret ;
35+ si -> replace_bitmap = ewah_new ();
36+ ret = ewah_read_mmap (si -> replace_bitmap , data , sz );
37+ if (ret < 0 )
38+ return error ("corrupt replace bitmap in link extension" );
39+ if (ret != sz )
2640 return error ("garbage at the end of link extension" );
2741 return 0 ;
2842}
@@ -60,15 +74,81 @@ static void mark_base_index_entries(struct index_state *base)
6074 base -> cache [i ]-> index = i + 1 ;
6175}
6276
77+ static void mark_entry_for_delete (size_t pos , void * data )
78+ {
79+ struct index_state * istate = data ;
80+ if (pos >= istate -> cache_nr )
81+ die ("position for delete %d exceeds base index size %d" ,
82+ (int )pos , istate -> cache_nr );
83+ istate -> cache [pos ]-> ce_flags |= CE_REMOVE ;
84+ istate -> split_index -> nr_deletions = 1 ;
85+ }
86+
87+ static void replace_entry (size_t pos , void * data )
88+ {
89+ struct index_state * istate = data ;
90+ struct split_index * si = istate -> split_index ;
91+ struct cache_entry * dst , * src ;
92+ if (pos >= istate -> cache_nr )
93+ die ("position for replacement %d exceeds base index size %d" ,
94+ (int )pos , istate -> cache_nr );
95+ if (si -> nr_replacements >= si -> saved_cache_nr )
96+ die ("too many replacements (%d vs %d)" ,
97+ si -> nr_replacements , si -> saved_cache_nr );
98+ dst = istate -> cache [pos ];
99+ if (dst -> ce_flags & CE_REMOVE )
100+ die ("entry %d is marked as both replaced and deleted" ,
101+ (int )pos );
102+ src = si -> saved_cache [si -> nr_replacements ];
103+ src -> index = pos + 1 ;
104+ src -> ce_flags |= CE_UPDATE_IN_BASE ;
105+ free (dst );
106+ dst = src ;
107+ si -> nr_replacements ++ ;
108+ }
109+
63110void merge_base_index (struct index_state * istate )
64111{
65112 struct split_index * si = istate -> split_index ;
113+ unsigned int i ;
66114
67115 mark_base_index_entries (si -> base );
68- istate -> cache_nr = si -> base -> cache_nr ;
116+
117+ si -> saved_cache = istate -> cache ;
118+ si -> saved_cache_nr = istate -> cache_nr ;
119+ istate -> cache_nr = si -> base -> cache_nr ;
120+ istate -> cache = NULL ;
121+ istate -> cache_alloc = 0 ;
69122 ALLOC_GROW (istate -> cache , istate -> cache_nr , istate -> cache_alloc );
70123 memcpy (istate -> cache , si -> base -> cache ,
71124 sizeof (* istate -> cache ) * istate -> cache_nr );
125+
126+ si -> nr_deletions = 0 ;
127+ si -> nr_replacements = 0 ;
128+ ewah_each_bit (si -> replace_bitmap , replace_entry , istate );
129+ ewah_each_bit (si -> delete_bitmap , mark_entry_for_delete , istate );
130+ if (si -> nr_deletions )
131+ remove_marked_cache_entries (istate );
132+
133+ for (i = si -> nr_replacements ; i < si -> saved_cache_nr ; i ++ ) {
134+ add_index_entry (istate , si -> saved_cache [i ],
135+ ADD_CACHE_OK_TO_ADD |
136+ /*
137+ * we may have to replay what
138+ * merge-recursive.c:update_stages()
139+ * does, which has this flag on
140+ */
141+ ADD_CACHE_SKIP_DFCHECK );
142+ si -> saved_cache [i ] = NULL ;
143+ }
144+
145+ ewah_free (si -> delete_bitmap );
146+ ewah_free (si -> replace_bitmap );
147+ free (si -> saved_cache );
148+ si -> delete_bitmap = NULL ;
149+ si -> replace_bitmap = NULL ;
150+ si -> saved_cache = NULL ;
151+ si -> saved_cache_nr = 0 ;
72152}
73153
74154void prepare_to_write_split_index (struct index_state * istate )
0 commit comments