Git.pm: fix return value of config method
[gitweb.git] / read-cache.c
index 8c57adfa166844ec00904187393d97cc7973dd47..8e5fbb619295fe3e4d950e8926d8034d6f825e41 100644 (file)
@@ -198,7 +198,8 @@ static int ce_match_stat_basic(struct cache_entry *ce, struct stat *st)
 
 static int is_racy_timestamp(const struct index_state *istate, struct cache_entry *ce)
 {
-       return (istate->timestamp &&
+       return (!S_ISGITLINK(ce->ce_mode) &&
+               istate->timestamp &&
                ((unsigned int)istate->timestamp) <= ce->ce_mtime);
 }
 
@@ -429,21 +430,52 @@ static int index_name_pos_also_unmerged(struct index_state *istate,
        return pos;
 }
 
-int add_file_to_index(struct index_state *istate, const char *path, int verbose)
+static int different_name(struct cache_entry *ce, struct cache_entry *alias)
 {
-       int size, namelen;
-       struct stat st;
+       int len = ce_namelen(ce);
+       return ce_namelen(alias) != len || memcmp(ce->name, alias->name, len);
+}
+
+/*
+ * If we add a filename that aliases in the cache, we will use the
+ * name that we already have - but we don't want to update the same
+ * alias twice, because that implies that there were actually two
+ * different files with aliasing names!
+ *
+ * So we use the CE_ADDED flag to verify that the alias was an old
+ * one before we accept it as
+ */
+static struct cache_entry *create_alias_ce(struct cache_entry *ce, struct cache_entry *alias)
+{
+       int len;
+       struct cache_entry *new;
+
+       if (alias->ce_flags & CE_ADDED)
+               die("Will not add file alias '%s' ('%s' already exists in index)", ce->name, alias->name);
+
+       /* Ok, create the new entry using the name of the existing alias */
+       len = ce_namelen(alias);
+       new = xcalloc(1, cache_entry_size(len));
+       memcpy(new->name, alias->name, len);
+       copy_cache_entry(new, ce);
+       free(ce);
+       return new;
+}
+
+int add_to_index(struct index_state *istate, const char *path, struct stat *st, int flags)
+{
+       int size, namelen, was_same;
+       mode_t st_mode = st->st_mode;
        struct cache_entry *ce, *alias;
        unsigned ce_option = CE_MATCH_IGNORE_VALID|CE_MATCH_RACY_IS_DIRTY;
+       int verbose = flags & (ADD_CACHE_VERBOSE | ADD_CACHE_PRETEND);
+       int pretend = flags & ADD_CACHE_PRETEND;
 
-       if (lstat(path, &st))
-               die("%s: unable to stat (%s)", path, strerror(errno));
-
-       if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode) && !S_ISDIR(st.st_mode))
-               die("%s: can only add regular files, symbolic links or git-directories", path);
+       if (!S_ISREG(st_mode) && !S_ISLNK(st_mode) && !S_ISDIR(st_mode))
+               return error("%s: can only add regular files, symbolic links or git-directories", path);
 
        namelen = strlen(path);
-       if (S_ISDIR(st.st_mode)) {
+       if (S_ISDIR(st_mode)) {
                while (namelen && path[namelen-1] == '/')
                        namelen--;
        }
@@ -451,10 +483,10 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)
        ce = xcalloc(1, size);
        memcpy(ce->name, path, namelen);
        ce->ce_flags = namelen;
-       fill_stat_cache_info(ce, &st);
+       fill_stat_cache_info(ce, st);
 
        if (trust_executable_bit && has_symlinks)
