You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ph...@apache.org on 2010/05/28 14:15:01 UTC
svn commit: r949157 - in /subversion/trunk/subversion/libsvn_wc: copy.c
wc-queries.sql wc_db.c wc_db.h
Author: philip
Date: Fri May 28 12:15:01 2010
New Revision: 949157
URL: http://svn.apache.org/viewvc?rev=949157&view=rev
Log:
Fix issue 3553: revprop change hook errors are not XML safe.
* subversion/mod_dav_svn/deadprops.c
(save_value): Quote hook error.
* subversion/tests/cmdline/prop_tests.py
(post_revprop_change_hook): Use regex for error matching, verify change.
(test_list): Remove XFail from post_revprop_change_hook.
Modified:
subversion/trunk/subversion/libsvn_wc/copy.c
subversion/trunk/subversion/libsvn_wc/wc-queries.sql
subversion/trunk/subversion/libsvn_wc/wc_db.c
subversion/trunk/subversion/libsvn_wc/wc_db.h
Modified: subversion/trunk/subversion/libsvn_wc/copy.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/copy.c?rev=949157&r1=949156&r2=949157&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/copy.c (original)
+++ subversion/trunk/subversion/libsvn_wc/copy.c Fri May 28 12:15:01 2010
@@ -34,6 +34,8 @@
#include "svn_path.h"
#include "wc.h"
+#include "log.h"
+#include "workqueue.h"
#include "adm_files.h"
#include "entries.h"
#include "props.h"
@@ -258,6 +260,7 @@ copy_added_dir_administratively(svn_wc_c
return SVN_NO_ERROR;
}
+#ifndef SVN_EXPERIMENTAL_COPY
/* This function effectively creates and schedules a file for
addition, but does extra administrative things to allow it to
function as a 'copy'.
@@ -475,6 +478,7 @@ copy_file_administratively(svn_wc_contex
return SVN_NO_ERROR;
}
+#endif
/* Recursively crawl over a directory PATH and do a number of things:
@@ -730,6 +734,98 @@ copy_dir_administratively(svn_wc_context
}
}
+#ifdef SVN_EXPERIMENTAL_COPY
+/* A replacement for both copy_file_administratively and
+ copy_added_file_administratively. Not yet fully working. Relies
+ on in-db-props. */
+static svn_error_t *
+copy_file(svn_wc_context_t *wc_ctx,
+ const char *src_abspath,
+ const char *dst_abspath,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ svn_wc_notify_func2_t notify_func,
+ void *notify_baton,
+ apr_pool_t *scratch_pool)
+{
+ svn_skel_t *work_items = NULL;
+ const char *dir_abspath = svn_dirent_dirname(dst_abspath, scratch_pool);
+ const char *tmpdir_abspath;
+ svn_stream_t *src, *src_pristine;
+ const char *tmp_dst_abspath;
+ svn_error_t *err;
+
+ SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&tmpdir_abspath, wc_ctx->db,
+ dst_abspath,
+ scratch_pool, scratch_pool));
+
+#ifndef SVN_EXPERIMENTAL_PRISTINE
+ SVN_ERR(svn_wc__get_pristine_contents(&src_pristine, wc_ctx->db,
+ src_abspath,
+ scratch_pool, scratch_pool));
+ if (src_pristine)
+ {
+ svn_skel_t *work_item;
+ svn_stream_t *tmp_pristine;
+ const char *tmp_pristine_abspath, *dst_pristine_abspath;
+
+ 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__text_base_path(&dst_pristine_abspath, wc_ctx->db,
+ dst_abspath, scratch_pool));
+ SVN_ERR(svn_wc__loggy_move(&work_item, wc_ctx->db, dir_abspath,
+ tmp_pristine_abspath, dst_pristine_abspath,
+ scratch_pool));
+ work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
+ }
+#endif
+
+ err = svn_stream_open_readonly(&src, src_abspath, scratch_pool, scratch_pool);
+ if (err)
+ {
+ if (!APR_STATUS_IS_ENOENT(err->apr_err))
+ return svn_error_return(err);
+ /* Source may not exist when recursively copying a directory. */
+ svn_error_clear(err);
+ }
+ else
+ {
+ svn_skel_t *work_item;
+ svn_stream_t *tmp_dst;
+
+ SVN_ERR(svn_stream_open_unique(&tmp_dst, &tmp_dst_abspath,
+ tmpdir_abspath, svn_io_file_del_none,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_io_copy_perms(src_abspath,
+ tmp_dst_abspath, scratch_pool));
+ SVN_ERR(svn_stream_copy3(src, tmp_dst,
+ cancel_func, cancel_baton, scratch_pool));
+ SVN_ERR(svn_wc__loggy_move(&work_item, wc_ctx->db, dir_abspath,
+ tmp_dst_abspath, dst_abspath,
+ scratch_pool));
+ work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
+ }
+
+ SVN_ERR(svn_wc__db_op_copy(wc_ctx->db, src_abspath, dst_abspath,
+ work_items, scratch_pool));
+ SVN_ERR(svn_wc__wq_run(wc_ctx->db, dir_abspath,
+ cancel_func, cancel_baton, scratch_pool));
+
+ if (notify_func)
+ {
+ svn_wc_notify_t *notify
+ = svn_wc_create_notify(dst_abspath, svn_wc_notify_add,
+ scratch_pool);
+ notify->kind = svn_node_file;
+ (*notify_func)(notify_baton, notify, scratch_pool);
+ }
+ return SVN_NO_ERROR;
+}
+#endif
+
/* Public Interface */
@@ -814,6 +910,7 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
if (src_kind == svn_node_file ||
(src_entry->kind == svn_node_file && src_kind == svn_node_none))
{
+#ifndef SVN_EXPERIMENTAL_COPY
/* Check if we are copying a file scheduled for addition,
these require special handling. */
if (src_entry->schedule == svn_wc_schedule_add
@@ -835,6 +932,41 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
notify_func, notify_baton,
scratch_pool));
}
+#else
+ svn_node_kind_t dst_kind, dst_db_kind;
+
+ /* This is the error checking from copy_file_administratively
+ but converted to wc-ng. It's not in copy_file since this
+ checking only needs to happen at the root of the copy and not
+ when called recursively. */
+ SVN_ERR(svn_io_check_path(dst_abspath, &dst_kind, scratch_pool));
+ if (dst_kind != svn_node_none)
+ return svn_error_createf(SVN_ERR_ENTRY_EXISTS, NULL,
+ _("'%s' already exists and is in the way"),
+ svn_dirent_local_style(dst_abspath,
+ scratch_pool));
+ SVN_ERR(svn_wc_read_kind(&dst_db_kind, wc_ctx, dst_abspath, TRUE,
+ scratch_pool));
+ if (dst_db_kind != svn_node_none)
+ {
+ svn_boolean_t is_deleted, is_present;
+
+ SVN_ERR(svn_wc__node_is_status_deleted(&is_deleted, wc_ctx,
+ dst_abspath, scratch_pool));
+ SVN_ERR(svn_wc__node_is_status_present(&is_present, wc_ctx,
+ dst_abspath, scratch_pool));
+ if (is_present && !is_deleted)
+ return svn_error_createf(SVN_ERR_ENTRY_EXISTS, NULL,
+ _("There is already a versioned item '%s'"),
+ svn_dirent_local_style(dst_abspath,
+ scratch_pool));
+
+ }
+
+ SVN_ERR(copy_file(wc_ctx, src_abspath, dst_abspath,
+ cancel_func, cancel_baton, notify_func, notify_baton,
+ scratch_pool));
+#endif
}
else if (src_kind == svn_node_dir)
{
Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=949157&r1=949156&r2=949157&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Fri May 28 12:15:01 2010
@@ -412,6 +412,39 @@ SELECT 0 FROM BASE_NODE WHERE wc_id = ?1
UNION
SELECT 1 FROM WORKING_NODE WHERE wc_id = ?1 AND local_relpath = ?2;
+-- STMT_INSERT_WORKING_NODE_COPY_FROM_BASE
+INSERT INTO WORKING_NODE (
+ wc_id, local_relpath, parent_relpath, presence, kind, checksum,
+ translated_size, changed_rev, changed_date, changed_author, depth,
+ symlink_target, last_mod_time, properties, copyfrom_repos_id,
+ copyfrom_repos_path, copyfrom_revnum )
+SELECT wc_id, ?3 AS local_relpath, ?4 AS parent_relpath, ?5 AS presence, kind,
+ checksum, translated_size, changed_rev, changed_date, changed_author, depth,
+ symlink_target, last_mod_time, properties, ?6 AS copyfrom_repos_id,
+ ?7 AS copyfrom_repos_path, ?8 AS copyfrom_revnum FROM BASE_NODE
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
+-- STMT_INSERT_WORKING_NODE_COPY_FROM_WORKING
+INSERT INTO WORKING_NODE (
+ wc_id, local_relpath, parent_relpath, presence, kind, checksum,
+ translated_size, changed_rev, changed_date, changed_author, depth,
+ symlink_target, last_mod_time, properties, copyfrom_repos_id,
+ copyfrom_repos_path, copyfrom_revnum )
+SELECT wc_id, ?3 AS local_relpath, ?4 AS parent_relpath, ?5 AS presence, kind,
+ checksum, translated_size, changed_rev, changed_date, changed_author, depth,
+ symlink_target, last_mod_time, properties, ?6 AS copyfrom_repos_id,
+ ?7 AS copyfrom_repos_path, ?8 AS copyfrom_revnum FROM WORKING_NODE
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
+-- STMT_INSERT_ACTUAL_NODE_FROM_ACTUAL_NODE
+INSERT INTO ACTUAL_NODE (
+ wc_id, local_relpath, parent_relpath, properties,
+ conflict_old, conflict_new, conflict_working,
+ prop_reject, changelist, text_mod, tree_conflict_data )
+SELECT wc_id, ?3 AS local_relpath, ?4 AS parent_relpath, properties,
+ conflict_old, conflict_new, conflict_working,
+ prop_reject, changelist, text_mod, tree_conflict_data FROM ACTUAL_NODE
+WHERE wc_id = ?1 AND local_relpath = ?2;
/* ------------------------------------------------------------------------- */
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=949157&r1=949156&r2=949157&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Fri May 28 12:15:01 2010
@@ -2179,17 +2179,231 @@ svn_wc__db_repos_ensure(apr_int64_t *rep
scratch_pool));
}
+/* Temporary helper for svn_wc__db_op_copy to handle copying from one
+ db to another, it becomes redundant when we centralise. */
+static svn_error_t *
+temp_cross_db_copy(svn_wc__db_t *db,
+ const char *src_abspath,
+ svn_wc__db_pdh_t *dst_pdh,
+ const char *dst_relpath,
+ svn_wc__db_kind_t kind,
+ apr_int64_t copyfrom_id,
+ const char *copyfrom_relpath,
+ svn_revnum_t copyfrom_rev,
+ apr_pool_t *scratch_pool)
+{
+ insert_working_baton_t iwb;
+ svn_revnum_t changed_rev;
+ apr_time_t changed_date;
+ const char *changed_author;
+ const svn_checksum_t *checksum;
+ apr_hash_t *props;
+
+ SVN_ERR_ASSERT(kind == svn_wc__db_kind_file);
+
+ SVN_ERR(svn_wc__db_read_info(NULL, /* status */
+ NULL, /* kind */
+ NULL, /* revision */
+ NULL, /* repos_relpath */
+ NULL, /* repos_root_url */
+ NULL, /* repos_uuid */
+ &changed_rev, &changed_date, &changed_author,
+ NULL, /* last_mod_time */
+ NULL, /* depth */
+ &checksum,
+ NULL, /* translated_size */
+ NULL, /* target */
+ NULL, /* changelist */
+ NULL, /* original_repos_relpath */
+ NULL, /* original_root_url */
+ NULL, /* original_uuid */
+ NULL, /* original_revision */
+ NULL, /* text_mod */
+ NULL, /* props_mod */
+ NULL, /* base_shadowed */
+ NULL, /* conflicted */
+ NULL, /* lock */
+ db, src_abspath, scratch_pool, scratch_pool));
+
+ SVN_ERR(svn_wc__get_pristine_props(&props, db, src_abspath,
+ scratch_pool, scratch_pool));
+
+ iwb.presence = svn_wc__db_status_normal;
+ iwb.kind = kind;
+ iwb.wc_id = dst_pdh->wcroot->wc_id;
+ iwb.local_relpath = dst_relpath;
+
+ iwb.props = props;
+ iwb.changed_rev = changed_rev;
+ iwb.changed_date = changed_date;
+ iwb.changed_author = changed_author;
+ iwb.original_repos_id = copyfrom_id;
+ iwb.original_repos_relpath = copyfrom_relpath;
+ iwb.original_revnum = copyfrom_rev;
+ iwb.moved_here = FALSE;
+
+ iwb.checksum = checksum;
+
+ SVN_ERR(insert_working_node(&iwb, dst_pdh->wcroot->sdb, scratch_pool));
+
+ /* ### What about actual_node? */
+
+ return SVN_NO_ERROR;
+}
svn_error_t *
svn_wc__db_op_copy(svn_wc__db_t *db,
const char *src_abspath,
const char *dst_abspath,
+ const svn_skel_t *work_items,
apr_pool_t *scratch_pool)
{
+ svn_wc__db_pdh_t *src_pdh, *dst_pdh;
+ const char *src_relpath, *dst_relpath;
+ const char *repos_relpath, *repos_root_url, *repos_uuid, *copyfrom_relpath;
+ svn_revnum_t revision, copyfrom_rev;
+ svn_wc__db_status_t status;
+ apr_int64_t copyfrom_id;
+ svn_wc__db_kind_t kind;
+
SVN_ERR_ASSERT(svn_dirent_is_absolute(src_abspath));
SVN_ERR_ASSERT(svn_dirent_is_absolute(dst_abspath));
- NOT_IMPLEMENTED();
+ /* ### This should all happen in one transaction, but that can't
+ ### happen until we move to a centralised database. */
+
+ SVN_ERR(svn_wc__db_pdh_parse_local_abspath(&src_pdh, &src_relpath, db,
+ src_abspath,
+ svn_sqlite__mode_readwrite,
+ scratch_pool, scratch_pool));
+ VERIFY_USABLE_PDH(src_pdh);
+
+ SVN_ERR(svn_wc__db_pdh_parse_local_abspath(&dst_pdh, &dst_relpath, db,
+ dst_abspath,
+ svn_sqlite__mode_readwrite,
+ scratch_pool, scratch_pool));
+ VERIFY_USABLE_PDH(dst_pdh);
+
+
+ SVN_ERR(svn_wc__db_read_info(&status, &kind, &revision,
+ &repos_relpath, &repos_root_url, &repos_uuid,
+ NULL, /* changed_rev */
+ NULL, /* changed_date */
+ NULL, /* changed_author */
+ NULL, /* last_mod_time */
+ NULL, /* depth */
+ NULL, /* checksum */
+ NULL, /* translated_size */
+ NULL, /* target */
+ NULL, /* changelist */
+ NULL, /* original_repos_relpath */
+ NULL, /* original_root_url */
+ NULL, /* original_uuid */
+ NULL, /* original_revision */
+ NULL, /* text_mod */
+ NULL, /* props_mod */
+ NULL, /* base_shadowed */
+ NULL, /* conflicted */
+ NULL, /* lock */
+ db, src_abspath, scratch_pool, scratch_pool));
+
+ SVN_ERR_ASSERT(kind == svn_wc__db_kind_file);
+
+ if (status != svn_wc__db_status_added)
+ {
+ copyfrom_relpath = repos_relpath;
+ copyfrom_rev = revision;
+ SVN_ERR(create_repos_id(©from_id,
+ repos_root_url, repos_uuid,
+ src_pdh->wcroot->sdb, scratch_pool));
+ }
+ else
+ {
+ const char *op_root_abspath;
+ const char *original_repos_relpath, *original_root_url, *original_uuid;
+ svn_revnum_t original_revision;
+
+ SVN_ERR(svn_wc__db_scan_addition(&status, &op_root_abspath,
+ NULL, /* repos_relpath */
+ NULL, /* repos_root_url */
+ NULL, /* repos_uuid */
+ &original_repos_relpath,
+ &original_root_url, &original_uuid,
+ &original_revision,
+ db, src_abspath,
+ scratch_pool, scratch_pool));
+
+ if (status == svn_wc__db_status_copied
+ || status == svn_wc__db_status_moved_here)
+ {
+ copyfrom_relpath
+ = svn_relpath_join(original_repos_relpath,
+ svn_dirent_skip_ancestor(op_root_abspath,
+ src_abspath),
+ scratch_pool);
+ copyfrom_rev = original_revision;
+ SVN_ERR(create_repos_id(©from_id,
+ original_root_url, original_uuid,
+ src_pdh->wcroot->sdb, scratch_pool));
+ }
+ else
+ {
+ copyfrom_relpath = NULL;
+ copyfrom_rev = SVN_INVALID_REVNUM;
+ }
+ }
+
+
+
+ if (!strcmp(src_pdh->local_abspath, dst_pdh->local_abspath))
+ {
+ svn_sqlite__stmt_t *stmt;
+ const char *dst_parent_relpath = svn_relpath_dirname(dst_relpath,
+ scratch_pool);
+
+ /* ### Need a better way to determine whether a WORKING_NODE exists */
+ if (status == svn_wc__db_status_added
+ || status == svn_wc__db_status_copied
+ || status == svn_wc__db_status_moved_here)
+ SVN_ERR(svn_sqlite__get_statement(&stmt, src_pdh->wcroot->sdb,
+ STMT_INSERT_WORKING_NODE_COPY_FROM_WORKING));
+ else
+ SVN_ERR(svn_sqlite__get_statement(&stmt, src_pdh->wcroot->sdb,
+ STMT_INSERT_WORKING_NODE_COPY_FROM_BASE));
+
+ SVN_ERR(svn_sqlite__bindf(stmt, "issst",
+ src_pdh->wcroot->wc_id, src_relpath,
+ dst_relpath, dst_parent_relpath,
+ presence_map, svn_wc__db_status_normal));
+
+ if (copyfrom_relpath)
+ {
+ SVN_ERR(svn_sqlite__bind_int64(stmt, 6, copyfrom_id));
+ SVN_ERR(svn_sqlite__bind_text(stmt, 7, copyfrom_relpath));
+ SVN_ERR(svn_sqlite__bind_int64(stmt, 8, copyfrom_rev));
+ }
+ SVN_ERR(svn_sqlite__step_done(stmt));
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, src_pdh->wcroot->sdb,
+ STMT_INSERT_ACTUAL_NODE_FROM_ACTUAL_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isss",
+ src_pdh->wcroot->wc_id, src_relpath,
+ dst_relpath, dst_parent_relpath));
+ SVN_ERR(svn_sqlite__step_done(stmt));
+ }
+ else
+ {
+ SVN_ERR(temp_cross_db_copy(db, src_abspath, dst_pdh, dst_relpath, kind,
+ copyfrom_id, copyfrom_relpath, copyfrom_rev,
+ scratch_pool));
+ }
+
+ /* ### Should do this earlier and insert the node with the right values. */
+ SVN_ERR(svn_wc__db_temp_elide_copyfrom(db, dst_abspath, scratch_pool));
+
+ SVN_ERR(add_work_items(dst_pdh->wcroot->sdb, work_items, scratch_pool));
+
+ return SVN_NO_ERROR;
}
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=949157&r1=949156&r2=949157&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Fri May 28 12:15:01 2010
@@ -1015,6 +1015,7 @@ svn_error_t *
svn_wc__db_op_copy(svn_wc__db_t *db,
const char *src_abspath,
const char *dst_abspath,
+ const svn_skel_t *work_items,
apr_pool_t *scratch_pool);