summaryrefslogtreecommitdiff
path: root/subversion/libsvn_client
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/libsvn_client')
-rw-r--r--subversion/libsvn_client/externals.c36
-rw-r--r--subversion/libsvn_client/merge.c42
-rw-r--r--subversion/libsvn_client/patch.c33
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 =