X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=builtin-apply.c;h=2216a0bf7cd53adc31346f66a3b9786a1d688bad;hb=2c47789d817aaf745a5ce5d5f79619c634cc8566;hp=9fcfe3955dcd1aaca92a812b6253a331290922fa;hpb=951b09ce363f503d7bbd9dfa01b5a3ea2623c3d8;p=git.git diff --git a/builtin-apply.c b/builtin-apply.c index 9fcfe3955..2216a0bf7 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -12,7 +12,7 @@ #include "blob.h" #include "delta.h" #include "builtin.h" -#include "path-list.h" +#include "string-list.h" /* * --check turns on checking that the working tree matches the @@ -46,7 +46,7 @@ static const char *fake_ancestor; static int line_termination = '\n'; static unsigned long p_context = ULONG_MAX; static const char apply_usage[] = -"git-apply [--stat] [--numstat] [--summary] [--check] [--index] [--cached] [--apply] [--no-add] [--index-info] [--allow-binary-replacement] [--reverse] [--reject] [--verbose] [-z] [-pNUM] [-CNUM] [--whitespace=] ..."; +"git apply [--stat] [--numstat] [--summary] [--check] [--index] [--cached] [--apply] [--no-add] [--index-info] [--allow-binary-replacement] [--reverse] [--reject] [--verbose] [-z] [-pNUM] [-CNUM] [--whitespace=] ..."; static enum ws_error_action { nowarn_ws_error, @@ -58,6 +58,8 @@ static int whitespace_error; static int squelch_whitespace_errors = 5; static int applied_after_fixing_ws; static const char *patch_input_file; +static const char *root; +static int root_len; static void parse_whitespace_option(const char *option) { @@ -192,7 +194,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) { @@ -340,6 +342,8 @@ static char *find_name(const char *line, char *def, int p_value, int terminate) */ strbuf_remove(&name, 0, cp - name.buf); free(def); + if (root) + strbuf_insert(&name, 0, root, root_len); return strbuf_detach(&name, NULL); } } @@ -378,6 +382,14 @@ static char *find_name(const char *line, char *def, int p_value, int terminate) free(def); } + if (root) { + char *ret = xmalloc(root_len + len + 1); + strcpy(ret, root); + memcpy(ret + root_len, start, len); + ret[root_len + len] = '\0'; + return ret; + } + return xmemdupz(start, len); } @@ -919,7 +931,7 @@ static void recount_diff(char *line, int size, struct fragment *fragment) newlines++; continue; case '\\': - break; + continue; case '@': ret = size < 3 || prefixcmp(line, "@@ "); break; @@ -2238,12 +2250,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; @@ -2252,7 +2264,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 @@ -2260,7 +2272,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; } @@ -2269,7 +2281,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; } } @@ -2284,7 +2296,8 @@ static int apply_data(struct patch *patch, struct stat *st, struct cache_entry * strbuf_init(&buf, 0); - if ((tpatch = in_fn_table(patch->old_name)) != NULL) { + if (!(patch->is_copy || patch->is_rename) && + ((tpatch = in_fn_table(patch->old_name)) != NULL)) { if (tpatch == (struct patch *) -1) { return error("patch %s has been renamed/deleted", patch->old_name); @@ -2363,7 +2376,7 @@ static int verify_index_match(struct cache_entry *ce, struct stat *st) static int check_preimage(struct patch *patch, struct cache_entry **ce, struct stat *st) { const char *old_name = patch->old_name; - struct patch *tpatch; + struct patch *tpatch = NULL; int stat_ret = 0; unsigned st_mode = 0; @@ -2377,7 +2390,9 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s return 0; assert(patch->is_new <= 0); - if ((tpatch = in_fn_table(old_name)) != NULL) { + + if (!(patch->is_copy || patch->is_rename) && + (tpatch = in_fn_table(old_name)) != NULL) { if (tpatch == (struct patch *) -1) { return error("%s: has been deleted/renamed", old_name); } @@ -2387,6 +2402,7 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s if (stat_ret && errno != ENOENT) return error("%s: %s", old_name, strerror(errno)); } + if (check_index && !tpatch) { int pos = cache_name_pos(old_name, strlen(old_name)); if (pos < 0) { @@ -3035,7 +3051,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); @@ -3240,6 +3256,18 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix) options |= RECOUNT; continue; } + if (!prefixcmp(arg, "--directory=")) { + arg += strlen("--directory="); + root_len = strlen(arg); + if (root_len && arg[root_len - 1] != '/') { + char *new_root; + root = new_root = xmalloc(root_len + 2); + strcpy(new_root, arg); + strcpy(new_root + root_len++, "/"); + } else + root = arg; + continue; + } if (0 < prefix_length) arg = prefix_filename(prefix, prefix_length, arg);