@@ -1098,7 +1098,7 @@ static int verify_hdr(struct cache_header *hdr, unsigned long size)
1098
1098
1099
1099
if (hdr -> hdr_signature != htonl (CACHE_SIGNATURE ))
1100
1100
return error ("bad signature" );
1101
- if (hdr -> hdr_version != htonl (2 ))
1101
+ if (hdr -> hdr_version != htonl (2 ) && hdr -> hdr_version != htonl ( 3 ) )
1102
1102
return error ("bad index version" );
1103
1103
git_SHA1_Init (& c );
1104
1104
git_SHA1_Update (& c , hdr , size - 20 );
@@ -1133,6 +1133,7 @@ int read_index(struct index_state *istate)
1133
1133
static void convert_from_disk (struct ondisk_cache_entry * ondisk , struct cache_entry * ce )
1134
1134
{
1135
1135
size_t len ;
1136
+ const char * name ;
1136
1137
1137
1138
ce -> ce_ctime = ntohl (ondisk -> ctime .sec );
1138
1139
ce -> ce_mtime = ntohl (ondisk -> mtime .sec );
@@ -1145,19 +1146,31 @@ static void convert_from_disk(struct ondisk_cache_entry *ondisk, struct cache_en
1145
1146
/* On-disk flags are just 16 bits */
1146
1147
ce -> ce_flags = ntohs (ondisk -> flags );
1147
1148
1148
- /* For future extension: we do not understand this entry yet */
1149
- if (ce -> ce_flags & CE_EXTENDED )
1150
- die ("Unknown index entry format" );
1151
1149
hashcpy (ce -> sha1 , ondisk -> sha1 );
1152
1150
1153
1151
len = ce -> ce_flags & CE_NAMEMASK ;
1152
+
1153
+ if (ce -> ce_flags & CE_EXTENDED ) {
1154
+ struct ondisk_cache_entry_extended * ondisk2 ;
1155
+ int extended_flags ;
1156
+ ondisk2 = (struct ondisk_cache_entry_extended * )ondisk ;
1157
+ extended_flags = ntohs (ondisk2 -> flags2 ) << 16 ;
1158
+ /* We do not yet understand any bit out of CE_EXTENDED_FLAGS */
1159
+ if (extended_flags & ~CE_EXTENDED_FLAGS )
1160
+ die ("Unknown index entry format %08x" , extended_flags );
1161
+ ce -> ce_flags |= extended_flags ;
1162
+ name = ondisk2 -> name ;
1163
+ }
1164
+ else
1165
+ name = ondisk -> name ;
1166
+
1154
1167
if (len == CE_NAMEMASK )
1155
- len = strlen (ondisk -> name );
1168
+ len = strlen (name );
1156
1169
/*
1157
1170
* NEEDSWORK: If the original index is crafted, this copy could
1158
1171
* go unchecked.
1159
1172
*/
1160
- memcpy (ce -> name , ondisk -> name , len + 1 );
1173
+ memcpy (ce -> name , name , len + 1 );
1161
1174
}
1162
1175
1163
1176
static inline size_t estimate_cache_size (size_t ondisk_size , unsigned int entries )
@@ -1417,6 +1430,7 @@ static int ce_write_entry(git_SHA_CTX *c, int fd, struct cache_entry *ce)
1417
1430
{
1418
1431
int size = ondisk_ce_size (ce );
1419
1432
struct ondisk_cache_entry * ondisk = xcalloc (1 , size );
1433
+ char * name ;
1420
1434
1421
1435
ondisk -> ctime .sec = htonl (ce -> ce_ctime );
1422
1436
ondisk -> ctime .nsec = 0 ;
@@ -1430,7 +1444,15 @@ static int ce_write_entry(git_SHA_CTX *c, int fd, struct cache_entry *ce)
1430
1444
ondisk -> size = htonl (ce -> ce_size );
1431
1445
hashcpy (ondisk -> sha1 , ce -> sha1 );
1432
1446
ondisk -> flags = htons (ce -> ce_flags );
1433
- memcpy (ondisk -> name , ce -> name , ce_namelen (ce ));
1447
+ if (ce -> ce_flags & CE_EXTENDED ) {
1448
+ struct ondisk_cache_entry_extended * ondisk2 ;
1449
+ ondisk2 = (struct ondisk_cache_entry_extended * )ondisk ;
1450
+ ondisk2 -> flags2 = htons ((ce -> ce_flags & CE_EXTENDED_FLAGS ) >> 16 );
1451
+ name = ondisk2 -> name ;
1452
+ }
1453
+ else
1454
+ name = ondisk -> name ;
1455
+ memcpy (name , ce -> name , ce_namelen (ce ));
1434
1456
1435
1457
return ce_write (c , fd , ondisk , size );
1436
1458
}
@@ -1439,16 +1461,25 @@ int write_index(const struct index_state *istate, int newfd)
1439
1461
{
1440
1462
git_SHA_CTX c ;
1441
1463
struct cache_header hdr ;
1442
- int i , err , removed ;
1464
+ int i , err , removed , extended ;
1443
1465
struct cache_entry * * cache = istate -> cache ;
1444
1466
int entries = istate -> cache_nr ;
1445
1467
1446
- for (i = removed = 0 ; i < entries ; i ++ )
1468
+ for (i = removed = extended = 0 ; i < entries ; i ++ ) {
1447
1469
if (cache [i ]-> ce_flags & CE_REMOVE )
1448
1470
removed ++ ;
1449
1471
1472
+ /* reduce extended entries if possible */
1473
+ cache [i ]-> ce_flags &= ~CE_EXTENDED ;
1474
+ if (cache [i ]-> ce_flags & CE_EXTENDED_FLAGS ) {
1475
+ extended ++ ;
1476
+ cache [i ]-> ce_flags |= CE_EXTENDED ;
1477
+ }
1478
+ }
1479
+
1450
1480
hdr .hdr_signature = htonl (CACHE_SIGNATURE );
1451
- hdr .hdr_version = htonl (2 );
1481
+ /* for extended format, increase version so older git won't try to read it */
1482
+ hdr .hdr_version = htonl (extended ? 3 : 2 );
1452
1483
hdr .hdr_entries = htonl (entries - removed );
1453
1484
1454
1485
git_SHA1_Init (& c );
0 commit comments