diff options
Diffstat (limited to 'subversion/libsvn_client')
-rw-r--r-- | subversion/libsvn_client/externals.c | 36 | ||||
-rw-r--r-- | subversion/libsvn_client/merge.c | 42 | ||||
-rw-r--r-- | subversion/libsvn_client/patch.c | 33 |
3 files changed, 85 insertions, 26 deletions
diff --git a/subversion/libsvn_client/externals.c b/subversion/libsvn_client/externals.c index e50371543954..851b260dec4c 100644 --- a/subversion/libsvn_client/externals.c +++ b/subversion/libsvn_client/externals.c @@ -231,6 +231,42 @@ switch_dir_external(const char *local_abspath, if (node_url) { + svn_boolean_t is_wcroot; + + SVN_ERR(svn_wc__is_wcroot(&is_wcroot, ctx->wc_ctx, local_abspath, + pool)); + + if (! is_wcroot) + { + /* This can't be a directory external! */ + + err = svn_wc__external_remove(ctx->wc_ctx, defining_abspath, + local_abspath, + TRUE /* declaration_only */, + ctx->cancel_func, ctx->cancel_baton, + pool); + + if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND) + { + /* New external... No problem that we can't remove it */ + svn_error_clear(err); + err = NULL; + } + else if (err) + return svn_error_trace(err); + + return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL, + _("The external '%s' defined in %s at '%s' " + "cannot be checked out because '%s' is " + "already a versioned path."), + url_from_externals_definition, + SVN_PROP_EXTERNALS, + svn_dirent_local_style(defining_abspath, + pool), + svn_dirent_local_style(local_abspath, + pool)); + } + /* If we have what appears to be a version controlled subdir, and its top-level URL matches that of our externals definition, perform an update. */ diff --git a/subversion/libsvn_client/merge.c b/subversion/libsvn_client/merge.c index e912682e3651..e2435754ea0b 100644 --- a/subversion/libsvn_client/merge.c +++ b/subversion/libsvn_client/merge.c @@ -2349,17 +2349,47 @@ files_same_p(svn_boolean_t *same, { svn_stream_t *mine_stream; svn_stream_t *older_stream; - svn_opt_revision_t working_rev = { svn_opt_revision_working, { 0 } }; + svn_string_t *special = svn_hash_gets(working_props, SVN_PROP_SPECIAL); + svn_string_t *eol_style = svn_hash_gets(working_props, SVN_PROP_EOL_STYLE); + svn_string_t *keywords = svn_hash_gets(working_props, SVN_PROP_KEYWORDS); /* Compare the file content, translating 'mine' to 'normal' form. */ - if (svn_prop_get_value(working_props, SVN_PROP_SPECIAL) != NULL) + if (special != NULL) SVN_ERR(svn_subst_read_specialfile(&mine_stream, mine_abspath, scratch_pool, scratch_pool)); else - SVN_ERR(svn_client__get_normalized_stream(&mine_stream, wc_ctx, - mine_abspath, &working_rev, - FALSE, TRUE, NULL, NULL, - scratch_pool, scratch_pool)); + SVN_ERR(svn_stream_open_readonly(&mine_stream, mine_abspath, + scratch_pool, scratch_pool)); + + if (!special && (eol_style || keywords)) + { + apr_hash_t *kw = NULL; + const char *eol = NULL; + svn_subst_eol_style_t style; + + /* We used to use svn_client__get_normalized_stream() here, but + that doesn't work in 100% of the cases because it doesn't + convert EOLs to the repository form; just to '\n'. + */ + + if (eol_style) + { + svn_subst_eol_style_from_value(&style, &eol, eol_style->data); + + if (style == svn_subst_eol_style_native) + eol = SVN_SUBST_NATIVE_EOL_STR; + else if (style != svn_subst_eol_style_fixed + && style != svn_subst_eol_style_none) + return svn_error_create(SVN_ERR_IO_UNKNOWN_EOL, NULL, NULL); + } + + if (keywords) + SVN_ERR(svn_subst_build_keywords3(&kw, keywords->data, "", "", + "", 0, "", scratch_pool)); + + mine_stream = svn_subst_stream_translated( + mine_stream, eol, FALSE, kw, FALSE, scratch_pool); + } SVN_ERR(svn_stream_open_readonly(&older_stream, older_abspath, scratch_pool, scratch_pool)); diff --git a/subversion/libsvn_client/patch.c b/subversion/libsvn_client/patch.c index d70e83ccaf48..6d8d0a4632c8 100644 --- a/subversion/libsvn_client/patch.c +++ b/subversion/libsvn_client/patch.c @@ -209,9 +209,6 @@ typedef struct patch_target_t { /* True if the target had to be skipped for some reason. */ svn_boolean_t skipped; - /* True if the target has been filtered by the patch callback. */ - svn_boolean_t filtered; - /* True if at least one hunk was rejected. */ svn_boolean_t had_rejects; @@ -489,6 +486,8 @@ resolve_target_path(patch_target_t *target, SVN_ERR(svn_wc__node_was_moved_away(&moved_to_abspath, NULL, wc_ctx, target->local_abspath, result_pool, scratch_pool)); + /* ### BUG: moved_to_abspath contains the target where the op-root was + ### moved to... not the target itself! */ if (moved_to_abspath) { target->local_abspath = moved_to_abspath; @@ -2264,8 +2263,6 @@ apply_one_patch(patch_target_t **patch_target, svn_patch_t *patch, int strip_count, svn_boolean_t ignore_whitespace, svn_boolean_t remove_tempfiles, - svn_client_patch_func_t patch_func, - void *patch_baton, svn_cancel_func_t cancel_func, void *cancel_baton, apr_pool_t *result_pool, apr_pool_t *scratch_pool) @@ -2285,19 +2282,6 @@ apply_one_patch(patch_target_t **patch_target, svn_patch_t *patch, return SVN_NO_ERROR; } - if (patch_func) - { - SVN_ERR(patch_func(patch_baton, &target->filtered, - target->canon_path_from_patchfile, - target->patched_path, target->reject_path, - scratch_pool)); - if (target->filtered) - { - *patch_target = target; - return SVN_NO_ERROR; - } - } - iterpool = svn_pool_create(scratch_pool); /* Match hunks. */ for (i = 0; i < patch->hunks->nelts; i++) @@ -3164,14 +3148,23 @@ apply_patches(/* The path to the patch file. */ if (patch) { patch_target_t *target; + svn_boolean_t filtered = FALSE; SVN_ERR(apply_one_patch(&target, patch, abs_wc_path, ctx->wc_ctx, strip_count, ignore_whitespace, remove_tempfiles, - patch_func, patch_baton, ctx->cancel_func, ctx->cancel_baton, iterpool, iterpool)); - if (! target->filtered) + + if (!target->skipped && patch_func) + { + SVN_ERR(patch_func(patch_baton, &filtered, + target->canon_path_from_patchfile, + target->patched_path, target->reject_path, + iterpool)); + } + + if (! filtered) { /* Save info we'll still need when we're done patching. */ patch_target_info_t *target_info = |