The index can now store and retrieve the ce_conv_flags data. Signed-off-by: Henrik Grubbström <grubba@xxxxxxxxxx> --- The on disk format has changed slightly due to the changes in the previous patch, but the change should have minimal impact, since it typically only would force a one-time reindex. read-cache.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 59 insertions(+), 6 deletions(-) diff --git a/read-cache.c b/read-cache.c index eeda928..630e001 100644 --- a/read-cache.c +++ b/read-cache.c @@ -27,6 +27,7 @@ static struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int reall #define CACHE_EXT(s) ( (s[0]<<24)|(s[1]<<16)|(s[2]<<8)|(s[3]) ) #define CACHE_EXT_TREE 0x54524545 /* "TREE" */ #define CACHE_EXT_RESOLVE_UNDO 0x52455543 /* "REUC" */ +#define CACHE_EXT_CONV 0x434f4e56 /* "CONV" */ struct index_state the_index; @@ -1209,6 +1210,34 @@ static int verify_hdr(struct cache_header *hdr, unsigned long size) return 0; } +/* The on disk format is the default conversion flags followed + * by alternating cache entry numbers and corresponding flags. + */ +static int conv_read(struct cache_entry **cache, unsigned int entries, + const unsigned int *data, unsigned long sz) +{ + unsigned int entry_no; + unsigned int default_conv_flags; + if (sz < sizeof(*data)) + return 0; + default_conv_flags = ntohl(*data); + data++; + sz -= sizeof(*data); + if (default_conv_flags) { + for (entry_no = 0; entry_no < entries; entry_no++) + cache[entry_no]->ce_conv_flags = default_conv_flags; + } + while (sz >= 2*sizeof(*data)) { + entry_no = ntohl(*data); + data++; + if (entry_no >= entries) break; + cache[entry_no]->ce_conv_flags = ntohl(*data); + data++; + sz -= 2*sizeof(*data); + } + return 0; +} + static int read_index_extension(struct index_state *istate, const char *ext, void *data, unsigned long sz) { @@ -1219,6 +1248,9 @@ static int read_index_extension(struct index_state *istate, case CACHE_EXT_RESOLVE_UNDO: istate->resolve_undo = resolve_undo_read(data, sz); break; + case CACHE_EXT_CONV: + return conv_read(istate->cache, istate->cache_nr, data, sz); + break; default: if (*ext < 'A' || 'Z' < *ext) return error("index uses %.4s extension, which we do not understand", @@ -1542,6 +1574,15 @@ static void ce_smudge_racily_clean_entry(struct cache_entry *ce) } } +static void conv_write(struct strbuf *sb, const struct cache_entry *ce, + int entry_no) +{ + unsigned int entry[2]; + entry[0] = htonl(entry_no); + entry[1] = htonl(ce->ce_conv_flags); + strbuf_add(sb, &entry, sizeof(entry)); +} + static int ce_write_entry(git_SHA_CTX *c, int fd, struct cache_entry *ce) { int size = ondisk_ce_size(ce); @@ -1577,10 +1618,12 @@ int write_index(struct index_state *istate, int newfd) { git_SHA_CTX c; struct cache_header hdr; - int i, err, removed, extended; + int i, j, err, removed, extended; struct cache_entry **cache = istate->cache; int entries = istate->cache_nr; struct stat st; + struct strbuf sb = STRBUF_INIT; + unsigned int default_conv_flags; for (i = removed = extended = 0; i < entries; i++) { if (cache[i]->ce_flags & CE_REMOVE) @@ -1603,7 +1646,10 @@ int write_index(struct index_state *istate, int newfd) if (ce_write(&c, newfd, &hdr, sizeof(hdr)) < 0) return -1; - for (i = 0; i < entries; i++) { + default_conv_flags = git_conv_flags(""); + strbuf_add_uint32(&sb, default_conv_flags); + + for (i = j = 0; i < entries; i++) { struct cache_entry *ce = cache[i]; if (ce->ce_flags & CE_REMOVE) continue; @@ -1611,12 +1657,21 @@ int write_index(struct index_state *istate, int newfd) ce_smudge_racily_clean_entry(ce); if (ce_write_entry(&c, newfd, ce) < 0) return -1; + if (ce->ce_conv_flags != default_conv_flags) + conv_write(&sb, ce, j); + j++; } /* Write extension data here */ + if (default_conv_flags || sb.len > sizeof(default_conv_flags)) { + err = write_index_ext_header(&c, newfd, CACHE_EXT_CONV, sb.len) < 0 + || ce_write(&c, newfd, sb.buf, sb.len) < 0; + strbuf_release(&sb); + if (err) + return -1; + } else + strbuf_release(&sb); if (istate->cache_tree) { - struct strbuf sb = STRBUF_INIT; - cache_tree_write(&sb, istate->cache_tree); err = write_index_ext_header(&c, newfd, CACHE_EXT_TREE, sb.len) < 0 || ce_write(&c, newfd, sb.buf, sb.len) < 0; @@ -1625,8 +1680,6 @@ int write_index(struct index_state *istate, int newfd) return -1; } if (istate->resolve_undo) { - struct strbuf sb = STRBUF_INIT; - resolve_undo_write(&sb, istate->resolve_undo); err = write_index_ext_header(&c, newfd, CACHE_EXT_RESOLVE_UNDO, sb.len) < 0 -- 1.7.0.4.369.g81e89 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html