X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=apply.c;h=34f20326a7f0ad2328b83af969d2c5419c2349eb;hb=ce729ea9bab9d115bdd2343c3ebe361fc6fce2c4;hp=9a131a5ecd97d267e27b41beee34c65e28d5e1c7;hpb=2b1f456adf8f0b574468661a65548106b317459b;p=thirdparty%2Fgit.git diff --git a/apply.c b/apply.c index 9a131a5ecd..34f20326a7 100644 --- a/apply.c +++ b/apply.c @@ -77,7 +77,8 @@ static int parse_whitespace_option(struct apply_state *state, const char *option return 0; } /* - * Please update $__git_whitespacelist in git-completion.bash + * Please update $__git_whitespacelist in git-completion.bash, + * Documentation/git-apply.txt, and Documentation/git-am.txt * when you add new options. */ return error(_("unrecognized whitespace option '%s'"), option); @@ -1291,8 +1292,15 @@ static char *git_header_name(int p_value, return NULL; /* no postimage name */ second = skip_tree_prefix(p_value, name + len + 1, line_len - (len + 1)); + /* + * If we are at the SP at the end of a directory, + * skip_tree_prefix() may return NULL as that makes + * it appears as if we have an absolute path. + * Keep going to find another SP. + */ if (!second) - return NULL; + continue; + /* * Does len bytes starting at "name" and "second" * (that are separated by one HT or SP we just @@ -2219,7 +2227,8 @@ static void reverse_patches(struct patch *p) struct fragment *frag = p->fragments; SWAP(p->new_name, p->old_name); - SWAP(p->new_mode, p->old_mode); + if (p->new_mode) + SWAP(p->new_mode, p->old_mode); SWAP(p->is_new, p->is_delete); SWAP(p->lines_added, p->lines_deleted); SWAP(p->old_oid_prefix, p->new_oid_prefix); @@ -3777,8 +3786,17 @@ static int check_preimage(struct apply_state *state, return error_errno("%s", old_name); } - if (!state->cached && !previous) - st_mode = ce_mode_from_stat(*ce, st->st_mode); + if (!state->cached && !previous) { + if (*ce && !(*ce)->ce_mode) + BUG("ce_mode == 0 for path '%s'", old_name); + + if (trust_executable_bit) + st_mode = ce_mode_from_stat(*ce, st->st_mode); + else if (*ce) + st_mode = (*ce)->ce_mode; + else + st_mode = patch->old_mode; + } if (patch->is_new < 0) patch->is_new = 0; @@ -4430,6 +4448,7 @@ static int create_one_file(struct apply_state *state, const char *buf, unsigned long size) { + char *newpath = NULL; int res; if (state->cached) @@ -4491,24 +4510,26 @@ static int create_one_file(struct apply_state *state, unsigned int nr = getpid(); for (;;) { - char newpath[PATH_MAX]; - mksnpath(newpath, sizeof(newpath), "%s~%u", path, nr); + newpath = mkpathdup("%s~%u", path, nr); res = try_create_file(state, newpath, mode, buf, size); if (res < 0) - return -1; + goto out; if (!res) { if (!rename(newpath, path)) - return 0; + goto out; unlink_or_warn(newpath); break; } if (errno != EEXIST) break; ++nr; + FREE_AND_NULL(newpath); } } - return error_errno(_("unable to write file '%s' mode %o"), - path, mode); + res = error_errno(_("unable to write file '%s' mode %o"), path, mode); +out: + free(newpath); + return res; } static int add_conflicted_stages_file(struct apply_state *state,