X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=builtin-apply.c;h=e9d49f133afd559d2df3f09997c08a61dfc2ff86;hb=8c178687959732edab8bf91da9ed9f4fbcf7c14e;hp=e15471b5b6d13eaffa6108535c067b5002a2b0c0;hpb=d1f2e1696ce168b3a70b59be7c58fa96c530d4fb;p=git.git diff --git a/builtin-apply.c b/builtin-apply.c index e15471b5b..e9d49f133 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -12,7 +12,8 @@ #include "blob.h" #include "delta.h" #include "builtin.h" -#include "path-list.h" +#include "string-list.h" +#include "dir.h" /* * --check turns on checking that the working tree matches the @@ -194,7 +195,7 @@ struct image { * the case where more than one patches touch the same file. */ -static struct path_list fn_table; +static struct string_list fn_table; static uint32_t hash_line(const char *cp, size_t len) { @@ -274,7 +275,7 @@ static void say_patch_name(FILE *output, const char *pre, static void read_patch_file(struct strbuf *sb, int fd) { if (strbuf_read(sb, fd, 0) < 0) - die("git-apply: read returned %s", strerror(errno)); + die("git apply: read returned %s", strerror(errno)); /* * Make sure that we have some slop in the buffer @@ -506,17 +507,17 @@ static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name, name = orig_name; len = strlen(name); if (isnull) - die("git-apply: bad git-diff - expected /dev/null, got %s on line %d", name, linenr); + die("git apply: bad git-diff - expected /dev/null, got %s on line %d", name, linenr); 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); + die("git apply: bad git-diff - inconsistent %s filename on line %d", oldnew, linenr); free(another); return orig_name; } else { /* expect "/dev/null" */ if (memcmp("/dev/null", line, 9) || line[9] != '\n') - die("git-apply: bad git-diff - expected /dev/null on line %d", linenr); + die("git apply: bad git-diff - expected /dev/null on line %d", linenr); return NULL; } } @@ -809,6 +810,13 @@ static int parse_git_header(char *line, int len, unsigned int size, struct patch * the default name from the header. */ patch->def_name = git_header_name(line, len); + if (patch->def_name && root) { + char *s = xmalloc(root_len + strlen(patch->def_name) + 1); + strcpy(s, root); + strcpy(s + root_len, patch->def_name); + free(patch->def_name); + patch->def_name = s; + } line += len; size -= len; @@ -1696,7 +1704,7 @@ static int match_fragment(struct image *img, fixlen = ws_fix_copy(buf, orig, oldlen, ws_rule, NULL); /* Try fixing the line in the target */ - if (sizeof(tgtfixbuf) < tgtlen) + if (sizeof(tgtfixbuf) > tgtlen) tgtfix = tgtfixbuf; else tgtfix = xmalloc(tgtlen); @@ -1996,6 +2004,8 @@ static int apply_one_fragment(struct image *img, struct fragment *frag, /* * A hunk to change lines at the beginning would begin with * @@ -1,L +N,M @@ + * but we need to be careful. -U0 that inserts before the second + * line also has this pattern. * * And a hunk to add to an empty file would begin with * @@ -0,0 +N,M @@ @@ -2003,7 +2013,8 @@ static int apply_one_fragment(struct image *img, struct fragment *frag, * In other words, a hunk that is (frag->oldpos <= 1) with or * without leading context must match at the beginning. */ - match_beginning = frag->oldpos <= 1; + match_beginning = (!frag->oldpos || + (frag->oldpos == 1 && !unidiff_zero)); /* * A hunk without trailing lines must match at the end. @@ -2250,12 +2261,12 @@ static int read_file_or_gitlink(struct cache_entry *ce, struct strbuf *buf) static struct patch *in_fn_table(const char *name) { - struct path_list_item *item; + struct string_list_item *item; if (name == NULL) return NULL; - item = path_list_lookup(name, &fn_table); + item = string_list_lookup(name, &fn_table); if (item != NULL) return (struct patch *)item->util; @@ -2264,7 +2275,7 @@ static struct patch *in_fn_table(const char *name) static void add_to_fn_table(struct patch *patch) { - struct path_list_item *item; + struct string_list_item *item; /* * Always add new_name unless patch is a deletion @@ -2272,7 +2283,7 @@ static void add_to_fn_table(struct patch *patch) * file creations and copies */ if (patch->new_name != NULL) { - item = path_list_insert(patch->new_name, &fn_table); + item = string_list_insert(patch->new_name, &fn_table); item->util = patch; } @@ -2281,7 +2292,7 @@ static void add_to_fn_table(struct patch *patch) * later chunks shouldn't patch old names */ if ((patch->new_name == NULL) || (patch->is_rename)) { - item = path_list_insert(patch->old_name, &fn_table); + item = string_list_insert(patch->old_name, &fn_table); item->util = (struct patch *) -1; } } @@ -2582,6 +2593,8 @@ static void build_fake_ancestor(struct patch *list, const char *filename) sha1_ptr = sha1; ce = make_cache_entry(patch->old_mode, sha1_ptr, name, 0, 0); + if (!ce) + die("make_cache_entry failed for path '%s'", name); if (add_index_entry(&result, ce, ADD_CACHE_OK_TO_ADD)) die ("Could not add %s to temporary index", name); } @@ -2732,15 +2745,7 @@ static void remove_file(struct patch *patch, int rmdir_empty) warning("unable to remove submodule %s", patch->old_name); } else if (!unlink(patch->old_name) && rmdir_empty) { - char *name = xstrdup(patch->old_name); - char *end = strrchr(name, '/'); - while (end) { - *end = 0; - if (rmdir(name)) - break; - end = strrchr(name, '/'); - } - free(name); + remove_path(patch->old_name); } } } @@ -3051,7 +3056,7 @@ static int apply_patch(int fd, const char *filename, int options) int skipped_patch = 0; /* FIXME - memory leak when using multiple patch files as inputs */ - memset(&fn_table, 0, sizeof(struct path_list)); + memset(&fn_table, 0, sizeof(struct string_list)); strbuf_init(&buf, 0); patch_input_file = filename; read_patch_file(&buf, fd);