@ -1499,6 +1499,7 @@ struct ondisk_cache_entry_extended {
@@ -1499,6 +1499,7 @@ struct ondisk_cache_entry_extended {
};
/* These are only used for v3 or lower */
#define align_padding_size(size, len) ((size + (len) + 8) & ~7) - (size + len)
#define align_flex_name(STRUCT,len) ((offsetof(struct STRUCT,name) + (len) + 8) & ~7)
#define ondisk_cache_entry_size(len) align_flex_name(ondisk_cache_entry,len)
#define ondisk_cache_entry_extended_size(len) align_flex_name(ondisk_cache_entry_extended,len)
@ -2032,7 +2033,7 @@ static void ce_smudge_racily_clean_entry(struct cache_entry *ce)
@@ -2032,7 +2033,7 @@ static void ce_smudge_racily_clean_entry(struct cache_entry *ce)
}
/* Copy miscellaneous fields but not the name */
static char *copy_cache_entry_to_ondisk(struct ondisk_cache_entry *ondisk,
static void copy_cache_entry_to_ondisk(struct ondisk_cache_entry *ondisk,
struct cache_entry *ce)
{
short flags;
@ -2056,32 +2057,35 @@ static char *copy_cache_entry_to_ondisk(struct ondisk_cache_entry *ondisk,
@@ -2056,32 +2057,35 @@ static char *copy_cache_entry_to_ondisk(struct ondisk_cache_entry *ondisk,
struct ondisk_cache_entry_extended *ondisk2;
ondisk2 = (struct ondisk_cache_entry_extended *)ondisk;
ondisk2->flags2 = htons((ce->ce_flags & CE_EXTENDED_FLAGS) >> 16);
return ondisk2->name;
}
else {
return ondisk->name;
}
}
static int ce_write_entry(git_SHA_CTX *c, int fd, struct cache_entry *ce,
struct strbuf *previous_name)
struct strbuf *previous_name, struct ondisk_cache_entry *ondisk)
{
int size;
struct ondisk_cache_entry *ondisk;
int saved_namelen = saved_namelen; /* compiler workaround */
char *name;
int result;
static unsigned char padding[8] = { 0x00 };
if (ce->ce_flags & CE_STRIP_NAME) {
saved_namelen = ce_namelen(ce);
ce->ce_namelen = 0;
}
if (ce->ce_flags & CE_EXTENDED)
size = offsetof(struct ondisk_cache_entry_extended, name);
else
size = offsetof(struct ondisk_cache_entry, name);
if (!previous_name) {
size = ondisk_ce_size(ce);
ondisk = xcalloc(1, size);
name = copy_cache_entry_to_ondisk(ondisk, ce);
memcpy(name, ce->name, ce_namelen(ce));
int len = ce_namelen(ce);
copy_cache_entry_to_ondisk(ondisk, ce);
result = ce_write(c, fd, ondisk, size);
if (!result)
result = ce_write(c, fd, ce->name, len);
if (!result)
result = ce_write(c, fd, padding, align_padding_size(size, len));
} else {
int common, to_remove, prefix_size;
unsigned char to_remove_vi[16];
@ -2094,16 +2098,12 @@ static int ce_write_entry(git_SHA_CTX *c, int fd, struct cache_entry *ce,
@@ -2094,16 +2098,12 @@ static int ce_write_entry(git_SHA_CTX *c, int fd, struct cache_entry *ce,
to_remove = previous_name->len - common;
prefix_size = encode_varint(to_remove, to_remove_vi);
if (ce->ce_flags & CE_EXTENDED)
size = offsetof(struct ondisk_cache_entry_extended, name);
else
size = offsetof(struct ondisk_cache_entry, name);
size += prefix_size + (ce_namelen(ce) - common + 1);
ondisk = xcalloc(1, size);
name = copy_cache_entry_to_ondisk(ondisk, ce);
memcpy(name, to_remove_vi, prefix_size);
memcpy(name + prefix_size, ce->name + common, ce_namelen(ce) - common);
copy_cache_entry_to_ondisk(ondisk, ce);
result = ce_write(c, fd, ondisk, size);
if (!result)
result = ce_write(c, fd, to_remove_vi, prefix_size);
if (!result)
result = ce_write(c, fd, ce->name + common, ce_namelen(ce) - common + 1);
strbuf_splice(previous_name, common, to_remove,
ce->name + common, ce_namelen(ce) - common);
@ -2113,8 +2113,6 @@ static int ce_write_entry(git_SHA_CTX *c, int fd, struct cache_entry *ce,
@@ -2113,8 +2113,6 @@ static int ce_write_entry(git_SHA_CTX *c, int fd, struct cache_entry *ce,
ce->ce_flags &= ~CE_STRIP_NAME;
}
result = ce_write(c, fd, ondisk, size);
free(ondisk);
return result;
}
@ -2196,6 +2194,7 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
@@ -2196,6 +2194,7 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
struct cache_entry **cache = istate->cache;
int entries = istate->cache_nr;
struct stat st;
struct ondisk_cache_entry_extended ondisk;
struct strbuf previous_name_buf = STRBUF_INIT, *previous_name;
int drop_cache_tree = 0;
@ -2232,6 +2231,7 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
@@ -2232,6 +2231,7 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
return -1;
previous_name = (hdr_version == 4) ? &previous_name_buf : NULL;
for (i = 0; i < entries; i++) {
struct cache_entry *ce = cache[i];
if (ce->ce_flags & CE_REMOVE)
@ -2251,7 +2251,7 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
@@ -2251,7 +2251,7 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
drop_cache_tree = 1;
}
if (ce_write_entry(&c, newfd, ce, previous_name) < 0)
if (ce_write_entry(&c, newfd, ce, previous_name, (struct ondisk_cache_entry *)&ondisk) < 0)
err = -1;
if (err)