Merge branch 'jk/add-i-diff-compact-heuristics'
[gitweb.git] / read-cache.c
index 89dbc0837a4155f9e70b56c7d61c8742482f3659..db2776605529bd43f77ca48e84b9e2ded95b493e 100644 (file)
@@ -5,6 +5,7 @@
  */
 #define NO_THE_INDEX_COMPATIBILITY_MACROS
 #include "cache.h"
+#include "tempfile.h"
 #include "lockfile.h"
 #include "cache-tree.h"
 #include "refs.h"
@@ -16,7 +17,6 @@
 #include "strbuf.h"
 #include "varint.h"
 #include "split-index.h"
-#include "sigchain.h"
 #include "utf8.h"
 
 static struct cache_entry *refresh_cache_entry(struct cache_entry *ce,
@@ -327,7 +327,7 @@ int ie_match_stat(const struct index_state *istate,
         * by definition never matches what is in the work tree until it
         * actually gets added.
         */
-       if (ce->ce_flags & CE_INTENT_TO_ADD)
+       if (ce_intent_to_add(ce))
                return DATA_CHANGED | TYPE_CHANGED | MODE_CHANGED;
 
        changed = ce_match_stat_basic(ce, st);
@@ -630,7 +630,7 @@ void set_object_name_for_intent_to_add_entry(struct cache_entry *ce)
        hashcpy(ce->sha1, sha1);
 }
 
-int add_to_index(struct index_state *istate, const char *path, struct stat *st, int flags)
+int add_to_index(struct index_state *istate, const char *path, struct stat *st, int flags, int force_mode)
 {
        int size, namelen, was_same;
        mode_t st_mode = st->st_mode;
@@ -659,7 +659,9 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
        else
                ce->ce_flags |= CE_INTENT_TO_ADD;
 
-       if (trust_executable_bit && has_symlinks)
+       if (S_ISREG(st_mode) && force_mode)
+               ce->ce_mode = create_ce_mode(force_mode);
+       else if (trust_executable_bit && has_symlinks)
                ce->ce_mode = create_ce_mode(st_mode);
        else {
                /* If there is an existing entry, pick the mode bits and type
@@ -678,21 +680,7 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
         * entry's directory case.
         */
        if (ignore_case) {
-               const char *startPtr = ce->name;
-               const char *ptr = startPtr;
-               while (*ptr) {
-                       while (*ptr && *ptr != '/')
-                               ++ptr;
-                       if (*ptr == '/') {
-                               struct cache_entry *foundce;
-                               ++ptr;
-                               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;
-                               }
-                       }
-               }
+               adjust_dirname_case(istate, ce->name);
        }
 
        alias = index_file_exists(istate, ce->name, ce_namelen(ce), ignore_case);
@@ -734,12 +722,13 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
        return 0;
 }
 
-int add_file_to_index(struct index_state *istate, const char *path, int flags)
+int add_file_to_index(struct index_state *istate, const char *path,
+       int flags, int force_mode)
 {
        struct stat st;
        if (lstat(path, &st))
                die_errno("unable to stat '%s'", path);
-       return add_to_index(istate, path, &st, flags);
+       return add_to_index(istate, path, &st, flags, force_mode);
 }
 
 struct cache_entry *make_cache_entry(unsigned int mode,
@@ -1251,7 +1240,7 @@ int refresh_index(struct index_state *istate, unsigned int flags,
 
                        if (cache_errno == ENOENT)
                                fmt = deleted_fmt;
-                       else if (ce->ce_flags & CE_INTENT_TO_ADD)
+                       else if (ce_intent_to_add(ce))
                                fmt = added_fmt; /* must be before other checks */
                        else if (changed & TYPE_CHANGED)
                                fmt = typechange_fmt;
@@ -1533,6 +1522,28 @@ static void check_ce_order(struct index_state *istate)
        }
 }
 
+static void tweak_untracked_cache(struct index_state *istate)
+{
+       switch (git_config_get_untracked_cache()) {
+       case -1: /* keep: do nothing */
+               break;
+       case 0: /* false */
+               remove_untracked_cache(istate);
+               break;
+       case 1: /* true */
+               add_untracked_cache(istate);
+               break;
+       default: /* unknown value: do nothing */
+               break;
+       }
+}
+
+static void post_read_index_from(struct index_state *istate)
+{
+       check_ce_order(istate);
+       tweak_untracked_cache(istate);
+}
+
 /* remember to discard_cache() before reading a different cache! */
 int do_read_index(struct index_state *istate, const char *path, int must_exist)
 {
@@ -1636,9 +1647,10 @@ int read_index_from(struct index_state *istate, const char *path)
                return istate->cache_nr;
 
        ret = do_read_index(istate, path, 0);
+
        split_index = istate->split_index;
        if (!split_index || is_null_sha1(split_index->base_sha1)) {
-               check_ce_order(istate);
+               post_read_index_from(istate);
                return ret;
        }
 
@@ -1653,10 +1665,10 @@ int read_index_from(struct index_state *istate, const char *path)
                die("broken index, expect %s in %s, got %s",
                    sha1_to_hex(split_index->base_sha1),
                    git_path("sharedindex.%s",
-                                    sha1_to_hex(split_index->base_sha1)),
+                            sha1_to_hex(split_index->base_sha1)),
                    sha1_to_hex(split_index->base->sha1));
        merge_base_index(istate);
-       check_ce_order(istate);
+       post_read_index_from(istate);
        return ret;
 }
 
