You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by cm...@apache.org on 2012/06/27 17:13:42 UTC
svn commit: r1354571 [22/37] - in /subversion/branches/master-passphrase: ./
build/ build/ac-macros/ build/generator/ build/generator/templates/
build/win32/ contrib/client-side/emacs/ contrib/server-side/ notes/
notes/api-errata/1.8/ notes/directory-i...
Modified: subversion/branches/master-passphrase/subversion/libsvn_wc/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_wc/copy.c?rev=1354571&r1=1354570&r2=1354571&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_wc/copy.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_wc/copy.c Wed Jun 27 15:12:37 2012
@@ -35,10 +35,7 @@
#include "wc.h"
#include "workqueue.h"
-#include "adm_files.h"
#include "props.h"
-#include "translate.h"
-#include "entries.h"
#include "svn_private_config.h"
#include "private/svn_wc_private.h"
@@ -53,23 +50,32 @@
SRC_ABSPATH doesn't exist then set *DST_ABSPATH to NULL to indicate
that no copy was made. */
static svn_error_t *
-copy_to_tmpdir(const char **dst_abspath,
+copy_to_tmpdir(svn_skel_t **work_item,
svn_node_kind_t *kind,
+ svn_wc__db_t *db,
const char *src_abspath,
+ const char *dst_abspath,
const char *tmpdir_abspath,
- svn_boolean_t recursive,
+ svn_boolean_t file_copy,
+ svn_boolean_t unversioned,
svn_cancel_func_t cancel_func,
void *cancel_baton,
+ apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
svn_boolean_t is_special;
svn_io_file_del_t delete_when;
+ const char *dst_tmp_abspath;
+ svn_node_kind_t dsk_kind;
+ if (!kind)
+ kind = &dsk_kind;
+
+ *work_item = NULL;
SVN_ERR(svn_io_check_special_path(src_abspath, kind, &is_special,
scratch_pool));
if (*kind == svn_node_none)
{
- *dst_abspath = NULL;
return SVN_NO_ERROR;
}
else if (*kind == svn_node_unknown)
@@ -89,87 +95,68 @@ copy_to_tmpdir(const char **dst_abspath,
### handle the directory case and b) we need to be able to remove
### the cleanup before queueing the move work item. */
- /* Set DST_ABSPATH to a temporary unique path. If *KIND is file, leave a
- file there and then overwrite it; otherwise leave no node on disk at
+ if (file_copy && !unversioned)
+ {
+ svn_boolean_t modified;
+ /* It's faster to look for mods on the source now, as
+ the timestamp might match, than to examine the
+ destination later as the destination timestamp will
+ never match. */
+ SVN_ERR(svn_wc__internal_file_modified_p(&modified,
+ db, src_abspath,
+ FALSE, scratch_pool));
+ if (!modified)
+ {
+ /* Why create a temp copy if we can just reinstall from pristine? */
+ SVN_ERR(svn_wc__wq_build_file_install(work_item,
+ db, dst_abspath, NULL, FALSE,
+ TRUE,
+ result_pool, scratch_pool));
+ return SVN_NO_ERROR;
+ }
+ }
+
+ /* Set DST_TMP_ABSPATH to a temporary unique path. If *KIND is file, leave
+ a file there and then overwrite it; otherwise leave no node on disk at
that path. In the latter case, something else might use that path
before we get around to using it a moment later, but never mind. */
- SVN_ERR(svn_io_open_unique_file3(NULL, dst_abspath, tmpdir_abspath,
+ SVN_ERR(svn_io_open_unique_file3(NULL, &dst_tmp_abspath, tmpdir_abspath,
delete_when, scratch_pool, scratch_pool));
if (*kind == svn_node_dir)
{
- if (recursive)
- SVN_ERR(svn_io_copy_dir_recursively(src_abspath,
- tmpdir_abspath,
- svn_dirent_basename(*dst_abspath,
- scratch_pool),
- TRUE, /* copy_perms */
- cancel_func, cancel_baton,
- scratch_pool));
+ if (file_copy)
+ SVN_ERR(svn_io_copy_dir_recursively(
+ src_abspath,
+ tmpdir_abspath,
+ svn_dirent_basename(dst_tmp_abspath, scratch_pool),
+ TRUE, /* copy_perms */
+ cancel_func, cancel_baton,
+ scratch_pool));
else
- SVN_ERR(svn_io_dir_make(*dst_abspath, APR_OS_DEFAULT, scratch_pool));
+ SVN_ERR(svn_io_dir_make(dst_tmp_abspath, APR_OS_DEFAULT, scratch_pool));
}
else if (!is_special)
- SVN_ERR(svn_io_copy_file(src_abspath, *dst_abspath, TRUE, /* copy_perms */
+ SVN_ERR(svn_io_copy_file(src_abspath, dst_tmp_abspath,
+ TRUE /* copy_perms */,
scratch_pool));
else
- SVN_ERR(svn_io_copy_link(src_abspath, *dst_abspath, scratch_pool));
-
-
- return SVN_NO_ERROR;
-}
-
+ SVN_ERR(svn_io_copy_link(src_abspath, dst_tmp_abspath, scratch_pool));
-/* If SRC_ABSPATH and DST_ABSPATH use different pristine stores, copy the
- pristine text of SRC_ABSPATH (if there is one) into the pristine text
- store connected to DST_ABSPATH. This will only happen when copying into
- a separate WC such as an external directory.
- */
-static svn_error_t *
-copy_pristine_text_if_necessary(svn_wc__db_t *db,
- const char *src_abspath,
- const char *dst_abspath,
- const char *tmpdir_abspath,
- const svn_checksum_t *checksum,
- svn_cancel_func_t cancel_func,
- void *cancel_baton,
- apr_pool_t *scratch_pool)
-{
- svn_boolean_t present;
- svn_stream_t *src_pristine, *tmp_pristine;
- const char *tmp_pristine_abspath;
- const svn_checksum_t *sha1_checksum, *md5_checksum;
-
- SVN_ERR_ASSERT(checksum->kind == svn_checksum_sha1);
-
- /* If it's already in DST_ABSPATH's pristine store, we're done. */
- SVN_ERR(svn_wc__db_pristine_check(&present, db, dst_abspath, checksum,
- scratch_pool));
- if (present)
- return SVN_NO_ERROR;
+ if (file_copy)
+ {
+ /* Remove 'read-only' from the destination file; it's a local add now. */
+ SVN_ERR(svn_io_set_file_read_write(dst_tmp_abspath,
+ FALSE, scratch_pool));
+ }
- sha1_checksum = checksum;
- SVN_ERR(svn_wc__db_pristine_get_md5(&md5_checksum, db,
- src_abspath, checksum,
- scratch_pool, scratch_pool));
-
- SVN_ERR(svn_wc__db_pristine_read(&src_pristine, NULL, db,
- src_abspath, sha1_checksum,
- scratch_pool, scratch_pool));
- SVN_ERR(svn_stream_open_unique(&tmp_pristine, &tmp_pristine_abspath,
- tmpdir_abspath, svn_io_file_del_none,
- scratch_pool, scratch_pool));
- SVN_ERR(svn_stream_copy3(src_pristine, tmp_pristine,
- cancel_func, cancel_baton,
- scratch_pool));
- SVN_ERR(svn_wc__db_pristine_install(db, tmp_pristine_abspath,
- sha1_checksum, md5_checksum,
- scratch_pool));
+ SVN_ERR(svn_wc__wq_build_file_move(work_item, db, dst_abspath,
+ dst_tmp_abspath, dst_abspath,
+ result_pool, scratch_pool));
return SVN_NO_ERROR;
}
-
/* Copy the versioned file SRC_ABSPATH in DB to the path DST_ABSPATH in DB.
If METADATA_ONLY is true, copy only the versioned metadata,
otherwise copy both the versioned metadata and the filesystem node (even
@@ -178,6 +165,9 @@ copy_pristine_text_if_necessary(svn_wc__
If IS_MOVE is true, record move information in working copy meta
data in addition to copying the file.
+ If COPY_PRISTINE_FILE is true, make sure the necessary pristine files are
+ available in the destination working copy.
+
If the versioned file has a text conflict, and the .mine file exists in
the filesystem, copy the .mine file to DST_ABSPATH. Otherwise, copy the
versioned file itself.
@@ -190,7 +180,7 @@ copy_versioned_file(svn_wc__db_t *db,
const char *dst_abspath,
const char *dst_op_root_abspath,
const char *tmpdir_abspath,
- const svn_checksum_t *checksum,
+ svn_boolean_t copy_pristine_file,
svn_boolean_t metadata_only,
svn_boolean_t conflicted,
svn_boolean_t is_move,
@@ -201,26 +191,23 @@ copy_versioned_file(svn_wc__db_t *db,
apr_pool_t *scratch_pool)
{
svn_skel_t *work_items = NULL;
- const char *dir_abspath = svn_dirent_dirname(dst_abspath, scratch_pool);
/* In case we are copying from one WC to another (e.g. an external dir),
ensure the destination WC has a copy of the pristine text. */
- /* Checksum is NULL for local additions */
- if (checksum != NULL)
- SVN_ERR(copy_pristine_text_if_necessary(db, src_abspath, dst_abspath,
- tmpdir_abspath, checksum,
- cancel_func, cancel_baton,
- scratch_pool));
+ if (copy_pristine_file)
+ SVN_ERR(svn_wc__db_pristine_transfer(db, src_abspath, NULL,
+ dst_op_root_abspath,
+ cancel_func, cancel_baton,
+ scratch_pool));
/* Prepare a temp copy of the filesystem node. It is usually a file, but
copy recursively if it's a dir. */
if (!metadata_only)
{
- const char *tmp_dst_abspath;
- svn_node_kind_t disk_kind;
const char *my_src_abspath = NULL;
int i;
+ svn_boolean_t handle_as_unversioned = FALSE;
/* By default, take the copy source as given. */
my_src_abspath = src_abspath;
@@ -257,57 +244,20 @@ copy_versioned_file(svn_wc__db_t *db,
scratch_pool));
if (working_kind == svn_node_file)
- my_src_abspath = conflict_working;
- }
- }
-
- SVN_ERR(copy_to_tmpdir(&tmp_dst_abspath, &disk_kind, my_src_abspath,
- tmpdir_abspath,
- TRUE, /* recursive */
- cancel_func, cancel_baton, scratch_pool));
-
- if (tmp_dst_abspath)
- {
- svn_skel_t *work_item;
-
- /* Remove 'read-only' from the destination file; it's a local add. */
- {
- const svn_string_t *needs_lock;
- SVN_ERR(svn_wc__internal_propget(&needs_lock, db, src_abspath,
- SVN_PROP_NEEDS_LOCK,
- scratch_pool, scratch_pool));
- if (needs_lock)
- SVN_ERR(svn_io_set_file_read_write(tmp_dst_abspath,
- FALSE, scratch_pool));
- }
-
- SVN_ERR(svn_wc__wq_build_file_move(&work_item, db, dir_abspath,
- tmp_dst_abspath, dst_abspath,
- scratch_pool, scratch_pool));
- work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
-
- if (disk_kind == svn_node_file)
- {
- svn_boolean_t modified;
-
- /* It's faster to look for mods on the source now, as
- the timestamp might match, than to examine the
- destination later as the destination timestamp will
- never match. */
- SVN_ERR(svn_wc__internal_file_modified_p(&modified,
- db, src_abspath,
- FALSE, scratch_pool));
- if (!modified)
{
- SVN_ERR(svn_wc__wq_build_record_fileinfo(&work_item,
- db, dst_abspath, 0,
- scratch_pool,
- scratch_pool));
- work_items = svn_wc__wq_merge(work_items, work_item,
- scratch_pool);
+ /* Don't perform unmodified/pristine optimization */
+ handle_as_unversioned = TRUE;
+ my_src_abspath = conflict_working;
}
}
}
+
+ SVN_ERR(copy_to_tmpdir(&work_items, NULL, db, my_src_abspath,
+ dst_abspath, tmpdir_abspath,
+ TRUE /* file_copy */,
+ handle_as_unversioned /* unversioned */,
+ cancel_func, cancel_baton,
+ scratch_pool, scratch_pool));
}
/* Copy the (single) node's metadata, and move the new filesystem node
@@ -315,8 +265,6 @@ copy_versioned_file(svn_wc__db_t *db,
SVN_ERR(svn_wc__db_op_copy(db, src_abspath, dst_abspath,
dst_op_root_abspath, is_move, work_items,
scratch_pool));
- SVN_ERR(svn_wc__wq_run(db, dir_abspath,
- cancel_func, cancel_baton, scratch_pool));
if (notify_func)
{
@@ -324,6 +272,11 @@ copy_versioned_file(svn_wc__db_t *db,
= svn_wc_create_notify(dst_abspath, svn_wc_notify_add,
scratch_pool);
notify->kind = svn_node_file;
+
+ /* When we notify that we performed a copy, make sure we already did */
+ if (work_items != NULL)
+ SVN_ERR(svn_wc__wq_run(db, dst_abspath,
+ cancel_func, cancel_baton, scratch_pool));
(*notify_func)(notify_baton, notify, scratch_pool);
}
return SVN_NO_ERROR;
@@ -334,7 +287,10 @@ copy_versioned_file(svn_wc__db_t *db,
otherwise copy both the versioned metadata and the filesystem nodes (even
if they are the wrong kind, and including unversioned children).
If IS_MOVE is true, record move information in working copy meta
- data in addition to copying the directory. */
+ data in addition to copying the directory.
+
+ WITHIN_ONE_WC is TRUE if the copy/move is within a single working copy (root)
+ */
static svn_error_t *
copy_versioned_dir(svn_wc__db_t *db,
const char *src_abspath,
@@ -343,6 +299,7 @@ copy_versioned_dir(svn_wc__db_t *db,
const char *tmpdir_abspath,
svn_boolean_t metadata_only,
svn_boolean_t is_move,
+ svn_boolean_t within_one_wc,
svn_cancel_func_t cancel_func,
void *cancel_baton,
svn_wc_notify_func2_t notify_func,
@@ -351,29 +308,23 @@ copy_versioned_dir(svn_wc__db_t *db,
{
svn_skel_t *work_items = NULL;
const char *dir_abspath = svn_dirent_dirname(dst_abspath, scratch_pool);
- const apr_array_header_t *versioned_children;
+ apr_hash_t *versioned_children;
+ apr_hash_t *conflicted_children;
apr_hash_t *disk_children;
+ apr_hash_index_t *hi;
svn_node_kind_t disk_kind;
apr_pool_t *iterpool;
- int i;
/* Prepare a temp copy of the single filesystem node (usually a dir). */
if (!metadata_only)
{
- const char *tmp_dst_abspath;
-
- SVN_ERR(copy_to_tmpdir(&tmp_dst_abspath, &disk_kind, src_abspath,
- tmpdir_abspath, FALSE, /* recursive */
- cancel_func, cancel_baton, scratch_pool));
- if (tmp_dst_abspath)
- {
- svn_skel_t *work_item;
-
- SVN_ERR(svn_wc__wq_build_file_move(&work_item, db, dir_abspath,
- tmp_dst_abspath, dst_abspath,
- scratch_pool, scratch_pool));
- work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
- }
+ SVN_ERR(copy_to_tmpdir(&work_items, &disk_kind,
+ db, src_abspath, dst_abspath,
+ tmpdir_abspath,
+ FALSE /* file_copy */,
+ FALSE /* unversioned */,
+ cancel_func, cancel_baton,
+ scratch_pool, scratch_pool));
}
/* Copy the (single) node's metadata, and move the new filesystem node
@@ -381,8 +332,6 @@ copy_versioned_dir(svn_wc__db_t *db,
SVN_ERR(svn_wc__db_op_copy(db, src_abspath, dst_abspath,
dst_op_root_abspath, is_move, work_items,
scratch_pool));
- SVN_ERR(svn_wc__wq_run(db, dir_abspath,
- cancel_func, cancel_baton, scratch_pool));
if (notify_func)
{
@@ -390,6 +339,12 @@ copy_versioned_dir(svn_wc__db_t *db,
= svn_wc_create_notify(dst_abspath, svn_wc_notify_add,
scratch_pool);
notify->kind = svn_node_dir;
+
+ /* When we notify that we performed a copy, make sure we already did */
+ if (work_items != NULL)
+ SVN_ERR(svn_wc__wq_run(db, dir_abspath,
+ cancel_func, cancel_baton, scratch_pool));
+
(*notify_func)(notify_baton, notify, scratch_pool);
}
@@ -403,79 +358,61 @@ copy_versioned_dir(svn_wc__db_t *db,
disk_children = NULL;
/* Copy all the versioned children */
- SVN_ERR(svn_wc__db_read_children(&versioned_children, db, src_abspath,
- scratch_pool, scratch_pool));
iterpool = svn_pool_create(scratch_pool);
- for (i = 0; i < versioned_children->nelts; ++i)
+ SVN_ERR(svn_wc__db_read_children_info(&versioned_children,
+ &conflicted_children,
+ db, src_abspath,
+ scratch_pool, iterpool));
+ for (hi = apr_hash_first(scratch_pool, versioned_children);
+ hi;
+ hi = apr_hash_next(hi))
{
const char *child_name, *child_src_abspath, *child_dst_abspath;
- svn_wc__db_status_t child_status;
- svn_kind_t child_kind;
- svn_boolean_t op_root;
- svn_boolean_t conflicted;
- const svn_checksum_t *checksum;
+ struct svn_wc__db_info_t *info;
svn_pool_clear(iterpool);
+
if (cancel_func)
SVN_ERR(cancel_func(cancel_baton));
- child_name = APR_ARRAY_IDX(versioned_children, i, const char *);
+ child_name = svn__apr_hash_index_key(hi);
+ info = svn__apr_hash_index_val(hi);
child_src_abspath = svn_dirent_join(src_abspath, child_name, iterpool);
child_dst_abspath = svn_dirent_join(dst_abspath, child_name, iterpool);
- SVN_ERR(svn_wc__db_read_info(&child_status, &child_kind, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL,
- &checksum, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, &conflicted,
- &op_root, NULL, NULL, NULL, NULL, NULL,
- db, child_src_abspath,
- iterpool, iterpool));
-
- if (op_root)
+ if (info->op_root)
SVN_ERR(svn_wc__db_op_copy_shadowed_layer(db,
child_src_abspath,
child_dst_abspath,
is_move,
scratch_pool));
- if (child_status == svn_wc__db_status_normal
- || child_status == svn_wc__db_status_added)
+ if (info->status == svn_wc__db_status_normal
+ || info->status == svn_wc__db_status_added)
{
/* We have more work to do than just changing the DB */
- if (child_kind == svn_kind_file)
+ if (info->kind == svn_kind_file)
{
- svn_boolean_t skip = FALSE;
-
/* We should skip this node if this child is a file external
(issues #3589, #4000) */
- if (child_status == svn_wc__db_status_normal)
- {
- SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, &skip,
- db, child_src_abspath,
- scratch_pool,
- scratch_pool));
- }
-
- if (!skip)
+ if (!info->file_external)
SVN_ERR(copy_versioned_file(db,
child_src_abspath,
child_dst_abspath,
dst_op_root_abspath,
- tmpdir_abspath, checksum,
- metadata_only, conflicted,
+ tmpdir_abspath,
+ !within_one_wc && info->has_checksum,
+ metadata_only, info->conflicted,
is_move,
cancel_func, cancel_baton,
NULL, NULL,
iterpool));
}
- else if (child_kind == svn_kind_dir)
+ else if (info->kind == svn_kind_dir)
SVN_ERR(copy_versioned_dir(db,
child_src_abspath, child_dst_abspath,
dst_op_root_abspath, tmpdir_abspath,
- metadata_only, is_move,
+ metadata_only, is_move, within_one_wc,
cancel_func, cancel_baton, NULL, NULL,
iterpool));
else
@@ -484,9 +421,9 @@ copy_versioned_dir(svn_wc__db_t *db,
svn_dirent_local_style(child_src_abspath,
scratch_pool));
}
- else if (child_status == svn_wc__db_status_deleted
- || child_status == svn_wc__db_status_not_present
- || child_status == svn_wc__db_status_excluded)
+ else if (info->status == svn_wc__db_status_deleted
+ || info->status == svn_wc__db_status_not_present
+ || info->status == svn_wc__db_status_excluded)
{
/* This will be copied as some kind of deletion. Don't touch
any actual files */
@@ -497,7 +434,7 @@ copy_versioned_dir(svn_wc__db_t *db,
/* Don't recurse on children while all we do is creating not-present
children */
}
- else if (child_status == svn_wc__db_status_incomplete)
+ else if (info->status == svn_wc__db_status_incomplete)
{
/* Should go ahead and copy incomplete to incomplete? Try to
copy as much as possible, or give up early? */
@@ -508,7 +445,7 @@ copy_versioned_dir(svn_wc__db_t *db,
}
else
{
- SVN_ERR_ASSERT(child_status == svn_wc__db_status_server_excluded);
+ SVN_ERR_ASSERT(info->status == svn_wc__db_status_server_excluded);
return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
_("Cannot copy '%s' excluded by server"),
@@ -517,8 +454,8 @@ copy_versioned_dir(svn_wc__db_t *db,
}
if (disk_children
- && (child_status == svn_wc__db_status_normal
- || child_status == svn_wc__db_status_added))
+ && (info->status == svn_wc__db_status_normal
+ || info->status == svn_wc__db_status_added))
{
/* Remove versioned child as it has been handled */
apr_hash_set(disk_children, child_name, APR_HASH_KEY_STRING, NULL);
@@ -527,21 +464,22 @@ copy_versioned_dir(svn_wc__db_t *db,
/* Copy the remaining filesystem children, which are unversioned, skipping
any conflict-marker files. */
- if (disk_children)
+ if (disk_children && apr_hash_count(disk_children))
{
- apr_hash_index_t *hi;
apr_hash_t *marker_files;
SVN_ERR(svn_wc__db_get_conflict_marker_files(&marker_files, db,
src_abspath, scratch_pool,
scratch_pool));
+ work_items = NULL;
+
for (hi = apr_hash_first(scratch_pool, disk_children); hi;
hi = apr_hash_next(hi))
{
const char *name = svn__apr_hash_index_key(hi);
const char *unver_src_abspath, *unver_dst_abspath;
- const char *tmp_dst_abspath;
+ svn_skel_t *work_item;
if (svn_wc_is_adm_dir(name, iterpool))
continue;
@@ -550,31 +488,23 @@ copy_versioned_dir(svn_wc__db_t *db,
apr_hash_get(marker_files, name, APR_HASH_KEY_STRING))
continue;
- svn_pool_clear(iterpool);
if (cancel_func)
SVN_ERR(cancel_func(cancel_baton));
+ svn_pool_clear(iterpool);
unver_src_abspath = svn_dirent_join(src_abspath, name, iterpool);
unver_dst_abspath = svn_dirent_join(dst_abspath, name, iterpool);
- SVN_ERR(copy_to_tmpdir(&tmp_dst_abspath, &disk_kind,
- unver_src_abspath, tmpdir_abspath,
- TRUE, /* recursive */
- cancel_func, cancel_baton, iterpool));
- if (tmp_dst_abspath)
- {
- svn_skel_t *work_item;
- SVN_ERR(svn_wc__wq_build_file_move(&work_item, db, dir_abspath,
- tmp_dst_abspath,
- unver_dst_abspath,
- iterpool, iterpool));
- SVN_ERR(svn_wc__db_wq_add(db, dst_abspath, work_item,
- iterpool));
- }
+ SVN_ERR(copy_to_tmpdir(&work_item, NULL, db, unver_src_abspath,
+ unver_dst_abspath, tmpdir_abspath,
+ TRUE /* recursive */, TRUE /* unversioned */,
+ cancel_func, cancel_baton,
+ scratch_pool, iterpool));
+ if (work_item)
+ work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
}
- SVN_ERR(svn_wc__wq_run(db, dst_abspath, cancel_func, cancel_baton,
- scratch_pool));
+ SVN_ERR(svn_wc__db_wq_add(db, dst_abspath, work_items, iterpool));
}
svn_pool_destroy(iterpool);
@@ -604,6 +534,10 @@ copy_or_move(svn_wc_context_t *wc_ctx,
svn_boolean_t conflicted;
const svn_checksum_t *checksum;
const char *tmpdir_abspath;
+ const char *src_wcroot_abspath;
+ const char *dst_wcroot_abspath;
+ svn_boolean_t within_one_wc;
+ svn_error_t *err;
SVN_ERR_ASSERT(svn_dirent_is_absolute(src_abspath));
SVN_ERR_ASSERT(svn_dirent_is_absolute(dst_abspath));
@@ -616,7 +550,6 @@ copy_or_move(svn_wc_context_t *wc_ctx,
svn_wc__db_status_t src_status, dstdir_status;
const char *src_repos_root_url, *dst_repos_root_url;
const char *src_repos_uuid, *dst_repos_uuid;
- svn_error_t *err;
err = svn_wc__db_read_info(&src_status, &src_db_kind, NULL, NULL,
&src_repos_root_url, &src_repos_uuid, NULL,
@@ -637,6 +570,10 @@ copy_or_move(svn_wc_context_t *wc_ctx,
else
SVN_ERR(err);
+ /* Do this now, as we know the right data is cached */
+ SVN_ERR(svn_wc__db_get_wcroot(&src_wcroot_abspath, db, src_abspath,
+ scratch_pool, scratch_pool));
+
switch (src_status)
{
case svn_wc__db_status_deleted:
@@ -665,6 +602,10 @@ copy_or_move(svn_wc_context_t *wc_ctx,
db, dstdir_abspath,
scratch_pool, scratch_pool));
+ /* Do this now, as we know the right data is cached */
+ SVN_ERR(svn_wc__db_get_wcroot(&dst_wcroot_abspath, db, dstdir_abspath,
+ scratch_pool, scratch_pool));
+
if (!src_repos_root_url)
{
if (src_status == svn_wc__db_status_added)
@@ -721,7 +662,6 @@ copy_or_move(svn_wc_context_t *wc_ctx,
disk, before actually doing the file copy. */
{
svn_wc__db_status_t dst_status;
- svn_error_t *err;
err = svn_wc__db_read_info(&dst_status, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -777,29 +717,42 @@ copy_or_move(svn_wc_context_t *wc_ctx,
}
SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&tmpdir_abspath, db,
- dst_abspath,
+ dstdir_abspath,
scratch_pool, scratch_pool));
+ within_one_wc = (strcmp(src_wcroot_abspath, dst_wcroot_abspath) == 0);
+
if (src_db_kind == svn_kind_file
|| src_db_kind == svn_kind_symlink)
{
- SVN_ERR(copy_versioned_file(db, src_abspath, dst_abspath, dst_abspath,
- tmpdir_abspath, checksum,
- metadata_only, conflicted, is_move,
- cancel_func, cancel_baton,
- notify_func, notify_baton,
- scratch_pool));
+ err = copy_versioned_file(db, src_abspath, dst_abspath, dst_abspath,
+ tmpdir_abspath,
+ !within_one_wc && (checksum != NULL),
+ metadata_only, conflicted, is_move,
+ cancel_func, cancel_baton,
+ notify_func, notify_baton,
+ scratch_pool);
}
else
{
- SVN_ERR(copy_versioned_dir(db, src_abspath, dst_abspath, dst_abspath,
- tmpdir_abspath,
- metadata_only, is_move,
- cancel_func, cancel_baton,
- notify_func, notify_baton,
- scratch_pool));
+ err = copy_versioned_dir(db, src_abspath, dst_abspath, dst_abspath,
+ tmpdir_abspath,
+ metadata_only, is_move, within_one_wc,
+ cancel_func, cancel_baton,
+ notify_func, notify_baton,
+ scratch_pool);
}
+ if (err && svn_error_find_cause(err, SVN_ERR_CANCELLED))
+ return svn_error_trace(err);
+
+ /* Run the work queue with the remaining work */
+ SVN_ERR(svn_error_compose_create(
+ err,
+ svn_wc__wq_run(db, dst_abspath,
+ cancel_func, cancel_baton,
+ scratch_pool)));
+
return SVN_NO_ERROR;
}
Modified: subversion/branches/master-passphrase/subversion/libsvn_wc/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_wc/deprecated.c?rev=1354571&r1=1354570&r2=1354571&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_wc/deprecated.c Wed Jun 27 15:12:37 2012
@@ -36,6 +36,7 @@
#include "svn_dirent_uri.h"
#include "svn_path.h"
+#include "private/svn_subr_private.h"
#include "private/svn_wc_private.h"
#include "wc.h"
@@ -688,9 +689,8 @@ svn_wc_queue_committed(svn_wc_committed_
const svn_checksum_t *md5_checksum;
if (digest)
- md5_checksum = svn_checksum__from_digest(
- digest, svn_checksum_md5,
- svn_wc__get_committed_queue_pool(*queue));
+ md5_checksum = svn_checksum__from_digest_md5(
+ digest, svn_wc__get_committed_queue_pool(*queue));
else
md5_checksum = NULL;
@@ -748,7 +748,7 @@ svn_wc_process_committed4(const char *pa
new_date = 0;
if (digest)
- md5_checksum = svn_checksum__from_digest(digest, svn_checksum_md5, pool);
+ md5_checksum = svn_checksum__from_digest_md5(digest, pool);
else
md5_checksum = NULL;
@@ -932,7 +932,9 @@ svn_wc_add3(const char *path,
{
svn_kind_t kind;
- SVN_ERR(svn_wc__db_read_kind(&kind, wc_db, local_abspath, FALSE, pool));
+ SVN_ERR(svn_wc__db_read_kind(&kind, wc_db, local_abspath,
+ FALSE /* allow_missing */,
+ FALSE /* show_hidden */, pool));
if (kind == svn_kind_dir)
{
svn_wc_adm_access_t *adm_access;
@@ -4185,6 +4187,49 @@ svn_wc_copy(const char *src_path,
/*** From merge.c ***/
svn_error_t *
+svn_wc_merge4(enum svn_wc_merge_outcome_t *merge_outcome,
+ svn_wc_context_t *wc_ctx,
+ const char *left_abspath,
+ const char *right_abspath,
+ const char *target_abspath,
+ const char *left_label,
+ const char *right_label,
+ const char *target_label,
+ const svn_wc_conflict_version_t *left_version,
+ const svn_wc_conflict_version_t *right_version,
+ svn_boolean_t dry_run,
+ const char *diff3_cmd,
+ const apr_array_header_t *merge_options,
+ const apr_array_header_t *prop_diff,
+ svn_wc_conflict_resolver_func2_t conflict_func,
+ void *conflict_baton,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *scratch_pool)
+{
+ return svn_error_trace(
+ svn_wc_merge5(merge_outcome,
+ NULL /* merge_props_outcome */,
+ wc_ctx,
+ left_abspath,
+ right_abspath,
+ target_abspath,
+ left_label,
+ right_label,
+ target_label,
+ left_version,
+ right_version,
+ dry_run,
+ diff3_cmd,
+ merge_options,
+ NULL /* original_props */,
+ prop_diff,
+ conflict_func, conflict_baton,
+ cancel_func, cancel_baton,
+ scratch_pool));
+}
+
+svn_error_t *
svn_wc_merge3(enum svn_wc_merge_outcome_t *merge_outcome,
const char *left,
const char *right,
@@ -4284,6 +4329,17 @@ svn_wc_merge(const char *left,
/*** From util.c ***/
+svn_wc_conflict_version_t *
+svn_wc_conflict_version_create(const char *repos_url,
+ const char *path_in_repos,
+ svn_revnum_t peg_rev,
+ svn_node_kind_t node_kind,
+ apr_pool_t *pool)
+{
+ return svn_wc_conflict_version_create2(repos_url, NULL, path_in_repos,
+ peg_rev, node_kind, pool);
+}
+
svn_wc_conflict_description_t *
svn_wc_conflict_description_create_text(const char *path,
svn_wc_adm_access_t *adm_access,
Modified: subversion/branches/master-passphrase/subversion/libsvn_wc/diff_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_wc/diff_editor.c?rev=1354571&r1=1354570&r2=1354571&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_wc/diff_editor.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_wc/diff_editor.c Wed Jun 27 15:12:37 2012
@@ -61,6 +61,7 @@
#include "svn_path.h"
#include "svn_hash.h"
+#include "private/svn_subr_private.h"
#include "private/svn_wc_private.h"
#include "wc.h"
@@ -1494,9 +1495,8 @@ window_handler(svn_txdelta_window_t *win
if (!window)
{
- fb->result_checksum = svn_checksum__from_digest(whb->result_digest,
- svn_checksum_md5,
- fb->pool);
+ fb->result_checksum = svn_checksum__from_digest_md5(whb->result_digest,
+ fb->pool);
}
return SVN_NO_ERROR;
Modified: subversion/branches/master-passphrase/subversion/libsvn_wc/diff_local.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_wc/diff_local.c?rev=1354571&r1=1354570&r2=1354571&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_wc/diff_local.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_wc/diff_local.c Wed Jun 27 15:12:37 2012
@@ -564,7 +564,9 @@ svn_wc_diff6(svn_wc_context_t *wc_ctx,
svn_boolean_t get_all;
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
- SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, local_abspath, FALSE,
+ SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, local_abspath,
+ FALSE /* allow_missing */,
+ FALSE /* show_hidden */,
scratch_pool));
if (kind == svn_kind_dir)
Modified: subversion/branches/master-passphrase/subversion/libsvn_wc/entries.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_wc/entries.c?rev=1354571&r1=1354570&r2=1354571&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_wc/entries.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_wc/entries.c Wed Jun 27 15:12:37 2012
@@ -55,7 +55,7 @@
typedef struct db_node_t {
apr_int64_t wc_id;
const char *local_relpath;
- apr_int64_t op_depth;
+ int op_depth;
apr_int64_t repos_id;
const char *repos_relpath;
const char *parent_relpath;
@@ -236,15 +236,6 @@ get_info_for_deleted(svn_wc_entry_t *ent
entry_abspath,
result_pool,
scratch_pool));
-
- if (*repos_relpath == NULL)
- SVN_ERR(svn_wc__db_scan_base_repos(repos_relpath,
- &entry->repos,
- &entry->uuid,
- db,
- entry_abspath,
- result_pool,
- scratch_pool));
}
else
{
@@ -1435,7 +1426,7 @@ insert_node(svn_sqlite__db_t *sdb,
SVN_ERR_ASSERT(node->op_depth > 0 || node->repos_relpath);
SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_NODE));
- SVN_ERR(svn_sqlite__bindf(stmt, "isisnnnnsnrisnnni",
+ SVN_ERR(svn_sqlite__bindf(stmt, "isdsnnnnsnrisnnni",
node->wc_id,
node->local_relpath,
node->op_depth,
@@ -1453,7 +1444,7 @@ insert_node(svn_sqlite__db_t *sdb,
node->repos_id));
SVN_ERR(svn_sqlite__bind_text(stmt, 6,
node->repos_relpath));
- SVN_ERR(svn_sqlite__bind_int64(stmt, 7, node->revision));
+ SVN_ERR(svn_sqlite__bind_revnum(stmt, 7, node->revision));
}
if (node->presence == svn_wc__db_status_normal)
Modified: subversion/branches/master-passphrase/subversion/libsvn_wc/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_wc/externals.c?rev=1354571&r1=1354570&r2=1354571&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_wc/externals.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_wc/externals.c Wed Jun 27 15:12:37 2012
@@ -1134,19 +1134,17 @@ is_external_rolled_out(svn_boolean_t *is
svn_wc__committable_external_info_t *xinfo,
apr_pool_t *scratch_pool)
{
- const char *x_repos_relpath;
- const char *x_repos_root_url;
+ const char *repos_relpath;
+ const char *repos_root_url;
svn_error_t *err;
*is_rolled_out = FALSE;
- err = svn_wc__node_get_origin(NULL, NULL,
- &x_repos_relpath,
- &x_repos_root_url,
- NULL, NULL,
- wc_ctx, xinfo->local_abspath,
- FALSE, /* scan_deleted */
- scratch_pool, scratch_pool);
+ err = svn_wc__db_base_get_info(NULL, NULL, NULL, &repos_relpath,
+ &repos_root_url, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ wc_ctx->db, xinfo->local_abspath,
+ scratch_pool, scratch_pool);
if (err)
{
@@ -1158,8 +1156,8 @@ is_external_rolled_out(svn_boolean_t *is
SVN_ERR(err);
}
- *is_rolled_out = (strcmp(xinfo->repos_root_url, x_repos_root_url) == 0 &&
- strcmp(xinfo->repos_relpath, x_repos_relpath) == 0);
+ *is_rolled_out = (strcmp(xinfo->repos_root_url, repos_root_url) == 0 &&
+ strcmp(xinfo->repos_relpath, repos_relpath) == 0);
return SVN_NO_ERROR;
}
Modified: subversion/branches/master-passphrase/subversion/libsvn_wc/info.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_wc/info.c?rev=1354571&r1=1354570&r2=1354571&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_wc/info.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_wc/info.c Wed Jun 27 15:12:37 2012
@@ -41,8 +41,7 @@ svn_wc_info_dup(const svn_wc_info_t *inf
if (info->changelist)
new_info->changelist = apr_pstrdup(pool, info->changelist);
- if (info->checksum)
- new_info->checksum = svn_checksum_dup(info->checksum, pool);
+ new_info->checksum = svn_checksum_dup(info->checksum, pool);
if (info->conflicts)
{
int i;
Modified: subversion/branches/master-passphrase/subversion/libsvn_wc/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_wc/lock.c?rev=1354571&r1=1354570&r2=1354571&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_wc/lock.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_wc/lock.c Wed Jun 27 15:12:37 2012
@@ -920,7 +920,9 @@ svn_wc_adm_retrieve(svn_wc_adm_access_t
if (associated)
{
err = svn_wc__db_read_kind(&kind, svn_wc__adm_get_db(associated),
- local_abspath, TRUE, pool);
+ local_abspath,
+ TRUE /* allow_missing */,
+ FALSE /* show_hidden */, pool);
if (err)
{
@@ -980,7 +982,9 @@ svn_wc_adm_probe_retrieve(svn_wc_adm_acc
SVN_ERR_ASSERT(associated != NULL);
SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
- SVN_ERR(svn_wc__db_read_kind(&kind, associated->db, local_abspath, TRUE, pool));
+ SVN_ERR(svn_wc__db_read_kind(&kind, associated->db, local_abspath,
+ TRUE /* allow_missing */, FALSE /* show_hidden*/,
+ pool));
if (kind == svn_kind_dir)
dir = path;
@@ -1515,7 +1519,8 @@ svn_wc__acquire_write_lock(const char **
svn_error_t *err;
SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, local_abspath,
- (lock_root_abspath != NULL),
+ (lock_root_abspath != NULL) /* allow_missing*/,
+ FALSE /* show_hidden */,
scratch_pool));
if (!lock_root_abspath && kind != svn_kind_dir)
@@ -1532,7 +1537,9 @@ svn_wc__acquire_write_lock(const char **
SVN_ERR_ASSERT(lock_root_abspath != NULL);
parent_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
- err = svn_wc__db_read_kind(&parent_kind, db, parent_abspath, TRUE,
+ err = svn_wc__db_read_kind(&parent_kind, db, parent_abspath,
+ TRUE /* allow_missing */,
+ FALSE /* show_missing */,
scratch_pool);
if (err && SVN_WC__ERR_IS_NOT_CURRENT_WC(err))
{
@@ -1565,7 +1572,9 @@ svn_wc__acquire_write_lock(const char **
/* Can't lock parents that don't exist */
if (kind == svn_kind_unknown)
{
- SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, FALSE,
+ SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath,
+ FALSE /* allow_missing */,
+ FALSE /* show_hidden */,
scratch_pool));
if (kind != svn_kind_dir)
Modified: subversion/branches/master-passphrase/subversion/libsvn_wc/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_wc/merge.c?rev=1354571&r1=1354570&r2=1354571&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_wc/merge.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_wc/merge.c Wed Jun 27 15:12:37 2012
@@ -926,9 +926,12 @@ maybe_resolve_conflicts(svn_skel_t **wor
/* Attempt a trivial merge of LEFT_ABSPATH and RIGHT_ABSPATH to TARGET_ABSPATH.
- * The merge is trivial if the file at LEFT_ABSPATH equals TARGET_ABSPATH,
- * because in this case the content of RIGHT_ABSPATH can be copied to the
- * target. On success, set *MERGE_OUTCOME to SVN_WC_MERGE_MERGED in case the
+ * The merge is trivial if the file at LEFT_ABSPATH equals the detranslated
+ * form of the target at DETRANSLATED_TARGET_ABSPATH, because in this case
+ * the content of RIGHT_ABSPATH can be copied to the target.
+ * Another trivial case is if DETRANSLATED_TARGET_ABSPATH is identical to
+ * RIGHT_ABSPATH - we can just accept the existing content as merge result.
+ * On success, set *MERGE_OUTCOME to SVN_WC_MERGE_MERGED in case the
* target was changed, or to SVN_WC_MERGE_UNCHANGED if the target was not
* changed. Install work queue items allocated in RESULT_POOL in *WORK_ITEMS.
* On failure, set *MERGE_OUTCOME to SVN_WC_MERGE_NO_MERGE. */
@@ -938,6 +941,7 @@ merge_file_trivial(svn_skel_t **work_ite
const char *left_abspath,
const char *right_abspath,
const char *target_abspath,
+ const char *detranslated_target_abspath,
svn_boolean_t dry_run,
svn_wc__db_t *db,
apr_pool_t *result_pool,
@@ -960,7 +964,8 @@ merge_file_trivial(svn_skel_t **work_ite
/* If the LEFT side of the merge is equal to WORKING, then we can
* copy RIGHT directly. */
SVN_ERR(svn_io_files_contents_same_p(&same_contents, left_abspath,
- target_abspath, scratch_pool));
+ detranslated_target_abspath,
+ scratch_pool));
if (same_contents)
{
/* Check whether the left side equals the right side.
@@ -989,6 +994,23 @@ merge_file_trivial(svn_skel_t **work_ite
return SVN_NO_ERROR;
}
+ else
+ {
+ /* Check whether the existing version equals the right side. If it
+ * does, the locally existing, changed file equals the incoming
+ * file, so there is no conflict. For binary files, we historically
+ * conflicted them needlessly, while merge_text_file figured it out
+ * eventually and returned svn_wc_merge_unchanged for them, which
+ * is what we do here. */
+ SVN_ERR(svn_io_files_contents_same_p(&same_contents,
+ detranslated_target_abspath,
+ right_abspath, scratch_pool));
+ if (same_contents)
+ {
+ *merge_outcome = svn_wc_merge_unchanged;
+ return SVN_NO_ERROR;
+ }
+ }
*merge_outcome = svn_wc_merge_no_merge;
return SVN_NO_ERROR;
@@ -1418,8 +1440,8 @@ svn_wc__internal_merge(svn_skel_t **work
SVN_ERR(merge_file_trivial(work_items, merge_outcome,
left_abspath, right_abspath,
- target_abspath, dry_run, db,
- result_pool, scratch_pool));
+ target_abspath, detranslated_target_abspath,
+ dry_run, db, result_pool, scratch_pool));
if (*merge_outcome == svn_wc_merge_no_merge)
{
if (is_binary)
@@ -1476,7 +1498,8 @@ svn_wc__internal_merge(svn_skel_t **work
svn_error_t *
-svn_wc_merge4(enum svn_wc_merge_outcome_t *merge_outcome,
+svn_wc_merge5(enum svn_wc_merge_outcome_t *merge_content_outcome,
+ enum svn_wc_notify_state_t *merge_props_outcome,
svn_wc_context_t *wc_ctx,
const char *left_abspath,
const char *right_abspath,
@@ -1489,6 +1512,7 @@ svn_wc_merge4(enum svn_wc_merge_outcome_
svn_boolean_t dry_run,
const char *diff3_cmd,
const apr_array_header_t *merge_options,
+ apr_hash_t *original_props,
const apr_array_header_t *prop_diff,
svn_wc_conflict_resolver_func2_t conflict_func,
void *conflict_baton,
@@ -1497,8 +1521,11 @@ svn_wc_merge4(enum svn_wc_merge_outcome_
apr_pool_t *scratch_pool)
{
const char *dir_abspath = svn_dirent_dirname(target_abspath, scratch_pool);
+ svn_skel_t *prop_items = NULL;
svn_skel_t *work_items;
- apr_hash_t *actual_props;
+ apr_hash_t *pristine_props = NULL;
+ apr_hash_t *actual_props = NULL;
+ apr_hash_t *new_actual_props = NULL;
SVN_ERR_ASSERT(svn_dirent_is_absolute(left_abspath));
SVN_ERR_ASSERT(svn_dirent_is_absolute(right_abspath));
@@ -1508,37 +1535,86 @@ svn_wc_merge4(enum svn_wc_merge_outcome_
if (!dry_run)
SVN_ERR(svn_wc__write_check(wc_ctx->db, dir_abspath, scratch_pool));
- /* Sanity check: the merge target must be under revision control,
- * unless the merge target is a copyfrom text, which lives in a
- * temporary file and does not exist in ACTUAL yet. */
+ /* Sanity check: the merge target must be a file under revision control */
{
+ svn_wc__db_status_t status;
svn_kind_t kind;
- svn_boolean_t hidden;
- SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, target_abspath, TRUE,
- scratch_pool));
+ svn_boolean_t had_props;
+ svn_boolean_t props_mod;
- if (kind == svn_kind_unknown)
+ SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, &had_props, &props_mod, NULL, NULL,
+ NULL,
+ wc_ctx->db, target_abspath,
+ scratch_pool, scratch_pool));
+
+ if (kind != svn_kind_file || (status != svn_wc__db_status_normal
+ && status != svn_wc__db_status_added))
{
- *merge_outcome = svn_wc_merge_no_merge;
+ *merge_content_outcome = svn_wc_merge_no_merge;
+ if (merge_props_outcome)
+ *merge_props_outcome = svn_wc_notify_state_unchanged;
return SVN_NO_ERROR;
}
- SVN_ERR(svn_wc__db_node_hidden(&hidden, wc_ctx->db, target_abspath,
- scratch_pool));
+ if (merge_props_outcome && had_props)
+ {
+ SVN_ERR(svn_wc__db_read_pristine_props(&pristine_props,
+ wc_ctx->db, target_abspath,
+ scratch_pool, scratch_pool));
+ }
+ else if (merge_props_outcome)
+ pristine_props = apr_hash_make(scratch_pool);
- if (hidden)
+ if (props_mod)
{
- *merge_outcome = svn_wc_merge_no_merge;
- return SVN_NO_ERROR;
+ SVN_ERR(svn_wc__db_read_props(&actual_props,
+ wc_ctx->db, target_abspath,
+ scratch_pool, scratch_pool));
}
+ else if (pristine_props)
+ actual_props = apr_hash_copy(scratch_pool, pristine_props);
+ else
+ actual_props = apr_hash_make(scratch_pool);
}
- SVN_ERR(svn_wc__db_read_props(&actual_props, wc_ctx->db, target_abspath,
- scratch_pool, scratch_pool));
+ if (merge_props_outcome)
+ {
+ int i;
+ apr_hash_t *new_pristine_props;
+ /* The PROPCHANGES may not have non-"normal" properties in it. If entry
+ or wc props were allowed, then the following code would install them
+ into the BASE and/or WORKING properties(!). */
+ for (i = prop_diff->nelts; i--; )
+ {
+ const svn_prop_t *change = &APR_ARRAY_IDX(prop_diff, i, svn_prop_t);
+
+ if (!svn_wc_is_normal_prop(change->name))
+ return svn_error_createf(SVN_ERR_BAD_PROP_KIND, NULL,
+ _("The property '%s' may not be merged "
+ "into '%s'."),
+ change->name,
+ svn_dirent_local_style(target_abspath,
+ scratch_pool));
+ }
+
+ SVN_ERR(svn_wc__merge_props(&prop_items, merge_props_outcome,
+ &new_pristine_props, &new_actual_props,
+ wc_ctx->db, target_abspath, svn_kind_file,
+ left_version, right_version,
+ original_props, pristine_props, actual_props,
+ prop_diff, FALSE /* base_merge */,
+ dry_run,
+ conflict_func, conflict_baton,
+ cancel_func, cancel_baton,
+ scratch_pool, scratch_pool));
+ }
/* Queue all the work. */
SVN_ERR(svn_wc__internal_merge(&work_items,
- merge_outcome,
+ merge_content_outcome,
wc_ctx->db,
left_abspath, left_version,
right_abspath, right_version,
@@ -1554,16 +1630,24 @@ svn_wc_merge4(enum svn_wc_merge_outcome_
cancel_func, cancel_baton,
scratch_pool, scratch_pool));
+ work_items = svn_wc__wq_merge(prop_items, work_items, scratch_pool);
+
/* If this isn't a dry run, then run the work! */
if (!dry_run)
{
- SVN_ERR(svn_wc__db_wq_add(wc_ctx->db, target_abspath, work_items,
- scratch_pool));
+ if (new_actual_props)
+ SVN_ERR(svn_wc__db_op_set_props(wc_ctx->db, target_abspath,
+ new_actual_props,
+ svn_wc__has_magic_property(prop_diff),
+ NULL, work_items, scratch_pool));
+ else
+ SVN_ERR(svn_wc__db_wq_add(wc_ctx->db, target_abspath, work_items,
+ scratch_pool));
SVN_ERR(svn_wc__wq_run(wc_ctx->db, target_abspath,
cancel_func, cancel_baton,
scratch_pool));
}
-
+
return SVN_NO_ERROR;
}
Modified: subversion/branches/master-passphrase/subversion/libsvn_wc/node.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_wc/node.c?rev=1354571&r1=1354570&r2=1354571&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_wc/node.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_wc/node.c Wed Jun 27 15:12:37 2012
@@ -288,27 +288,18 @@ svn_wc_read_kind(svn_node_kind_t *kind,
svn_boolean_t show_hidden,
apr_pool_t *scratch_pool)
{
- svn_wc__db_status_t db_status;
svn_kind_t db_kind;
- svn_error_t *err;
- err = svn_wc__db_read_info(&db_status, &db_kind, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL,
- wc_ctx->db, local_abspath,
- scratch_pool, scratch_pool);
+ SVN_ERR(svn_wc__db_read_kind(&db_kind,
+ wc_ctx->db, local_abspath, TRUE, show_hidden,
+ scratch_pool));
- if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
- {
- svn_error_clear(err);
- *kind = svn_node_none;
- return SVN_NO_ERROR;
- }
+ if (db_kind == svn_kind_dir)
+ *kind = svn_node_dir;
+ else if (db_kind == svn_kind_file || db_kind == svn_kind_symlink)
+ *kind = svn_node_file;
else
- SVN_ERR(err);
-
- SVN_ERR(convert_db_kind_to_node_kind(kind, db_kind, db_status, show_hidden));
+ *kind = svn_node_none;
return SVN_NO_ERROR;
}
@@ -876,41 +867,47 @@ svn_wc__node_has_working(svn_boolean_t *
}
-static svn_error_t *
-get_base_rev(svn_revnum_t *base_revision,
- svn_wc__db_t *db,
- const char *local_abspath,
- apr_pool_t *scratch_pool)
+svn_error_t *
+svn_wc__node_get_base(svn_revnum_t *revision,
+ const char **repos_relpath,
+ const char **repos_root_url,
+ const char **repos_uuid,
+ svn_wc_context_t *wc_ctx,
+ const char *local_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
svn_error_t *err;
- err = svn_wc__db_base_get_info(NULL, NULL, base_revision, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- db, local_abspath,
- scratch_pool, scratch_pool);
-
- if (!err || err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
- return svn_error_trace(err);
-
- svn_error_clear(err);
-
- *base_revision = SVN_INVALID_REVNUM;
+ err = svn_wc__db_base_get_info(NULL, NULL, revision, repos_relpath,
+ repos_root_url, repos_uuid, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL,
+ wc_ctx->db, local_abspath,
+ result_pool, scratch_pool);
+ if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+ {
+ svn_error_clear(err);
+ if (revision)
+ *revision = SVN_INVALID_REVNUM;
+ if (repos_relpath)
+ *repos_relpath = NULL;
+ if (repos_root_url)
+ *repos_root_url = NULL;
+ if (repos_uuid)
+ *repos_uuid = NULL;
+ return SVN_NO_ERROR;
+ }
+ SVN_ERR(err);
+ SVN_ERR_ASSERT(!revision || SVN_IS_VALID_REVNUM(*revision));
+ SVN_ERR_ASSERT(!repos_relpath || *repos_relpath);
+ SVN_ERR_ASSERT(!repos_root_url || *repos_root_url);
+ SVN_ERR_ASSERT(!repos_uuid || *repos_uuid);
return SVN_NO_ERROR;
}
svn_error_t *
-svn_wc__node_get_base_rev(svn_revnum_t *base_revision,
- svn_wc_context_t *wc_ctx,
- const char *local_abspath,
- apr_pool_t *scratch_pool)
-{
- return svn_error_trace(get_base_rev(base_revision, wc_ctx->db,
- local_abspath, scratch_pool));
-}
-
-svn_error_t *
svn_wc__node_get_pre_ng_status_data(svn_revnum_t *revision,
svn_revnum_t *changed_rev,
apr_time_t *changed_date,
@@ -960,36 +957,54 @@ svn_wc__node_get_pre_ng_status_data(svn_
svn_error_t *
-svn_wc__internal_get_commit_base_rev(svn_revnum_t *commit_base_revision,
- svn_wc__db_t *db,
- const char *local_abspath,
- apr_pool_t *scratch_pool)
+svn_wc__internal_get_commit_base(svn_revnum_t *commit_base_revision,
+ const char **repos_relpath,
+ const char **repos_root_url,
+ const char **repos_uuid,
+ svn_wc__db_t *db,
+ const char *local_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
svn_wc__db_status_t status;
svn_boolean_t have_base;
svn_boolean_t have_more_work;
svn_revnum_t revision;
- svn_revnum_t original_revision;
+ svn_revnum_t orig_revision;
+ const char *orig_repos_relpath;
+ const char *orig_repos_root_url;
+ const char *orig_repos_uuid;
*commit_base_revision = SVN_INVALID_REVNUM;
- SVN_ERR(svn_wc__db_read_info(&status, NULL, &revision, NULL, NULL, NULL,
+ SVN_ERR(svn_wc__db_read_info(&status, NULL,
+ &revision, repos_relpath,
+ repos_root_url, repos_uuid,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ &orig_repos_relpath, &orig_repos_root_url,
+ &orig_repos_uuid, &orig_revision,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, &original_revision, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL,
&have_base, &have_more_work, NULL,
db, local_abspath, scratch_pool, scratch_pool));
if (SVN_IS_VALID_REVNUM(revision))
{
/* We are looking directly at BASE */
- *commit_base_revision = revision;
+ if (commit_base_revision)
+ *commit_base_revision = revision;
return SVN_NO_ERROR;
}
- else if (SVN_IS_VALID_REVNUM(original_revision))
+ else if (SVN_IS_VALID_REVNUM(orig_revision))
{
/* We are looking at a copied node */
- *commit_base_revision = original_revision;
+ if (commit_base_revision)
+ *commit_base_revision = orig_revision;
+ if (repos_relpath)
+ *repos_relpath = orig_repos_relpath;
+ if (repos_root_url)
+ *repos_root_url = orig_repos_root_url;
+ if (repos_uuid)
+ *repos_uuid = orig_repos_uuid;
return SVN_NO_ERROR;
}
@@ -997,8 +1012,9 @@ svn_wc__internal_get_commit_base_rev(svn
{
/* If the node was copied/moved-here, return the copy/move source
revision (not this node's base revision). */
- SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, commit_base_revision,
+ SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL,
+ repos_relpath, repos_root_url,
+ repos_uuid, commit_base_revision,
NULL, NULL, db, local_abspath,
scratch_pool, scratch_pool));
@@ -1019,10 +1035,10 @@ svn_wc__internal_get_commit_base_rev(svn
{
/* This is a deletion within a copied subtree. Get the copied-from
* revision. */
- SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL,
- commit_base_revision, NULL, NULL,
- db,
+ SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL,
+ repos_relpath, repos_root_url,
+ repos_uuid, commit_base_revision,
+ NULL, NULL, db,
svn_dirent_dirname(work_del_abspath,
scratch_pool),
scratch_pool, scratch_pool));
@@ -1038,7 +1054,8 @@ svn_wc__internal_get_commit_base_rev(svn
if (have_base && !have_more_work)
{
SVN_ERR(svn_wc__db_base_get_info(&status, NULL, commit_base_revision,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ repos_relpath, repos_root_url,
+ repos_uuid, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
db, local_abspath,
scratch_pool, scratch_pool));
@@ -1051,14 +1068,19 @@ svn_wc__internal_get_commit_base_rev(svn
}
svn_error_t *
-svn_wc__node_get_commit_base_rev(svn_revnum_t *commit_base_revision,
- svn_wc_context_t *wc_ctx,
- const char *local_abspath,
- apr_pool_t *scratch_pool)
-{
- return svn_error_trace(svn_wc__internal_get_commit_base_rev(
- commit_base_revision, wc_ctx->db, local_abspath,
- scratch_pool));
+svn_wc__node_get_commit_base(svn_revnum_t *revision,
+ const char **repos_relpath,
+ const char **repos_root_url,
+ const char **repos_uuid,
+ svn_wc_context_t *wc_ctx,
+ const char *local_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ return svn_error_trace(svn_wc__internal_get_commit_base(
+ revision, repos_relpath, repos_root_url, repos_uuid,
+ wc_ctx->db, local_abspath,
+ result_pool, scratch_pool));
}
svn_error_t *
@@ -1322,18 +1344,18 @@ svn_wc__node_get_lock_tokens_recursive(a
}
svn_error_t *
-svn_wc__get_server_excluded_subtrees(apr_hash_t **server_excluded_subtrees,
- svn_wc_context_t *wc_ctx,
- const char *local_abspath,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
+svn_wc__get_excluded_subtrees(apr_hash_t **server_excluded_subtrees,
+ svn_wc_context_t *wc_ctx,
+ const char *local_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
return svn_error_trace(
- svn_wc__db_get_server_excluded_subtrees(server_excluded_subtrees,
- wc_ctx->db,
- local_abspath,
- result_pool,
- scratch_pool));
+ svn_wc__db_get_excluded_subtrees(server_excluded_subtrees,
+ wc_ctx->db,
+ local_abspath,
+ result_pool,
+ scratch_pool));
}
svn_error_t *
@@ -1475,68 +1497,38 @@ svn_wc__node_get_origin(svn_boolean_t *i
}
svn_error_t *
-svn_wc__node_get_commit_status(svn_node_kind_t *kind,
- svn_boolean_t *added,
+svn_wc__node_get_commit_status(svn_boolean_t *added,
svn_boolean_t *deleted,
svn_boolean_t *is_replace_root,
- svn_boolean_t *not_present,
- svn_boolean_t *excluded,
svn_boolean_t *is_op_root,
- svn_boolean_t *symlink,
svn_revnum_t *revision,
- const char **repos_relpath,
svn_revnum_t *original_revision,
const char **original_repos_relpath,
- svn_boolean_t *conflicted,
- const char **changelist,
- svn_boolean_t *props_mod,
- svn_boolean_t *update_root,
- const char **lock_token,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
svn_wc__db_status_t status;
- svn_kind_t db_kind;
- svn_wc__db_lock_t *lock;
- svn_boolean_t had_props;
- svn_boolean_t props_mod_tmp;
svn_boolean_t have_base;
svn_boolean_t have_more_work;
svn_boolean_t op_root;
- if (!props_mod)
- props_mod = &props_mod_tmp;
-
/* ### All of this should be handled inside a single read transaction */
- SVN_ERR(svn_wc__db_read_info(&status, &db_kind, revision, repos_relpath,
+ SVN_ERR(svn_wc__db_read_info(&status, NULL, revision, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
original_repos_relpath, NULL, NULL,
- original_revision, &lock, NULL, NULL,
- changelist, conflicted,
- &op_root, &had_props, props_mod,
+ original_revision, NULL, NULL, NULL,
+ NULL, NULL,
+ &op_root, NULL, NULL,
&have_base, &have_more_work, NULL,
wc_ctx->db, local_abspath,
result_pool, scratch_pool));
- if (kind)
- {
- if (db_kind == svn_kind_file)
- *kind = svn_node_file;
- else if (db_kind == svn_kind_dir)
- *kind = svn_node_dir;
- else
- *kind = svn_node_unknown;
- }
if (added)
*added = (status == svn_wc__db_status_added);
if (deleted)
*deleted = (status == svn_wc__db_status_deleted);
- if (not_present)
- *not_present = (status == svn_wc__db_status_not_present);
- if (excluded)
- *excluded = (status == svn_wc__db_status_excluded);
if (is_op_root)
*is_op_root = op_root;
@@ -1552,40 +1544,19 @@ svn_wc__node_get_commit_status(svn_node_
*is_replace_root = FALSE;
}
- if (symlink)
- {
- apr_hash_t *props;
- *symlink = FALSE;
-
- if (db_kind == svn_kind_file
- && (had_props || *props_mod))
- {
- SVN_ERR(svn_wc__db_read_props(&props, wc_ctx->db, local_abspath,
- scratch_pool, scratch_pool));
-
- *symlink = ((props != NULL)
- && (apr_hash_get(props, SVN_PROP_SPECIAL,
- APR_HASH_KEY_STRING) != NULL));
- }
- }
-
/* Retrieve some information from BASE which is needed for replacing
- and/or deleting BASE nodes. (We don't need lock here) */
+ and/or deleting BASE nodes. */
if (have_base
- && ((revision && !SVN_IS_VALID_REVNUM(*revision))
- || (update_root && status == svn_wc__db_status_normal)))
+ && !have_more_work
+ && op_root
+ && (revision && !SVN_IS_VALID_REVNUM(*revision)))
{
SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, revision, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, update_root,
+ NULL, NULL, NULL,
wc_ctx->db, local_abspath,
scratch_pool, scratch_pool));
}
- else if (update_root)
- *update_root = FALSE;
-
- if (lock_token)
- *lock_token = lock ? lock->token : NULL;
return SVN_NO_ERROR;
}
Modified: subversion/branches/master-passphrase/subversion/libsvn_wc/old-and-busted.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_wc/old-and-busted.c?rev=1354571&r1=1354570&r2=1354571&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_wc/old-and-busted.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_wc/old-and-busted.c Wed Jun 27 15:12:37 2012
@@ -382,7 +382,7 @@ opt_revision_to_string(const char **str,
*str = apr_pstrmemdup(pool, "HEAD", 4);
break;
case svn_opt_revision_number:
- *str = apr_itoa(pool, rev->value.number);
+ *str = apr_ltoa(pool, rev->value.number);
break;
default:
return svn_error_createf
Modified: subversion/branches/master-passphrase/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_wc/props.c?rev=1354571&r1=1354570&r2=1354571&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_wc/props.c Wed Jun 27 15:12:37 2012
@@ -79,14 +79,12 @@ append_prop_conflict(svn_stream_t *strea
/* TODO: someday, perhaps prefix each conflict_description with a
timestamp or something? */
const svn_string_t *conflict_desc;
- apr_size_t len;
const char *native_text;
SVN_ERR(prop_conflict_from_skel(&conflict_desc, prop_skel, pool, pool));
native_text = svn_utf_cstring_from_utf8_fuzzy(conflict_desc->data, pool);
- len = strlen(native_text);
- return svn_stream_write(stream, native_text, &len);
+ return svn_stream_puts(stream, native_text);
}
@@ -1844,7 +1842,6 @@ svn_wc__prop_list_recursive(svn_wc_conte
const char *local_abspath,
const char *propname,
svn_depth_t depth,
- svn_boolean_t base_props,
svn_boolean_t pristine,
const apr_array_header_t *changelists,
svn_wc__proplist_receiver_t receiver_func,
@@ -1855,8 +1852,11 @@ svn_wc__prop_list_recursive(svn_wc_conte
{
svn_wc__proplist_receiver_t receiver = receiver_func;
void *baton = receiver_baton;
- struct propname_filter_baton_t pfb = { receiver_func, receiver_baton,
- propname };
+ struct propname_filter_baton_t pfb;
+
+ pfb.receiver_func = receiver_func;
+ pfb.receiver_baton = receiver_baton;
+ pfb.propname = propname;
SVN_ERR_ASSERT(receiver_func);
@@ -1898,7 +1898,7 @@ svn_wc__prop_list_recursive(svn_wc_conte
case svn_depth_infinity:
{
SVN_ERR(svn_wc__db_read_props_streamily(wc_ctx->db, local_abspath,
- depth, base_props, pristine,
+ depth, pristine,
changelists, receiver, baton,
cancel_func, cancel_baton,
scratch_pool));
@@ -1912,6 +1912,22 @@ svn_wc__prop_list_recursive(svn_wc_conte
}
svn_error_t *
+svn_wc__prop_retrieve_recursive(apr_hash_t **values,
+ svn_wc_context_t *wc_ctx,
+ const char *local_abspath,
+ const char *propname,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ return svn_error_trace(
+ svn_wc__db_prop_retrieve_recursive(values,
+ wc_ctx->db,
+ local_abspath,
+ propname,
+ result_pool, scratch_pool));
+}
+
+svn_error_t *
svn_wc__get_pristine_props(apr_hash_t **props,
svn_wc__db_t *db,
const char *local_abspath,
@@ -2210,32 +2226,11 @@ do_propset(svn_wc__db_t *db,
{
apr_hash_t *prophash;
svn_wc_notify_action_t notify_action;
- svn_wc__db_status_t status;
svn_skel_t *work_item = NULL;
svn_boolean_t clear_recorded_info = FALSE;
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
- /* Get the node status for this path. */
- SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL,
- db, local_abspath,
- scratch_pool, scratch_pool));
-
- if (status != svn_wc__db_status_normal
- && status != svn_wc__db_status_added
- && status != svn_wc__db_status_incomplete)
- return svn_error_createf(SVN_ERR_WC_INVALID_SCHEDULE, NULL,
- _("Can't set properties on '%s':"
- " invalid status for updating properties."),
- svn_dirent_local_style(local_abspath,
- scratch_pool));
-
- /* Else, handle a regular property: */
-
-
/* Setting an inappropriate property is not allowed (unless
overridden by 'skip_checks', in some circumstances). Deleting an
inappropriate property is allowed, however, since older clients
@@ -2320,7 +2315,7 @@ do_propset(svn_wc__db_t *db,
}
else if (kind == svn_node_file && strcmp(name, SVN_PROP_EOL_STYLE) == 0)
{
- svn_string_t *old_value = apr_hash_get(prophash, SVN_PROP_KEYWORDS,
+ svn_string_t *old_value = apr_hash_get(prophash, SVN_PROP_EOL_STYLE,
APR_HASH_KEY_STRING);
if (((value == NULL) != (old_value == NULL))
@@ -2430,6 +2425,7 @@ svn_wc_prop_set4(svn_wc_context_t *wc_ct
apr_pool_t *scratch_pool)
{
enum svn_prop_kind prop_kind = svn_property_kind2(name);
+ svn_wc__db_status_t status;
svn_kind_t kind;
const char *dir_abspath;
@@ -2451,8 +2447,22 @@ svn_wc_prop_set4(svn_wc_context_t *wc_ct
backward we never call this API with depth > empty, so we only need
to do the write check once per call, here (and not for every node in
the node walker). */
- SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, local_abspath, TRUE,
- scratch_pool));
+ /* Get the node status for this path. */
+ SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ wc_ctx->db, local_abspath,
+ scratch_pool, scratch_pool));
+
+ if (status != svn_wc__db_status_normal
+ && status != svn_wc__db_status_added
+ && status != svn_wc__db_status_incomplete)
+ return svn_error_createf(SVN_ERR_WC_INVALID_SCHEDULE, NULL,
+ _("Can't set properties on '%s':"
+ " invalid status for updating properties."),
+ svn_dirent_local_style(local_abspath,
+ scratch_pool));
if (kind == svn_kind_dir)
dir_abspath = local_abspath;
@@ -2461,7 +2471,7 @@ svn_wc_prop_set4(svn_wc_context_t *wc_ct
SVN_ERR(svn_wc__write_check(wc_ctx->db, dir_abspath, scratch_pool));
- if (depth == svn_depth_empty)
+ if (depth == svn_depth_empty || kind != svn_kind_dir)
{
apr_hash_t *changelist_hash = NULL;
@@ -2482,8 +2492,14 @@ svn_wc_prop_set4(svn_wc_context_t *wc_ct
}
else
{
- struct propset_walk_baton wb = { name, value, wc_ctx->db, skip_checks,
- notify_func, notify_baton };
+ struct propset_walk_baton wb;
+
+ wb.propname = name;
+ wb.propval = value;
+ wb.db = wc_ctx->db;
+ wb.force = skip_checks;
+ wb.notify_func = notify_func;
+ wb.notify_baton = notify_baton;
SVN_ERR(svn_wc__internal_walk_children(wc_ctx->db, local_abspath,
FALSE, changelist_filter,
Modified: subversion/branches/master-passphrase/subversion/libsvn_wc/questions.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_wc/questions.c?rev=1354571&r1=1354570&r2=1354571&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_wc/questions.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_wc/questions.c Wed Jun 27 15:12:37 2012
@@ -374,11 +374,9 @@ svn_error_t *
svn_wc_text_modified_p2(svn_boolean_t *modified_p,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
- svn_boolean_t force_comparison,
+ svn_boolean_t unused,
apr_pool_t *scratch_pool)
{
- /* ### We ignore FORCE_COMPARISON, but we also fixed its only
- remaining use-case */
return svn_wc__internal_file_modified_p(modified_p, wc_ctx->db,
local_abspath, FALSE, scratch_pool);
}
@@ -398,6 +396,8 @@ svn_wc__internal_conflicted_p(svn_boolea
const apr_array_header_t *conflicts;
int i;
svn_boolean_t conflicted;
+ svn_boolean_t resolved_text = FALSE;
+ svn_boolean_t resolved_props = FALSE;
if (text_conflicted_p)
*text_conflicted_p = FALSE;
@@ -466,7 +466,12 @@ svn_wc__internal_conflicted_p(svn_boolea
scratch_pool));
*text_conflicted_p = (kind == svn_node_file);
+
+ if (*text_conflicted_p)
+ break;
}
+
+ resolved_text = TRUE; /* Remove in-db conflict marker */
break;
case svn_wc_conflict_kind_property:
@@ -479,8 +484,11 @@ svn_wc__internal_conflicted_p(svn_boolea
scratch_pool));
*prop_conflicted_p = (kind == svn_node_file);
- }
+ if (*prop_conflicted_p)
+ break;
+ }
+ resolved_props = TRUE; /* Remove in-db conflict marker */
break;
case svn_wc_conflict_kind_tree:
@@ -494,6 +502,23 @@ svn_wc__internal_conflicted_p(svn_boolea
break;
}
}
+
+ if (resolved_text || resolved_props)
+ {
+ svn_boolean_t own_lock;
+
+ /* The marker files are missing, so "repair" wc.db if we can */
+ SVN_ERR(svn_wc__db_wclock_owns_lock(&own_lock, db, local_abspath, FALSE,
+ scratch_pool));
+ if (own_lock)
+ SVN_ERR(svn_wc__db_op_mark_resolved(db, local_abspath,
+ resolved_text,
+ resolved_props,
+ FALSE /* resolved_tree */,
+ NULL /* work_items */,
+ scratch_pool));
+ }
+
return SVN_NO_ERROR;
}