-               ce->ce_mode = create_ce_mode(st.st_mode);
+               ce->ce_mode = create_ce_mode(st_mode);
        else {
                /* If there is an existing entry, pick the mode bits and type
                 * from it, otherwise assume unexecutable regular file.
@@ -463,26 +495,46 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)
                int pos = index_name_pos_also_unmerged(istate, path, namelen);
 
                ent = (0 <= pos) ? istate->cache[pos] : NULL;
-               ce->ce_mode = ce_mode_from_stat(ent, st.st_mode);
+               ce->ce_mode = ce_mode_from_stat(ent, st_mode);
        }
 
        alias = index_name_exists(istate, ce->name, ce_namelen(ce), ignore_case);
-       if (alias && !ce_stage(alias) && !ie_match_stat(istate, alias, &st, ce_option)) {
+       if (alias && !ce_stage(alias) && !ie_match_stat(istate, alias, st, ce_option)) {
                /* Nothing changed, really */
                free(ce);
                ce_mark_uptodate(alias);
+               alias->ce_flags |= CE_ADDED;
                return 0;
        }
-
-       if (index_path(ce->sha1, path, &st, 1))
-               die("unable to index file %s", path);
-       if (add_index_entry(istate, ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE))
-               die("unable to add %s to index",path);
-       if (verbose)
+       if (index_path(ce->sha1, path, st, 1))
+               return error("unable to index file %s", path);
+       if (ignore_case && alias && different_name(ce, alias))
+               ce = create_alias_ce(ce, alias);
+       ce->ce_flags |= CE_ADDED;
+
+       /* It was suspected to be recily clean, but it turns out to be Ok */
+       was_same = (alias &&
+                   !ce_stage(alias) &&
+                   !hashcmp(alias->sha1, ce->sha1) &&
+                   ce->ce_mode == alias->ce_mode);
+
+       if (pretend)
+               ;
+       else if (add_index_entry(istate, ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE))
+               return error("unable to add %s to index",path);
+       if (verbose && !was_same)
                printf("add '%s'\n", path);
        return 0;
 }
 
+int add_file_to_index(struct index_state *istate, const char *path, int flags)
+{
+       struct stat st;
+       if (lstat(path, &st))
+               die("%s: unable to stat (%s)", path, strerror(errno));
+       return add_to_index(istate, path, &st, flags);
+}
+
 struct cache_entry *make_cache_entry(unsigned int mode,
                const unsigned char *sha1, const char *path, int stage,
                int refresh)
@@ -841,6 +893,15 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,
        if (ce_uptodate(ce))
                return ce;
 
+       /*
+        * CE_VALID means the user promised us that the change to
+        * the work tree does not matter and told us not to worry.
+        */
+       if (!ignore_valid && (ce->ce_flags & CE_VALID)) {
+               ce_mark_uptodate(ce);
+               return ce;
+       }
+
        if (lstat(ce->name, &st) < 0) {
                if (err)
                        *err = errno;
@@ -901,6 +962,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
        int allow_unmerged = (flags & REFRESH_UNMERGED) != 0;
        int quiet = (flags & REFRESH_QUIET) != 0;
        int not_new = (flags & REFRESH_IGNORE_MISSING) != 0;
+       int ignore_submodules = (flags & REFRESH_IGNORE_SUBMODULES) != 0;
        unsigned int options = really ? CE_MATCH_IGNORE_VALID : 0;
 
        for (i = 0; i < istate->cache_nr; i++) {
@@ -908,6 +970,9 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
                int cache_errno = 0;
 
                ce = istate->cache[i];
+               if (ignore_submodules && S_ISGITLINK(ce->ce_mode))
+                       continue;
+
                if (ce_stage(ce)) {
                        while ((i < istate->cache_nr) &&
                               ! strcmp(istate->cache[i]->name, ce->name))
@@ -1309,7 +1374,7 @@ int write_index(const struct index_state *istate, int newfd)
                struct cache_entry *ce = cache[i];
                if (ce->ce_flags & CE_REMOVE)
                        continue;
-               if (is_racy_timestamp(istate, ce))
+               if (!ce_uptodate(ce) && is_racy_timestamp(istate, ce))
                        ce_smudge_racily_clean_entry(ce);
                if (ce_write_entry(&c, newfd, ce) < 0)
                        return -1;