diff options
Diffstat (limited to 'read-cache.c')
-rw-r--r-- | read-cache.c | 98 |
1 files changed, 64 insertions, 34 deletions
diff --git a/read-cache.c b/read-cache.c index 6f0057fe66..36ff89f29e 100644 --- a/read-cache.c +++ b/read-cache.c @@ -5,6 +5,7 @@ */ #define NO_THE_INDEX_COMPATIBILITY_MACROS #include "cache.h" +#include "lockfile.h" #include "cache-tree.h" #include "refs.h" #include "dir.h" @@ -16,6 +17,7 @@ #include "varint.h" #include "split-index.h" #include "sigchain.h" +#include "utf8.h" static struct cache_entry *refresh_cache_entry(struct cache_entry *ce, unsigned int options); @@ -679,15 +681,18 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st, 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); if (!S_ISGITLINK(alias->ce_mode)) ce_mark_uptodate(alias); alias->ce_flags |= CE_ADDED; + + free(ce); return 0; } if (!intent_only) { - if (index_path(ce->sha1, path, st, HASH_WRITE_OBJECT)) + if (index_path(ce->sha1, path, st, HASH_WRITE_OBJECT)) { + free(ce); return error("unable to index file %s", path); + } } else set_object_name_for_intent_to_add_entry(ce); @@ -702,9 +707,11 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st, ce->ce_mode == alias->ce_mode); if (pretend) - ; - else if (add_index_entry(istate, ce, add_option)) - return error("unable to add %s to index",path); + free(ce); + else if (add_index_entry(istate, ce, add_option)) { + free(ce); + return error("unable to add %s to index", path); + } if (verbose && !was_same) printf("add '%s'\n", path); return 0; @@ -723,7 +730,7 @@ struct cache_entry *make_cache_entry(unsigned int mode, unsigned int refresh_options) { int size, len; - struct cache_entry *ce; + struct cache_entry *ce, *ret; if (!verify_path(path)) { error("Invalid path '%s'", path); @@ -740,7 +747,10 @@ struct cache_entry *make_cache_entry(unsigned int mode, ce->ce_namelen = len; ce->ce_mode = create_ce_mode(mode); - return refresh_cache_entry(ce, refresh_options); + ret = refresh_cache_entry(ce, refresh_options); + if (ret != ce) + free(ce); + return ret; } int ce_same_name(const struct cache_entry *a, const struct cache_entry *b) @@ -775,9 +785,10 @@ static int verify_dotfile(const char *rest) * shares the path end test with the ".." case. */ case 'g': - if (rest[1] != 'i') + case 'G': + if (rest[1] != 'i' && rest[1] != 'I') break; - if (rest[2] != 't') + if (rest[2] != 't' && rest[2] != 'T') break; rest += 2; /* fallthrough */ @@ -801,6 +812,10 @@ int verify_path(const char *path) return 1; if (is_dir_sep(c)) { inside: + if (protect_hfs && is_hfs_dotgit(path)) + return 0; + if (protect_ntfs && is_ntfs_dotgit(path)) + return 0; c = *path++; if ((c == '.' && !verify_dotfile(path)) || is_dir_sep(c) || c == '\0') @@ -1246,24 +1261,16 @@ static struct cache_entry *refresh_cache_entry(struct cache_entry *ce, #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; + int value; unsigned int version = INDEX_FORMAT_DEFAULT; if (!envversion) { - git_config(index_format_config, &version); + if (!git_config_get_int("index.version", &value)) + version = value; 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); @@ -1375,6 +1382,14 @@ static int read_index_extension(struct index_state *istate, return 0; } +int hold_locked_index(struct lock_file *lk, int die_on_error) +{ + return hold_lock_file_for_update(lk, get_index_file(), + die_on_error + ? LOCK_DIE_ON_ERROR + : 0); +} + int read_index(struct index_state *istate) { return read_index_from(istate, get_index_file()); @@ -1473,6 +1488,28 @@ static struct cache_entry *create_from_disk(struct ondisk_cache_entry *ondisk, return ce; } +static void check_ce_order(struct index_state *istate) +{ + unsigned int i; + + for (i = 1; i < istate->cache_nr; i++) { + struct cache_entry *ce = istate->cache[i - 1]; + struct cache_entry *next_ce = istate->cache[i]; + int name_compare = strcmp(ce->name, next_ce->name); + + if (0 < name_compare) + die("unordered stage entries in index"); + if (!name_compare) { + if (!ce_stage(ce)) + die("multiple stage entries for merged file '%s'", + ce->name); + if (ce_stage(ce) > ce_stage(next_ce)) + die("unordered stage entries for '%s'", + ce->name); + } + } +} + /* remember to discard_cache() before reading a different cache! */ int do_read_index(struct index_state *istate, const char *path, int must_exist) { @@ -1577,11 +1614,10 @@ int read_index_from(struct index_state *istate, const char *path) ret = do_read_index(istate, path, 0); split_index = istate->split_index; - if (!split_index) - return ret; - - if (is_null_sha1(split_index->base_sha1)) + if (!split_index || is_null_sha1(split_index->base_sha1)) { + check_ce_order(istate); return ret; + } if (split_index->base) discard_index(split_index->base); @@ -1597,6 +1633,7 @@ int read_index_from(struct index_state *istate, const char *path) sha1_to_hex(split_index->base_sha1)), sha1_to_hex(split_index->base->sha1)); merge_base_index(istate); + check_ce_order(istate); return ret; } @@ -2031,16 +2068,10 @@ void set_alternate_index_output(const char *name) static int commit_locked_index(struct lock_file *lk) { - if (alternate_index_output) { - if (lk->fd >= 0 && close_lock_file(lk)) - return -1; - if (rename(lk->filename, alternate_index_output)) - return -1; - lk->filename[0] = 0; - return 0; - } else { + if (alternate_index_output) + return commit_lock_file_to(lk, alternate_index_output); + else return commit_lock_file(lk); - } } static int do_write_locked_index(struct index_state *istate, struct lock_file *lock, @@ -2180,7 +2211,6 @@ int read_index_unmerged(struct index_state *istate) if (add_index_entry(istate, new_ce, 0)) return error("%s: cannot drop to stage #0", new_ce->name); - i = index_name_pos(istate, new_ce->name, len); } return unmerged; } |