Merge branch 'sh/write-pack-file-warning-message-fix'
[gitweb.git] / read-cache.c
index bb38115a9dfb7d3745c25e18ab9ab4e9e54f87a3..f23c44a81a56f43e95a0e14fb37a84bac1a06caf 100644 (file)
@@ -15,7 +15,8 @@
 #include "strbuf.h"
 #include "varint.h"
 
-static struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really);
+static struct cache_entry *refresh_cache_entry(struct cache_entry *ce,
+                                              unsigned int options);
 
 /* Mask for the name length in ce_flags in the on-disk index */
 
@@ -47,6 +48,7 @@ static void replace_index_entry(struct index_state *istate, int nr, struct cache
        struct cache_entry *old = istate->cache[nr];
 
        remove_name_hash(istate, old);
+       free(old);
        set_index_entry(istate, nr, ce);
        istate->cache_changed = 1;
 }
@@ -58,7 +60,7 @@ void rename_index_entry_at(struct index_state *istate, int nr, const char *new_n
 
        new = xmalloc(cache_entry_size(namelen));
        copy_cache_entry(new, old);
-       new->ce_flags &= ~CE_STATE_MASK;
+       new->ce_flags &= ~CE_HASHED;
        new->ce_namelen = namelen;
        memcpy(new->name, new_name, namelen + 1);
 
@@ -478,6 +480,7 @@ int remove_index_entry_at(struct index_state *istate, int pos)
 
        record_resolve_undo(istate, ce);
        remove_name_hash(istate, ce);
+       free(ce);
        istate->cache_changed = 1;
        istate->cache_nr--;
        if (pos >= istate->cache_nr)
@@ -499,8 +502,10 @@ void remove_marked_cache_entries(struct index_state *istate)
        unsigned int i, j;
 
        for (i = j = 0; i < istate->cache_nr; i++) {
-               if (ce_array[i]->ce_flags & CE_REMOVE)
+               if (ce_array[i]->ce_flags & CE_REMOVE) {
                        remove_name_hash(istate, ce_array[i]);
+                       free(ce_array[i]);
+               }
                else
                        ce_array[j++] = ce_array[i];
        }
@@ -579,7 +584,7 @@ static struct cache_entry *create_alias_ce(struct cache_entry *ce, struct cache_
        return new;
 }
 
-static void record_intent_to_add(struct cache_entry *ce)
+void set_object_name_for_intent_to_add_entry(struct cache_entry *ce)
 {
        unsigned char sha1[20];
        if (write_sha1_file("", 0, blob_type, sha1))
@@ -643,7 +648,7 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
                        if (*ptr == '/') {
                                struct cache_entry *foundce;
                                ++ptr;
-                               foundce = index_name_exists(istate, ce->name, ptr - ce->name, ignore_case);
+                               foundce = index_dir_exists(istate, ce->name, ptr - ce->name - 1);
                                if (foundce) {
                                        memcpy((void *)startPtr, foundce->name + (startPtr - ce->name), ptr - startPtr);
                                        startPtr = ptr;
@@ -652,7 +657,7 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
                }
        }
 
-       alias = index_name_exists(istate, ce->name, ce_namelen(ce), ignore_case);
+       alias = index_file_exists(istate, ce->name, ce_namelen(ce), ignore_case);
        if (alias && !ce_stage(alias) && !ie_match_stat(istate, alias, st, ce_option)) {
                /* Nothing changed, really */
                free(ce);
@@ -665,7 +670,7 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
                if (index_path(ce->sha1, path, st, HASH_WRITE_OBJECT))
                        return error("unable to index file %s", path);
        } else
-               record_intent_to_add(ce);
+               set_object_name_for_intent_to_add_entry(ce);
 
        if (ignore_case && alias && different_name(ce, alias))
                ce = create_alias_ce(ce, alias);
@@ -696,7 +701,7 @@ int add_file_to_index(struct index_state *istate, const char *path, int flags)
 
 struct cache_entry *make_cache_entry(unsigned int mode,
                const unsigned char *sha1, const char *path, int stage,
-               int refresh)
+               unsigned int refresh_options)
 {
        int size, len;
        struct cache_entry *ce;
@@ -716,10 +721,7 @@ struct cache_entry *make_cache_entry(unsigned int mode,
        ce->ce_namelen = len;
        ce->ce_mode = create_ce_mode(mode);
 
-       if (refresh)
-               return refresh_cache_entry(ce, 0);
-
-       return ce;
+       return refresh_cache_entry(ce, refresh_options);
 }
 
 int ce_same_name(const struct cache_entry *a, const struct cache_entry *b)
@@ -728,11 +730,6 @@ int ce_same_name(const struct cache_entry *a, const struct cache_entry *b)
        return ce_namelen(b) == len && !memcmp(a->name, b->name, len);
 }
 
-int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec)
-{
-       return match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, NULL);
-}
-
 /*
  * We fundamentally don't like some paths: we don't want
  * dot or dot-dot anywhere, and for obvious reasons don't
@@ -1029,11 +1026,12 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,
        struct stat st;
        struct cache_entry *updated;
        int changed, size;
+       int refresh = options & CE_MATCH_REFRESH;
        int ignore_valid = options & CE_MATCH_IGNORE_VALID;
        int ignore_skip_worktree = options & CE_MATCH_IGNORE_SKIP_WORKTREE;
        int ignore_missing = options & CE_MATCH_IGNORE_MISSING;
 
-       if (ce_uptodate(ce))
+       if (!refresh || ce_uptodate(ce))
                return ce;
 
        /*
@@ -1117,7 +1115,8 @@ static void show_file(const char * fmt, const char * name, int in_porcelain,
        printf(fmt, name);
 }
 
-int refresh_index(struct index_state *istate, unsigned int flags, const char **pathspec,
+int refresh_index(struct index_state *istate, unsigned int flags,
+                 const struct pathspec *pathspec,
                  char *seen, const char *header_msg)
 {
        int i;
@@ -1129,7 +1128,8 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
        int ignore_submodules = (flags & REFRESH_IGNORE_SUBMODULES) != 0;
        int first = 1;
        int in_porcelain = (flags & REFRESH_IN_PORCELAIN);
-       unsigned int options = ((really ? CE_MATCH_IGNORE_VALID : 0) |
+       unsigned int options = (CE_MATCH_REFRESH |
+                               (really ? CE_MATCH_IGNORE_VALID : 0) |
                                (not_new ? CE_MATCH_IGNORE_MISSING : 0));
        const char *modified_fmt;
        const char *deleted_fmt;
@@ -1152,8 +1152,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
                if (ignore_submodules && S_ISGITLINK(ce->ce_mode))
                        continue;
 
-               if (pathspec &&
-                   !match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen))
+               if (pathspec && !ce_path_match(ce, pathspec, seen))
                        filtered = 1;
 
                if (ce_stage(ce)) {
@@ -1208,9 +1207,10 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
        return has_errors;
 }
 
-static struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really)
+static struct cache_entry *refresh_cache_entry(struct cache_entry *ce,
+                                              unsigned int options)
 {
-       return refresh_cache_ent(&the_index, ce, really, NULL, NULL);
+       return refresh_cache_ent(&the_index, ce, options, NULL, NULL);
 }
 
 
@@ -1220,6 +1220,42 @@ static struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int reall
 
 #define INDEX_FORMAT_DEFAULT 3
 
+static int index_format_config(const char *var, const char *value, void *cb)
+{
+       unsigned int *version = cb;
+       if (!strcmp(var, "index.version")) {
+               *version = git_config_int(var, value);
+               return 0;
+       }
+       return 1;
+}
+
+static unsigned int get_index_format_default(void)
+{
+       char *envversion = getenv("GIT_INDEX_VERSION");
+       char *endp;
+       unsigned int version = INDEX_FORMAT_DEFAULT;
+
+       if (!envversion) {
+               git_config(index_format_config, &version);
+               if (version < INDEX_FORMAT_LB || INDEX_FORMAT_UB < version) {
+                       warning(_("index.version set, but the value is invalid.\n"
+                                 "Using version %i"), INDEX_FORMAT_DEFAULT);
+                       return INDEX_FORMAT_DEFAULT;
+               }
+               return version;
+       }
+
+       version = strtoul(envversion, &endp, 10);
+       if (*endp ||
+           version < INDEX_FORMAT_LB || INDEX_FORMAT_UB < version) {
+               warning(_("GIT_INDEX_VERSION set, but the value is invalid.\n"
+                         "Using version %i"), INDEX_FORMAT_DEFAULT);
+               version = INDEX_FORMAT_DEFAULT;
+       }
+       return version;
+}
+
 /*
  * dev/ino/uid/gid/size are also just tracked to the low 32 bits
  * Again - this is just a (very strong in practice) heuristic that
@@ -1231,14 +1267,14 @@ static struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int reall
 struct ondisk_cache_entry {
        struct cache_time ctime;
        struct cache_time mtime;
-       unsigned int dev;
-       unsigned int ino;
-       unsigned int mode;
-       unsigned int uid;
-       unsigned int gid;
-       unsigned int size;
+       uint32_t dev;
+       uint32_t ino;
+       uint32_t mode;
+       uint32_t uid;
+       uint32_t gid;
+       uint32_t size;
        unsigned char sha1[20];
-       unsigned short flags;
+       uint16_t flags;
        char name[FLEX_ARRAY]; /* more */
 };
 
