@@ -1101,78 +1101,64 @@ static void write_reused_pack_one(struct packed_git *reuse_packfile,
11011101
11021102static size_t write_reused_pack_verbatim (struct bitmapped_pack * reuse_packfile ,
11031103 struct hashfile * out ,
1104- off_t pack_start ,
11051104 struct pack_window * * w_curs )
11061105{
1107- size_t pos = reuse_packfile -> bitmap_pos ;
1106+ size_t pos = 0 ;
11081107 size_t end ;
11091108
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 ;
11301128 }
11311129
11321130 /*
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.
11371134 *
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().
11421138 */
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" );
11521142
1153- if (pos > end )
1154- pos = end ;
1143+ while (pos < end && reuse_packfile_bitmap -> words [ pos ] == ( eword_t )~ 0 )
1144+ pos ++ ;
11551145
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 ;
11601148
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 );
11621152
11631153 /* 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 );
11661155 hashflush (out );
11671156 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 );
11691158
11701159 display_progress (progress_state , written );
11711160 }
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 ;
11761162}
11771163
11781164static void write_reused_pack (struct bitmapped_pack * reuse_packfile ,
@@ -1184,8 +1170,7 @@ static void write_reused_pack(struct bitmapped_pack *reuse_packfile,
11841170 struct pack_window * w_curs = NULL ;
11851171
11861172 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 );
11891174
11901175 for (; i < reuse_packfile_bitmap -> word_alloc ; ++ i ) {
11911176 eword_t word = reuse_packfile_bitmap -> words [i ];
0 commit comments