diff options
author | Vincent Ambo <tazjin@google.com> | 2020-05-22T16·46+0100 |
---|---|---|
committer | Vincent Ambo <tazjin@google.com> | 2020-05-22T16·46+0100 |
commit | 5229c9b232de5bfa959ad6ebbb4c8192ac513352 (patch) | |
tree | 8539e7e23682cac110900f946f034ae44162cacd /third_party/git/apply.c | |
parent | f2b211131f2347342dde63975b09cf603149f1a3 (diff) | |
parent | 8518a7a51faaf50f830646d4c3585f51236b9349 (diff) |
merge(3p/git): Merge git upstream at v2.26.2 r/808
Diffstat (limited to 'third_party/git/apply.c')
-rw-r--r-- | third_party/git/apply.c | 78 |
1 files changed, 51 insertions, 27 deletions
diff --git a/third_party/git/apply.c b/third_party/git/apply.c index cde95369bb3f..bdc008fae2ad 100644 --- a/third_party/git/apply.c +++ b/third_party/git/apply.c @@ -32,7 +32,7 @@ static void git_apply_config(void) { git_config_get_string_const("apply.whitespace", &apply_default_whitespace); git_config_get_string_const("apply.ignorewhitespace", &apply_default_ignorewhitespace); - git_config(git_default_config, NULL); + git_config(git_xmerge_config, NULL); } static int parse_whitespace_option(struct apply_state *state, const char *option) @@ -450,7 +450,7 @@ static char *find_name_gnu(struct strbuf *root, /* * Proposed "new-style" GNU patch/diff format; see - * https://public-inbox.org/git/7vll0wvb2a.fsf@assigned-by-dhcp.cox.net/ + * https://lore.kernel.org/git/7vll0wvb2a.fsf@assigned-by-dhcp.cox.net/ */ if (unquote_c_style(&name, line, NULL)) { strbuf_release(&name); @@ -1361,11 +1361,32 @@ int parse_git_diff_header(struct strbuf *root, if (check_header_line(*linenr, patch)) return -1; if (res > 0) - return offset; + goto done; break; } } +done: + if (!patch->old_name && !patch->new_name) { + if (!patch->def_name) { + error(Q_("git diff header lacks filename information when removing " + "%d leading pathname component (line %d)", + "git diff header lacks filename information when removing " + "%d leading pathname components (line %d)", + parse_hdr_state.p_value), + parse_hdr_state.p_value, *linenr); + return -128; + } + patch->old_name = xstrdup(patch->def_name); + patch->new_name = xstrdup(patch->def_name); + } + if ((!patch->new_name && !patch->is_delete) || + (!patch->old_name && !patch->is_new)) { + error(_("git diff header lacks filename information " + "(line %d)"), *linenr); + return -128; + } + patch->is_toplevel_relative = 1; return offset; } @@ -1546,26 +1567,6 @@ static int find_header(struct apply_state *state, return -128; if (git_hdr_len <= len) continue; - if (!patch->old_name && !patch->new_name) { - if (!patch->def_name) { - error(Q_("git diff header lacks filename information when removing " - "%d leading pathname component (line %d)", - "git diff header lacks filename information when removing " - "%d leading pathname components (line %d)", - state->p_value), - state->p_value, state->linenr); - return -128; - } - patch->old_name = xstrdup(patch->def_name); - patch->new_name = xstrdup(patch->def_name); - } - if ((!patch->new_name && !patch->is_delete) || - (!patch->old_name && !patch->is_new)) { - error(_("git diff header lacks filename information " - "(line %d)"), state->linenr); - return -128; - } - patch->is_toplevel_relative = 1; *hdrsize = git_hdr_len; return offset; } @@ -2661,6 +2662,16 @@ static int find_pos(struct apply_state *state, int backwards_lno, forwards_lno, current_lno; /* + * When running with --allow-overlap, it is possible that a hunk is + * seen that pretends to start at the beginning (but no longer does), + * and that *still* needs to match the end. So trust `match_end` more + * than `match_beginning`. + */ + if (state->allow_overlap && match_beginning && match_end && + img->nr - preimage->nr != 0) + match_beginning = 0; + + /* * If match_beginning or match_end is specified, there is no * point starting from a wrong line that will never match and * wander around and wait for a match at the specified end. @@ -3146,7 +3157,8 @@ static int apply_binary(struct apply_state *state, * See if the old one matches what the patch * applies to. */ - hash_object_file(img->buf, img->len, blob_type, &oid); + hash_object_file(the_hash_algo, img->buf, img->len, blob_type, + &oid); if (strcmp(oid_to_hex(&oid), patch->old_oid_prefix)) return error(_("the patch applies to '%s' (%s), " "which does not match the " @@ -3191,7 +3203,8 @@ static int apply_binary(struct apply_state *state, name); /* verify that the result matches */ - hash_object_file(img->buf, img->len, blob_type, &oid); + hash_object_file(the_hash_algo, img->buf, img->len, blob_type, + &oid); if (strcmp(oid_to_hex(&oid), patch->new_oid_prefix)) return error(_("binary patch to '%s' creates incorrect result (expecting %s, got %s)"), name, patch->new_oid_prefix, oid_to_hex(&oid)); @@ -4182,8 +4195,8 @@ static void show_rename_copy(struct patch *p) old_name = slash_old + 1; new_name = slash_new + 1; } - /* p->old_name thru old_name is the common prefix, and old_name and new_name - * through the end of names are renames + /* p->old_name through old_name is the common prefix, and old_name and + * new_name through the end of names are renames */ if (old_name != p->old_name) printf(" %s %.*s{%s => %s} (%d%%)\n", renamecopy, @@ -4643,6 +4656,7 @@ static int apply_patch(struct apply_state *state, struct patch *list = NULL, **listp = &list; int skipped_patch = 0; int res = 0; + int flush_attributes = 0; state->patch_input_file = filename; if (read_patch_file(&buf, fd) < 0) @@ -4670,6 +4684,14 @@ static int apply_patch(struct apply_state *state, patch_stats(state, patch); *listp = patch; listp = &patch->next; + + if ((patch->new_name && + ends_with_path_components(patch->new_name, + GITATTRIBUTES_FILE)) || + (patch->old_name && + ends_with_path_components(patch->old_name, + GITATTRIBUTES_FILE))) + flush_attributes = 1; } else { if (state->apply_verbosity > verbosity_normal) @@ -4746,6 +4768,8 @@ static int apply_patch(struct apply_state *state, if (state->summary && state->apply_verbosity > verbosity_silent) summary_patch_list(list); + if (flush_attributes) + reset_parsed_attributes(); end: free_patch_list(list); strbuf_release(&buf); |