Merge branch 'maint'
[gitweb.git] / builtin-apply.c
index 2dde34186a53cba3066a363525bff7998d268266..f94d0dbf488ff43ccc496939560c81daf05772cf 100644 (file)
@@ -30,7 +30,7 @@ static int unidiff_zero;
 static int p_value = 1;
 static int p_value_known;
 static int check_index;
-static int write_index;
+static int update_index;
 static int cached;
 static int diffstat;
 static int numstat;
@@ -417,7 +417,7 @@ static int gitdiff_hdrend(const char *line, struct patch *patch)
 static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name, const char *oldnew)
 {
        if (!orig_name && !isnull)
-               return find_name(line, NULL, 1, TERM_TAB);
+               return find_name(line, NULL, p_value, TERM_TAB);
 
        if (orig_name) {
                int len;
@@ -427,7 +427,7 @@ static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name,
                len = strlen(name);
                if (isnull)
                        die("git-apply: bad git-diff - expected /dev/null, got %s on line %d", name, linenr);
-               another = find_name(line, NULL, 1, TERM_TAB);
+               another = find_name(line, NULL, p_value, TERM_TAB);
                if (!another || memcmp(another, name, len))
                        die("git-apply: bad git-diff - inconsistent %s filename on line %d", oldnew, linenr);
                free(another);
@@ -1475,8 +1475,8 @@ static int read_old_data(struct stat *st, const char *path, char **buf_p, unsign
                }
                close(fd);
                nsize = got;
-               nbuf = buf;
-               if (convert_to_git(path, &nbuf, &nsize)) {
+               nbuf = convert_to_git(path, buf, &nsize);
+               if (nbuf) {
                        free(buf);
                        *buf_p = nbuf;
                        *alloc_p = nsize;
@@ -1607,7 +1607,8 @@ static int apply_line(char *output, const char *patch, int plen)
        int need_fix_leading_space = 0;
        char *buf;
 
-       if ((new_whitespace != strip_whitespace) || !whitespace_error) {
+       if ((new_whitespace != strip_whitespace) || !whitespace_error ||
+           *patch != '+') {
                memcpy(output, patch + 1, plen);
                return plen;
        }
@@ -1911,11 +1912,11 @@ static int apply_binary(struct buffer_desc *desc, struct patch *patch)
 
        if (has_sha1_file(sha1)) {
                /* We already have the postimage */
-               char type[10];
+               enum object_type type;
                unsigned long size;
 
                free(desc->buffer);
-               desc->buffer = read_sha1_file(sha1, type, &size);
+               desc->buffer = read_sha1_file(sha1, &type, &size);
                if (!desc->buffer)
                        return error("the necessary postimage %s for "
                                     "'%s' cannot be read",
@@ -1971,8 +1972,8 @@ static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *
        buf = NULL;
        if (cached) {
                if (ce) {
-                       char type[20];
-                       buf = read_sha1_file(ce->sha1, type, &size);
+                       enum object_type type;
+                       buf = read_sha1_file(ce->sha1, &type, &size);
                        if (!buf)
                                return error("read of %s failed",
                                             patch->old_name);
@@ -1980,7 +1981,7 @@ static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *
                }
        }
        else if (patch->old_name) {
-               size = st->st_size;
+               size = xsize_t(st->st_size);
                alloc = size + 8192;
                buf = xmalloc(alloc);
                if (read_old_data(st, patch->old_name, &buf, &alloc, &size))
@@ -2307,7 +2308,7 @@ static void patch_stats(struct patch *patch)
 
 static void remove_file(struct patch *patch, int rmdir_empty)
 {
-       if (write_index) {
+       if (update_index) {
                if (remove_file_from_cache(patch->old_name) < 0)
                        die("unable to remove %s from index", patch->old_name);
                cache_tree_invalidate_path(active_cache_tree, patch->old_name);
@@ -2334,7 +2335,7 @@ static void add_index_file(const char *path, unsigned mode, void *buf, unsigned
        int namelen = strlen(path);
        unsigned ce_size = cache_entry_size(namelen);
 
-       if (!write_index)
+       if (!update_index)
                return;
 
        ce = xcalloc(1, ce_size);
@@ -2356,24 +2357,21 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,
 {
        int fd;
        char *nbuf;
-       unsigned long nsize;
 
-       if (S_ISLNK(mode))
+       if (has_symlinks && S_ISLNK(mode))
                /* Although buf:size is counted string, it also is NUL
                 * terminated.
                 */
                return symlink(buf, path);
-       nsize = size;
-       nbuf = (char *) buf;
-       if (convert_to_working_tree(path, &nbuf, &nsize)) {
-               free((char *) buf);
-               buf = nbuf;
-               size = nsize;
-       }
 
        fd = open(path, O_CREAT | O_EXCL | O_WRONLY, (mode & 0100) ? 0777 : 0666);
        if (fd < 0)
                return -1;
+
+       nbuf = convert_to_working_tree(path, buf, &size);
+       if (nbuf)
+               buf = nbuf;
+
        while (size) {
                int written = xwrite(fd, buf, size);
                if (written < 0)
@@ -2385,6 +2383,8 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,
        }
        if (close(fd) < 0)
                die("closing file %s: %s", path, strerror(errno));
+       if (nbuf)
+               free(nbuf);
        return 0;
 }
 
@@ -2412,8 +2412,7 @@ static void create_one_file(char *path, unsigned mode, const char *buf, unsigned
                 * used to be.
                 */
                struct stat st;
-               errno = 0;
-               if (!lstat(path, &st) && S_ISDIR(st.st_mode) && !rmdir(path))
+               if (!lstat(path, &st) && (!S_ISDIR(st.st_mode) || !rmdir(path)))
                        errno = EEXIST;
        }
 
@@ -2658,10 +2657,10 @@ static int apply_patch(int fd, const char *filename, int inaccurate_eof)
        if (whitespace_error && (new_whitespace == error_on_whitespace))
                apply = 0;
 
-       write_index = check_index && apply;
-       if (write_index && newfd < 0)
-               newfd = hold_lock_file_for_update(&lock_file,
-                                                 get_index_file(), 1);
+       update_index = check_index && apply;
+       if (update_index && newfd < 0)
+               newfd = hold_locked_index(&lock_file, 1);
+
        if (check_index) {
                if (read_cache() < 0)
                        die("unable to read index file");
@@ -2866,9 +2865,9 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
                                whitespace_error == 1 ? "s" : "");
        }
 
-       if (write_index) {
+       if (update_index) {
                if (write_cache(newfd, active_cache, active_nr) ||
-                   close(newfd) || commit_lock_file(&lock_file))
+                   close(newfd) || commit_locked_index(&lock_file))
                        die("Unable to write new index file");
        }