@@ -2113,7 +2125,7 @@ static int commit_locked_index(struct lock_file *lk)
 static int do_write_locked_index(struct index_state *istate, struct lock_file *lock,
                                 unsigned flags)
 {
-       int ret = do_write_index(istate, lock->fd, 0);
+       int ret = do_write_index(istate, get_lock_file_fd(lock), 0);
        if (ret)
                return ret;
        assert((flags & (COMMIT_LOCK | CLOSE_LOCK)) !=
@@ -2137,54 +2149,27 @@ static int write_split_index(struct index_state *istate,
        return ret;
 }
 
-static char *temporary_sharedindex;
-
-static void remove_temporary_sharedindex(void)
-{
-       if (temporary_sharedindex) {
-               unlink_or_warn(temporary_sharedindex);
-               free(temporary_sharedindex);
-               temporary_sharedindex = NULL;
-       }
-}
-
-static void remove_temporary_sharedindex_on_signal(int signo)
-{
-       remove_temporary_sharedindex();
-       sigchain_pop(signo);
-       raise(signo);
-}
+static struct tempfile temporary_sharedindex;
 
 static int write_shared_index(struct index_state *istate,
                              struct lock_file *lock, unsigned flags)
 {
        struct split_index *si = istate->split_index;
-       static int installed_handler;
        int fd, ret;
 
-       temporary_sharedindex = git_pathdup("sharedindex_XXXXXX");
-       fd = mkstemp(temporary_sharedindex);
+       fd = mks_tempfile(&temporary_sharedindex, git_path("sharedindex_XXXXXX"));
        if (fd < 0) {
-               free(temporary_sharedindex);
-               temporary_sharedindex = NULL;
                hashclr(si->base_sha1);
                return do_write_locked_index(istate, lock, flags);
        }
-       if (!installed_handler) {
-               atexit(remove_temporary_sharedindex);
-               sigchain_push_common(remove_temporary_sharedindex_on_signal);
-       }
        move_cache_to_base_index(istate);
        ret = do_write_index(si->base, fd, 1);
-       close(fd);
        if (ret) {
-               remove_temporary_sharedindex();
+               delete_tempfile(&temporary_sharedindex);
                return ret;
        }
-       ret = rename(temporary_sharedindex,
-                    git_path("sharedindex.%s", sha1_to_hex(si->base->sha1)));
-       free(temporary_sharedindex);
-       temporary_sharedindex = NULL;
+       ret = rename_tempfile(&temporary_sharedindex,
+                             git_path("sharedindex.%s", sha1_to_hex(si->base->sha1)));
        if (!ret)
                hashcpy(si->base_sha1, si->base->sha1);
        return ret;