git-tar-tree: complete deprecation conversion message
[gitweb.git] / builtin-update-index.c
index 7f9c638466f79fee7d2914b8ec76d713c3670e7e..6ed61ebc57e9591edfe00f2e57926df7b790856b 100644 (file)
@@ -109,16 +109,17 @@ static int add_file_to_cache(const char *path)
        ce->ce_flags = htons(namelen);
        fill_stat_cache_info(ce, &st);
 
-       ce->ce_mode = create_ce_mode(st.st_mode);
-       if (!trust_executable_bit) {
-               /* If there is an existing entry, pick the mode bits
-                * from it, otherwise force to 644.
+       if (trust_executable_bit && has_symlinks)
+               ce->ce_mode = create_ce_mode(st.st_mode);
+       else {
+               /* If there is an existing entry, pick the mode bits and type
+                * from it, otherwise assume unexecutable regular file.
                 */
+               struct cache_entry *ent;
                int pos = cache_name_pos(path, namelen);
-               if (0 <= pos)
-                       ce->ce_mode = active_cache[pos]->ce_mode;
-               else
-                       ce->ce_mode = create_ce_mode(S_IFREG | 0644);
+
+               ent = (0 <= pos) ? active_cache[pos] : NULL;
+               ce->ce_mode = ce_mode_from_stat(ent, st.st_mode);
        }
 
        if (index_path(ce->sha1, path, &st, !info_only))
@@ -226,6 +227,7 @@ static void read_index_info(int line_termination)
                char *path_name;
                unsigned char sha1[20];
                unsigned int mode;
+               unsigned long ul;
                int stage;
 
                /* This reads lines formatted in one of three formats:
@@ -248,9 +250,12 @@ static void read_index_info(int line_termination)
                if (buf.eof)
                        break;
 
-               mode = strtoul(buf.buf, &ptr, 8);
-               if (ptr == buf.buf || *ptr != ' ')
+               errno = 0;
+               ul = strtoul(buf.buf, &ptr, 8);
+               if (ptr == buf.buf || *ptr != ' '
+                   || errno || (unsigned int) ul != ul)
                        goto bad_line;
+               mode = ul;
 
                tab = strchr(ptr, '\t');
                if (!tab || tab - ptr < 41)
@@ -486,6 +491,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
        int prefix_length = prefix ? strlen(prefix) : 0;
        char set_executable_bit = 0;
        unsigned int refresh_flags = 0;
+       int lock_error = 0;
        struct lock_file *lock_file;
 
        git_config(git_default_config);
@@ -493,7 +499,9 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
        /* We can't free this memory, it becomes part of a linked list parsed atexit() */
        lock_file = xcalloc(1, sizeof(struct lock_file));
 
-       newfd = hold_lock_file_for_update(lock_file, get_index_file(), 1);
+       newfd = hold_lock_file_for_update(lock_file, get_index_file(), 0);
+       if (newfd < 0)
+               lock_error = errno;
 
        entries = read_cache();
        if (entries < 0)
@@ -501,6 +509,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
 
        for (i = 1 ; i < argc; i++) {
                const char *path = argv[i];
+               const char *p;
 
                if (allow_options && *path == '-') {
                        if (!strcmp(path, "--")) {
@@ -542,7 +551,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
                                if (i+3 >= argc)
                                        die("git-update-index: --cacheinfo <mode> <sha1> <path>");
 
-                               if ((sscanf(argv[i+1], "%o", &mode) != 1) ||
+                               if ((strtoul_ui(argv[i+1], 8, &mode) != 1) ||
                                    get_sha1_hex(argv[i+2], sha1) ||
                                    add_cacheinfo(mode, sha1, argv[i+3], 0))
                                        die("git-update-index: --cacheinfo"
@@ -616,9 +625,12 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
                                usage(update_index_usage);
                        die("unknown option %s", path);
                }
-               update_one(path, prefix, prefix_length);
+               p = prefix_path(prefix, prefix_length, path);
+               update_one(p, NULL, 0);
                if (set_executable_bit)
-                       chmod_path(set_executable_bit, path);
+                       chmod_path(set_executable_bit, p);
+               if (p < path || p > path + strlen(path))
+                       free((char*)p);
        }
        if (read_from_stdin) {
                struct strbuf buf;
@@ -646,6 +658,12 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
 
  finish:
        if (active_cache_changed) {
+               if (newfd < 0) {
+                       if (refresh_flags & REFRESH_QUIET)
+                               exit(128);
+                       die("unable to create '%s.lock': %s",
+                           get_index_file(), strerror(lock_error));
+               }
                if (write_cache(newfd, active_cache, active_nr) ||
                    close(newfd) || commit_lock_file(lock_file))
                        die("Unable to write new index file");