@@ -1101,78 +1101,64 @@ static void write_reused_pack_one(struct packed_git *reuse_packfile,
1101
1101
1102
1102
static size_t write_reused_pack_verbatim (struct bitmapped_pack * reuse_packfile ,
1103
1103
struct hashfile * out ,
1104
- off_t pack_start ,
1105
1104
struct pack_window * * w_curs )
1106
1105
{
1107
- size_t pos = reuse_packfile -> bitmap_pos ;
1106
+ size_t pos = 0 ;
1108
1107
size_t end ;
1109
1108
1110
- if (pos % BITS_IN_EWORD ) {
1111
- size_t word_pos = (pos / BITS_IN_EWORD );
1112
- size_t offset = pos % BITS_IN_EWORD ;
1113
- size_t last ;
1114
- eword_t word = reuse_packfile_bitmap -> words [word_pos ];
1115
-
1116
- if (offset + reuse_packfile -> bitmap_nr < BITS_IN_EWORD )
1117
- last = offset + reuse_packfile -> bitmap_nr ;
1118
- else
1119
- last = BITS_IN_EWORD ;
1120
-
1121
- for (; offset < last ; offset ++ ) {
1122
- if (word >> offset == 0 )
1123
- return word_pos ;
1124
- if (!bitmap_get (reuse_packfile_bitmap ,
1125
- word_pos * BITS_IN_EWORD + offset ))
1126
- return word_pos ;
1127
- }
1128
-
1129
- pos += BITS_IN_EWORD - (pos % BITS_IN_EWORD );
1109
+ if (reuse_packfile -> bitmap_pos ) {
1110
+ /*
1111
+ * We can't reuse whole chunks verbatim out of
1112
+ * non-preferred packs since we can't guarantee that
1113
+ * all duplicate objects were resolved in favor of
1114
+ * that pack.
1115
+ *
1116
+ * Even if we have a whole eword_t worth of bits that
1117
+ * could be reused, there may be objects between the
1118
+ * objects corresponding to the first and last bit of
1119
+ * that word which were selected from a different
1120
+ * pack, causing us to send duplicate or unwanted
1121
+ * objects.
1122
+ *
1123
+ * Handle non-preferred packs from within
1124
+ * write_reused_pack(), which inspects and reuses
1125
+ * individual bits.
1126
+ */
1127
+ return reuse_packfile -> bitmap_pos / BITS_IN_EWORD ;
1130
1128
}
1131
1129
1132
1130
/*
1133
- * Now we're going to copy as many whole eword_t's as possible.
1134
- * "end" is the index of the last whole eword_t we copy, but
1135
- * there may be additional bits to process. Those are handled
1136
- * individually by write_reused_pack().
1131
+ * Only read through the last word whose bits all correspond
1132
+ * to objects in the given packfile, since we must stop at a
1133
+ * word boundary.
1137
1134
*
1138
- * Begin by advancing to the first word boundary in range of the
1139
- * bit positions occupied by objects in "reuse_packfile". Then
1140
- * pick the last word boundary in the same range. If we have at
1141
- * least one word's worth of bits to process, continue on.
1135
+ * If there is no whole word to read (i.e. the packfile
1136
+ * contains fewer than BITS_IN_EWORD objects), then we'll
1137
+ * inspect bits one-by-one in write_reused_pack().
1142
1138
*/
1143
- end = reuse_packfile -> bitmap_pos + reuse_packfile -> bitmap_nr ;
1144
- if (end % BITS_IN_EWORD )
1145
- end -= end % BITS_IN_EWORD ;
1146
- if (pos >= end )
1147
- return reuse_packfile -> bitmap_pos / BITS_IN_EWORD ;
1148
-
1149
- while (pos < end &&
1150
- reuse_packfile_bitmap -> words [pos / BITS_IN_EWORD ] == (eword_t )~0 )
1151
- pos += BITS_IN_EWORD ;
1139
+ end = reuse_packfile -> bitmap_nr / BITS_IN_EWORD ;
1140
+ if (reuse_packfile_bitmap -> word_alloc < end )
1141
+ BUG ("fewer words than expected in reuse_packfile_bitmap" );
1152
1142
1153
- if (pos > end )
1154
- pos = end ;
1143
+ while (pos < end && reuse_packfile_bitmap -> words [ pos ] == ( eword_t )~ 0 )
1144
+ pos ++ ;
1155
1145
1156
- if (reuse_packfile -> bitmap_pos < pos ) {
1157
- off_t pack_start_off = pack_pos_to_offset (reuse_packfile -> p , 0 );
1158
- off_t pack_end_off = pack_pos_to_offset (reuse_packfile -> p ,
1159
- pos - reuse_packfile -> bitmap_pos );
1146
+ if (pos ) {
1147
+ off_t to_write ;
1160
1148
1161
- written += pos - reuse_packfile -> bitmap_pos ;
1149
+ written = (pos * BITS_IN_EWORD );
1150
+ to_write = pack_pos_to_offset (reuse_packfile -> p , written )
1151
+ - sizeof (struct pack_header );
1162
1152
1163
1153
/* We're recording one chunk, not one object. */
1164
- record_reused_object (pack_start_off ,
1165
- pack_start_off - (hashfile_total (out ) - pack_start ));
1154
+ record_reused_object (sizeof (struct pack_header ), 0 );
1166
1155
hashflush (out );
1167
1156
copy_pack_data (out , reuse_packfile -> p , w_curs ,
1168
- pack_start_off , pack_end_off - pack_start_off );
1157
+ sizeof ( struct pack_header ), to_write );
1169
1158
1170
1159
display_progress (progress_state , written );
1171
1160
}
1172
- if (pos % BITS_IN_EWORD )
1173
- BUG ("attempted to jump past a word boundary to %" PRIuMAX ,
1174
- (uintmax_t )pos );
1175
- return pos / BITS_IN_EWORD ;
1161
+ return pos ;
1176
1162
}
1177
1163
1178
1164
static void write_reused_pack (struct bitmapped_pack * reuse_packfile ,
@@ -1184,8 +1170,7 @@ static void write_reused_pack(struct bitmapped_pack *reuse_packfile,
1184
1170
struct pack_window * w_curs = NULL ;
1185
1171
1186
1172
if (allow_ofs_delta )
1187
- i = write_reused_pack_verbatim (reuse_packfile , f , pack_start ,
1188
- & w_curs );
1173
+ i = write_reused_pack_verbatim (reuse_packfile , f , & w_curs );
1189
1174
1190
1175
for (; i < reuse_packfile_bitmap -> word_alloc ; ++ i ) {
1191
1176
eword_t word = reuse_packfile_bitmap -> words [i ];
0 commit comments