@@ -1250,15 +1286,15 @@ struct ondisk_cache_entry {
 struct ondisk_cache_entry_extended {
        struct cache_time ctime;
        struct cache_time mtime;
-       unsigned int dev;
-       unsigned int ino;
-       unsigned int mode;
-       unsigned int uid;
-       unsigned int gid;
-       unsigned int size;
+       uint32_t dev;
+       uint32_t ino;
+       uint32_t mode;
+       uint32_t uid;
+       uint32_t gid;
+       uint32_t size;
        unsigned char sha1[20];
-       unsigned short flags;
-       unsigned short flags2;
+       uint16_t flags;
+       uint16_t flags2;
        char name[FLEX_ARRAY]; /* more */
 };
 
@@ -1314,26 +1350,6 @@ int read_index(struct index_state *istate)
        return read_index_from(istate, get_index_file());
 }
 
-#ifndef NEEDS_ALIGNED_ACCESS
-#define ntoh_s(var) ntohs(var)
-#define ntoh_l(var) ntohl(var)
-#else
-static inline uint16_t ntoh_s_force_align(void *p)
-{
-       uint16_t x;
-       memcpy(&x, p, sizeof(x));
-       return ntohs(x);
-}
-static inline uint32_t ntoh_l_force_align(void *p)
-{
-       uint32_t x;
-       memcpy(&x, p, sizeof(x));
-       return ntohl(x);
-}
-#define ntoh_s(var) ntoh_s_force_align(&(var))
-#define ntoh_l(var) ntoh_l_force_align(&(var))
-#endif
-
 static struct cache_entry *cache_entry_from_ondisk(struct ondisk_cache_entry *ondisk,
                                                   unsigned int flags,
                                                   const char *name,
@@ -1341,16 +1357,16 @@ static struct cache_entry *cache_entry_from_ondisk(struct ondisk_cache_entry *on
 {
        struct cache_entry *ce = xmalloc(cache_entry_size(len));
 
-       ce->ce_stat_data.sd_ctime.sec = ntoh_l(ondisk->ctime.sec);
-       ce->ce_stat_data.sd_mtime.sec = ntoh_l(ondisk->mtime.sec);
-       ce->ce_stat_data.sd_ctime.nsec = ntoh_l(ondisk->ctime.nsec);
-       ce->ce_stat_data.sd_mtime.nsec = ntoh_l(ondisk->mtime.nsec);
-       ce->ce_stat_data.sd_dev   = ntoh_l(ondisk->dev);
-       ce->ce_stat_data.sd_ino   = ntoh_l(ondisk->ino);
-       ce->ce_mode  = ntoh_l(ondisk->mode);
-       ce->ce_stat_data.sd_uid   = ntoh_l(ondisk->uid);
-       ce->ce_stat_data.sd_gid   = ntoh_l(ondisk->gid);
-       ce->ce_stat_data.sd_size  = ntoh_l(ondisk->size);
+       ce->ce_stat_data.sd_ctime.sec = get_be32(&ondisk->ctime.sec);
+       ce->ce_stat_data.sd_mtime.sec = get_be32(&ondisk->mtime.sec);
+       ce->ce_stat_data.sd_ctime.nsec = get_be32(&ondisk->ctime.nsec);
+       ce->ce_stat_data.sd_mtime.nsec = get_be32(&ondisk->mtime.nsec);
+       ce->ce_stat_data.sd_dev   = get_be32(&ondisk->dev);
+       ce->ce_stat_data.sd_ino   = get_be32(&ondisk->ino);
+       ce->ce_mode  = get_be32(&ondisk->mode);
+       ce->ce_stat_data.sd_uid   = get_be32(&ondisk->uid);
+       ce->ce_stat_data.sd_gid   = get_be32(&ondisk->gid);
+       ce->ce_stat_data.sd_size  = get_be32(&ondisk->size);
        ce->ce_flags = flags & ~CE_NAMEMASK;
        ce->ce_namelen = len;
        hashcpy(ce->sha1, ondisk->sha1);
@@ -1390,14 +1406,14 @@ static struct cache_entry *create_from_disk(struct ondisk_cache_entry *ondisk,
        unsigned int flags;
 
        /* On-disk flags are just 16 bits */
-       flags = ntoh_s(ondisk->flags);
+       flags = get_be16(&ondisk->flags);
        len = flags & CE_NAMEMASK;
 
        if (flags & CE_EXTENDED) {
                struct ondisk_cache_entry_extended *ondisk2;
                int extended_flags;
                ondisk2 = (struct ondisk_cache_entry_extended *)ondisk;
-               extended_flags = ntoh_s(ondisk2->flags2) << 16;
+               extended_flags = get_be16(&ondisk2->flags2) << 16;
                /* We do not yet understand any bit out of CE_EXTENDED_FLAGS */
                if (extended_flags & ~CE_EXTENDED_FLAGS)
                        die("Unknown index entry format %08x", extended_flags);
@@ -1796,7 +1812,7 @@ int write_index(struct index_state *istate, int newfd)
        }
 
        if (!istate->version)
-               istate->version = INDEX_FORMAT_DEFAULT;
+               istate->version = get_index_format_default();
 
        /* demote version 3 to version 2 when the latter suffices */
        if (istate->version == 3 || istate->version == 2)
@@ -1819,8 +1835,17 @@ int write_index(struct index_state *istate, int newfd)
                        continue;
                if (!ce_uptodate(ce) && is_racy_timestamp(istate, ce))
                        ce_smudge_racily_clean_entry(ce);
-               if (is_null_sha1(ce->sha1))
-                       return error("cache entry has null sha1: %s", ce->name);
+               if (is_null_sha1(ce->sha1)) {
+                       static const char msg[] = "cache entry has null sha1: %s";
+                       static int allow = -1;
+
+                       if (allow < 0)
+                               allow = git_env_bool("GIT_ALLOW_NULL_SHA1", 0);
+                       if (allow)
+                               warning(msg, ce->name);
+                       else
+                               return error(msg, ce->name);
+               }
                if (ce_write_entry(&c, newfd, ce, previous_name) < 0)
                        return -1;
        }
@@ -1886,7 +1911,7 @@ int read_index_unmerged(struct index_state *istate)
                new_ce->ce_mode = ce->ce_mode;
                if (add_index_entry(istate, new_ce, 0))
                        return error("%s: cannot drop to stage #0",
-                                    ce->name);
+                                    new_ce->name);
                i = index_name_pos(istate, new_ce->name, len);
        }
        return unmerged;