diff options
author | svnmir <svnmir@FreeBSD.org> | 2015-08-09 04:37:48 +0000 |
---|---|---|
committer | svnmir <svnmir@FreeBSD.org> | 2015-08-09 04:37:48 +0000 |
commit | 91308aec6ca93cab82659cd43b3f6a83d366350b (patch) | |
tree | 78a13bd0acf7405df6eb6ca94a4e354d124065a6 /subversion/libsvn_client/patch.c | |
parent | 0d1e05fe9c6027aaf742eb9b8b05f4dbefb92e2e (diff) | |
download | FreeBSD-src-91308aec6ca93cab82659cd43b3f6a83d366350b.zip FreeBSD-src-91308aec6ca93cab82659cd43b3f6a83d366350b.tar.gz |
Vendor import subversion-1.8.14
Diffstat (limited to 'subversion/libsvn_client/patch.c')
-rw-r--r-- | subversion/libsvn_client/patch.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/subversion/libsvn_client/patch.c b/subversion/libsvn_client/patch.c index b965646..b7fbf06 100644 --- a/subversion/libsvn_client/patch.c +++ b/subversion/libsvn_client/patch.c @@ -2057,6 +2057,56 @@ send_patch_notification(const patch_target_t *target, return SVN_NO_ERROR; } +static void +svn_sort__array(apr_array_header_t *array, + int (*comparison_func)(const void *, + const void *)) +{ + qsort(array->elts, array->nelts, array->elt_size, comparison_func); +} + +/* Implements the callback for svn_sort__array. Puts hunks that match + before hunks that do not match, puts hunks that match in order + based on postion matched, puts hunks that do not match in order + based on original position. */ +static int +sort_matched_hunks(const void *a, const void *b) +{ + const hunk_info_t *item1 = *((const hunk_info_t * const *)a); + const hunk_info_t *item2 = *((const hunk_info_t * const *)b); + svn_boolean_t matched1 = !item1->rejected && !item1->already_applied; + svn_boolean_t matched2 = !item2->rejected && !item2->already_applied; + svn_linenum_t original1, original2; + + if (matched1 && matched2) + { + /* Both match so use order matched in file. */ + if (item1->matched_line > item2->matched_line) + return 1; + else if (item1->matched_line == item2->matched_line) + return 0; + else + return -1; + } + else if (matched2) + /* Only second matches, put it before first. */ + return 1; + else if (matched1) + /* Only first matches, put it before second. */ + return -1; + + /* Neither matches, sort by original_start. */ + original1 = svn_diff_hunk_get_original_start(item1->hunk); + original2 = svn_diff_hunk_get_original_start(item2->hunk); + if (original1 > original2) + return 1; + else if (original1 == original2) + return 0; + else + return -1; +} + + /* Apply a PATCH to a working copy at ABS_WC_PATH and put the result * into temporary files, to be installed in the working copy later. * Return information about the patch target in *PATCH_TARGET, allocated @@ -2138,6 +2188,10 @@ apply_one_patch(patch_target_t **patch_target, svn_patch_t *patch, APR_ARRAY_PUSH(target->content->hunks, hunk_info_t *) = hi; } + /* Hunks are applied in the order determined by the matched line and + this may be different from the order of the original lines. */ + svn_sort__array(target->content->hunks, sort_matched_hunks); + /* Apply or reject hunks. */ for (i = 0; i < target->content->hunks->nelts; i++) { |