Author: stsp
Date: Wed Jul 13 16:33:12 2011
New Revision: 1146119
URL: http://svn.apache.org/viewvc?rev=1146119&view=rev
Log:
Start recording the difference between a copy and a move in wc.db.
With this commit we set the existing 'moved_here' boolean flag in
the NODES table on the node which is the add-half of a copy (as well
as any children of this node) if a copy was in fact a move.
* subversion/libsvn_wc/wc-queries.sql
(STMT_INSERT_WORKING_NODE_COPY_FROM_BASE,
STMT_INSERT_WORKING_NODE_COPY_FROM_WORKING,
STMT_INSERT_WORKING_NODE_COPY_FROM_DEPTH): Fill the 'moved_here' column
from a new query parameter.
* subversion/libsvn_wc/copy.c
(copy_versioned_file, copy_versioned_dir): New parameter IS_MOVE which
indicates whether the copy is in fact a move. Call the appropriate
svn_wc__db_op interface function depending on this parameter.
(copy_or_move): New, contains most code from svn_wc_copy3(). Pass IS_MOVE
parameter down to copy_versioned_file() and copy_versioned_dir().
(svn_wc_copy3): Reimplement as a thin wrapper around copy_or_move().
(svn_wc_move): Call copy_or_move() instead of svn_wc_copy3().
* subversion/libsvn_wc/entries.c
(read_one_entry): Treat status 'moved-here' the same as status 'copied'
so that moved nodes appear as normal copies to old code.
* subversion/libsvn_wc/wc_db.c
(db_op_copy): Add new parameter IS_MOVE, which is passed into DB queries
as appropriate.
(op_copy_baton): New field IS_MOVE.
(op_copy_txn): Pass IS_MOVE from copy baton to db_op_copy().
(svn_wc__db_op_copy): Initialise new field IS_MOVE in copy baton.
(db_op_copy_shadowed_layer): Pass 0 for 'moved_here' query parameter
while creating in-DB copies of nodes shadowed by a copy/move operation.
(svn_wc__db_op_move): Implement. Set IS_MOVE in the copy baton so that
the copy code will treat this operation as a move.
* subversion/libsvn_wc/wc_db.h
(svn_wc__db_op_copy_shadowed_layer): Tweak docstring.
(svn_wc__db_op_move): Make signature match that of svn_wc__op_copy()
and tweak the docstring.
Modified:
subversion/trunk/subversion/libsvn_wc/copy.c
subversion/trunk/subversion/libsvn_wc/entries.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=1146119&r1=1146118&r2=1146119&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/copy.c (original)
+++ subversion/trunk/subversion/libsvn_wc/copy.c Wed Jul 13 16:33:12 2011
@@ -175,6 +175,9 @@ copy_pristine_text_if_necessary(svn_wc__
otherwise copy both the versioned metadata and the filesystem node (even
if it is the wrong kind, and recursively if it is a dir).
+ If IS_MOVE is true, record move information in working copy meta
+ data in addition to copying the file.
+
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,6 +193,7 @@ copy_versioned_file(svn_wc__db_t *db,
const svn_checksum_t *checksum,
svn_boolean_t metadata_only,
svn_boolean_t conflicted,
+ svn_boolean_t is_move,
svn_cancel_func_t cancel_func,
void *cancel_baton,
svn_wc_notify_func2_t notify_func,
@@ -308,8 +312,14 @@ copy_versioned_file(svn_wc__db_t *db,
/* Copy the (single) node's metadata, and move the new filesystem node
into place. */
- SVN_ERR(svn_wc__db_op_copy(db, src_abspath, dst_abspath, dst_op_root_abspath,
- work_items, scratch_pool));
+ if (is_move)
+ SVN_ERR(svn_wc__db_op_move(db, src_abspath, dst_abspath,
+ dst_op_root_abspath, work_items,
+ scratch_pool));
+ else
+ SVN_ERR(svn_wc__db_op_copy(db, src_abspath, dst_abspath,
+ dst_op_root_abspath, work_items,
+ scratch_pool));
SVN_ERR(svn_wc__wq_run(db, dir_abspath,
cancel_func, cancel_baton, scratch_pool));
@@ -327,7 +337,9 @@ copy_versioned_file(svn_wc__db_t *db,
/* Copy the versioned dir SRC_ABSPATH in DB to the path DST_ABSPATH in DB,
recursively. If METADATA_ONLY is true, copy only the versioned metadata,
otherwise copy both the versioned metadata and the filesystem nodes (even
- if they are the wrong kind, and including unversioned children). */
+ 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. */
static svn_error_t *
copy_versioned_dir(svn_wc__db_t *db,
const char *src_abspath,
@@ -335,6 +347,7 @@ copy_versioned_dir(svn_wc__db_t *db,
const char *dst_op_root_abspath,
const char *tmpdir_abspath,
svn_boolean_t metadata_only,
+ svn_boolean_t is_move,
svn_cancel_func_t cancel_func,
void *cancel_baton,
svn_wc_notify_func2_t notify_func,
@@ -370,8 +383,14 @@ copy_versioned_dir(svn_wc__db_t *db,
/* Copy the (single) node's metadata, and move the new filesystem node
into place. */
- SVN_ERR(svn_wc__db_op_copy(db, src_abspath, dst_abspath, dst_op_root_abspath,
- work_items, scratch_pool));
+ if (is_move)
+ SVN_ERR(svn_wc__db_op_move(db, src_abspath, dst_abspath,
+ dst_op_root_abspath, work_items,
+ scratch_pool));
+ else
+ SVN_ERR(svn_wc__db_op_copy(db, src_abspath, dst_abspath,
+ dst_op_root_abspath, work_items,
+ scratch_pool));
SVN_ERR(svn_wc__wq_run(db, dir_abspath,
cancel_func, cancel_baton, scratch_pool));
@@ -456,6 +475,7 @@ copy_versioned_dir(svn_wc__db_t *db,
dst_op_root_abspath,
tmpdir_abspath, checksum,
metadata_only, conflicted,
+ is_move,
cancel_func, cancel_baton,
NULL, NULL,
iterpool));
@@ -464,7 +484,7 @@ copy_versioned_dir(svn_wc__db_t *db,
SVN_ERR(copy_versioned_dir(db,
child_src_abspath, child_dst_abspath,
dst_op_root_abspath, tmpdir_abspath,
- metadata_only,
+ metadata_only, is_move,
cancel_func, cancel_baton, NULL, NULL,
iterpool));
else
@@ -479,9 +499,14 @@ copy_versioned_dir(svn_wc__db_t *db,
{
/* This will be copied as some kind of deletion. Don't touch
any actual files */
- SVN_ERR(svn_wc__db_op_copy(db, child_src_abspath, child_dst_abspath,
- dst_op_root_abspath,
- NULL, iterpool));
+ if (is_move)
+ SVN_ERR(svn_wc__db_op_move(db, child_src_abspath,
+ child_dst_abspath, dst_op_root_abspath,
+ NULL, scratch_pool));
+ else
+ SVN_ERR(svn_wc__db_op_copy(db, child_src_abspath,
+ child_dst_abspath, dst_op_root_abspath,
+ NULL, iterpool));
/* Don't recurse on children while all we do is creating not-present
children */
@@ -563,13 +588,15 @@ copy_versioned_dir(svn_wc__db_t *db,
}
-/* Public Interface */
-
-svn_error_t *
-svn_wc_copy3(svn_wc_context_t *wc_ctx,
+/* The guts of svn_wc_copy3() and svn_wc_move().
+ * The additional parameter IS_MOVE indicates whether this is a copy or
+ * a move operation. */
+static svn_error_t *
+copy_or_move(svn_wc_context_t *wc_ctx,
const char *src_abspath,
const char *dst_abspath,
svn_boolean_t metadata_only,
+ svn_boolean_t is_move,
svn_cancel_func_t cancel_func,
void *cancel_baton,
svn_wc_notify_func2_t notify_func,
@@ -744,7 +771,7 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
{
SVN_ERR(copy_versioned_file(db, src_abspath, dst_abspath, dst_abspath,
tmpdir_abspath, checksum,
- metadata_only, conflicted,
+ metadata_only, conflicted, is_move,
cancel_func, cancel_baton,
notify_func, notify_baton,
scratch_pool));
@@ -753,7 +780,7 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
{
SVN_ERR(copy_versioned_dir(db, src_abspath, dst_abspath, dst_abspath,
tmpdir_abspath,
- metadata_only,
+ metadata_only, is_move,
cancel_func, cancel_baton,
notify_func, notify_baton,
scratch_pool));
@@ -762,6 +789,28 @@ svn_wc_copy3(svn_wc_context_t *wc_ctx,
return SVN_NO_ERROR;
}
+
+/* Public Interface */
+
+svn_error_t *
+svn_wc_copy3(svn_wc_context_t *wc_ctx,
+ const char *src_abspath,
+ const char *dst_abspath,
+ svn_boolean_t metadata_only,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ svn_wc_notify_func2_t notify_func,
+ void *notify_baton,
+ apr_pool_t *scratch_pool)
+{
+ return svn_error_trace(copy_or_move(wc_ctx, src_abspath, dst_abspath,
+ metadata_only, FALSE /* is_move */,
+ cancel_func, cancel_baton,
+ notify_func, notify_baton,
+ scratch_pool));
+}
+
+
/* Remove the conflict markers of NODE_ABSPATH, that were left over after
copying NODE_ABSPATH from SRC_ABSPATH.
@@ -922,8 +971,9 @@ svn_wc_move(svn_wc_context_t *wc_ctx,
apr_pool_t *scratch_pool)
{
svn_wc__db_t *db = wc_ctx->db;
- SVN_ERR(svn_wc_copy3(wc_ctx, src_abspath, dst_abspath,
+ SVN_ERR(copy_or_move(wc_ctx, src_abspath, dst_abspath,
TRUE /* metadata_only */,
+ TRUE /* is_move */,
cancel_func, cancel_baton,
notify_func, notify_baton,
scratch_pool));
Modified: subversion/trunk/subversion/libsvn_wc/entries.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/entries.c?rev=1146119&r1=1146118&r2=1146119&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/entries.c (original)
+++ subversion/trunk/subversion/libsvn_wc/entries.c Wed Jul 13 16:33:12 2011
@@ -637,7 +637,10 @@ read_one_entry(const svn_wc_entry_t **ne
/* ### scan_addition may need to be updated to avoid returning
### status_copied in this case. */
}
- else if (work_status == svn_wc__db_status_copied)
+ /* For backwards-compatiblity purposes we treat moves just like
+ * regular copies. */
+ else if (work_status == svn_wc__db_status_copied ||
+ work_status == svn_wc__db_status_moved_here)
{
entry->copied = TRUE;
@@ -662,7 +665,8 @@ read_one_entry(const svn_wc_entry_t **ne
svn_boolean_t is_copied_child;
svn_boolean_t is_mixed_rev = FALSE;
- SVN_ERR_ASSERT(work_status == svn_wc__db_status_copied);
+ SVN_ERR_ASSERT(work_status == svn_wc__db_status_copied ||
+ work_status == svn_wc__db_status_moved_here);
/* If this node inherits copyfrom information from an
ancestor node, then it must be a copied child. */
Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1146119&r1=1146118&r2=1146119&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Wed Jul 13 16:33:12
2011
@@ -870,11 +870,11 @@ WHERE wc_id = ?1
-- STMT_INSERT_WORKING_NODE_COPY_FROM_BASE
INSERT OR REPLACE INTO nodes (
wc_id, local_relpath, op_depth, parent_relpath, repos_id,
- repos_path, revision, presence, depth, kind, changed_revision,
+ repos_path, revision, presence, depth, moved_here, kind, changed_revision,
changed_date, changed_author, checksum, properties, translated_size,
last_mod_time, symlink_target )
SELECT wc_id, ?3 /*local_relpath*/, ?4 /*op_depth*/, ?5 /*parent_relpath*/,
- repos_id, repos_path, revision, ?6 /*presence*/, depth,
+ repos_id, repos_path, revision, ?6 /*presence*/, depth, ?7/*moved_here*/,
kind, changed_revision, changed_date, changed_author, checksum, properties,
translated_size, last_mod_time, symlink_target
FROM nodes
@@ -883,11 +883,11 @@ WHERE wc_id = ?1 AND local_relpath = ?2
-- STMT_INSERT_WORKING_NODE_COPY_FROM_WORKING
INSERT OR REPLACE INTO nodes (
wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,
- revision, presence, depth, kind, changed_revision, changed_date,
+ revision, presence, depth, moved_here, kind, changed_revision,
changed_date,
changed_author, checksum, properties, translated_size, last_mod_time,
symlink_target )
SELECT wc_id, ?3 /*local_relpath*/, ?4 /*op_depth*/, ?5 /*parent_relpath*/,
- repos_id, repos_path, revision, ?6 /*presence*/, depth,
+ repos_id, repos_path, revision, ?6 /*presence*/, depth, ?7 /*moved_here*/,
kind, changed_revision, changed_date, changed_author, checksum, properties,
translated_size, last_mod_time, symlink_target
FROM nodes
@@ -898,15 +898,15 @@ LIMIT 1
-- STMT_INSERT_WORKING_NODE_COPY_FROM_DEPTH
INSERT OR REPLACE INTO nodes (
wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,
- revision, presence, depth, kind, changed_revision, changed_date,
+ revision, presence, depth, moved_here, kind, changed_revision,
changed_date,
changed_author, checksum, properties, translated_size, last_mod_time,
symlink_target )
SELECT wc_id, ?3 /*local_relpath*/, ?4 /*op_depth*/, ?5 /*parent_relpath*/,
- repos_id, repos_path, revision, ?6 /*presence*/,
- depth, kind, changed_revision, changed_date, changed_author, checksum,
+ repos_id, repos_path, revision, ?6 /*presence*/, depth, ?7 /*moved_here*/,
+ kind, changed_revision, changed_date, changed_author, checksum,
properties, translated_size, last_mod_time, symlink_target
FROM nodes
-WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?7
+WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?8
-- STMT_INSERT_ACTUAL_NODE_FROM_ACTUAL_NODE
INSERT OR REPLACE INTO actual_node (
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1146119&r1=1146118&r2=1146119&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Wed Jul 13 16:33:12 2011
@@ -3422,14 +3422,15 @@ op_depth_for_copy(apr_int64_t *op_depth,
apr_pool_t *scratch_pool);
-/* Like svn_wc__db_op_copy(), but with WCROOT+LOCAL_RELPATH instead of
- DB+LOCAL_ABSPATH. */
+/* Like svn_wc__db_op_copy()/svn_wc__db_op_move(), but with
+ WCROOT+LOCAL_RELPATH instead of DB+LOCAL_ABSPATH. */
static svn_error_t *
db_op_copy(svn_wc__db_wcroot_t *src_wcroot,
const char *src_relpath,
svn_wc__db_wcroot_t *dst_wcroot,
const char *dst_relpath,
const svn_skel_t *work_items,
+ svn_boolean_t is_move,
apr_pool_t *scratch_pool)
{
const char *copyfrom_relpath;
@@ -3544,12 +3545,13 @@ db_op_copy(svn_wc__db_wcroot_t *src_wcro
SVN_ERR(svn_sqlite__get_statement(&stmt, src_wcroot->sdb,
STMT_INSERT_WORKING_NODE_COPY_FROM_BASE));
- SVN_ERR(svn_sqlite__bindf(stmt, "issist",
+ SVN_ERR(svn_sqlite__bindf(stmt, "issisti",
src_wcroot->wc_id, src_relpath,
dst_relpath,
dst_op_depth,
dst_parent_relpath,
- presence_map, dst_presence));
+ presence_map, dst_presence,
+ (apr_int64_t)(is_move ? 1 : 0)));
SVN_ERR(svn_sqlite__step_done(stmt));
@@ -3619,6 +3621,7 @@ struct op_copy_baton
const char *dst_relpath;
const svn_skel_t *work_items;
+ svn_boolean_t is_move;
};
/* Helper for svn_wc__db_op_copy.
@@ -3642,7 +3645,7 @@ op_copy_txn(void * baton, svn_sqlite__db
SVN_ERR(db_op_copy(ocb->src_wcroot, ocb->src_relpath,
ocb->dst_wcroot, ocb->dst_relpath,
- ocb->work_items, scratch_pool));
+ ocb->work_items, ocb->is_move, scratch_pool));
return SVN_NO_ERROR;
}
@@ -3673,6 +3676,7 @@ svn_wc__db_op_copy(svn_wc__db_t *db,
VERIFY_USABLE_WCROOT(ocb.dst_wcroot);
ocb.work_items = work_items;
+ ocb.is_move = FALSE;
/* Call with the sdb in src_wcroot. It might call itself again to
also obtain a lock in dst_wcroot */
@@ -3812,15 +3816,16 @@ db_op_copy_shadowed_layer(svn_wc__db_wcr
SVN_ERR(svn_sqlite__get_statement(&stmt, src_wcroot->sdb,
STMT_INSERT_WORKING_NODE_COPY_FROM_BASE));
- SVN_ERR(svn_sqlite__bindf(stmt, "issist",
+ SVN_ERR(svn_sqlite__bindf(stmt, "issisti",
src_wcroot->wc_id, src_relpath,
dst_relpath,
dst_op_depth,
svn_relpath_dirname(dst_relpath, iterpool),
- presence_map, dst_presence));
+ presence_map, dst_presence,
+ (apr_int64_t)0));
if (src_op_depth > 0)
- SVN_ERR(svn_sqlite__bind_int64(stmt, 7, src_op_depth));
+ SVN_ERR(svn_sqlite__bind_int64(stmt, 8, src_op_depth));
SVN_ERR(svn_sqlite__step_done(stmt));
@@ -4713,12 +4718,36 @@ svn_error_t *
svn_wc__db_op_move(svn_wc__db_t *db,
const char *src_abspath,
const char *dst_abspath,
+ const char *dst_op_root_abspath,
+ const svn_skel_t *work_items,
apr_pool_t *scratch_pool)
{
+ struct op_copy_baton ocb = {0};
+
SVN_ERR_ASSERT(svn_dirent_is_absolute(src_abspath));
SVN_ERR_ASSERT(svn_dirent_is_absolute(dst_abspath));
- NOT_IMPLEMENTED();
+ SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&ocb.src_wcroot,
+ &ocb.src_relpath, db,
+ src_abspath,
+ scratch_pool, scratch_pool));
+ VERIFY_USABLE_WCROOT(ocb.src_wcroot);
+
+ SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&ocb.dst_wcroot,
+ &ocb.dst_relpath,
+ db, dst_abspath,
+ scratch_pool, scratch_pool));
+ VERIFY_USABLE_WCROOT(ocb.dst_wcroot);
+
+ ocb.work_items = work_items;
+ ocb.is_move = TRUE;
+
+ /* Call with the sdb in src_wcroot. It might call itself again to
+ also obtain a lock in dst_wcroot */
+ SVN_ERR(svn_sqlite__with_lock(ocb.src_wcroot->sdb, op_copy_txn, &ocb,
+ 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=1146119&r1=1146118&r2=1146119&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Wed Jul 13 16:33:12 2011
@@ -1227,7 +1227,8 @@ svn_wc__db_op_copy(svn_wc__db_t *db,
* properly deleted.
*
* Usually this operation is directly followed by a call to svn_wc__db_op_copy
- * which performs the real copy from src_abspath to dst_abspath.
+ * or svn_wc__db_op_move which performs the real copy from src_abspath to
+ * dst_abspath.
*/
svn_error_t *
svn_wc__db_op_copy_shadowed_layer(svn_wc__db_t *db,
@@ -1427,12 +1428,20 @@ svn_wc__db_op_delete(svn_wc__db_t *db,
apr_pool_t *scratch_pool);
-/* ### KFF: Would like to know behavior when dst_path already exists
- ### and is a) a dir or b) a non-dir. */
+/* Move the node at SRC_ABSPATH (in NODES and ACTUAL_NODE tables) to
+ * DST_ABSPATH, both in DB but not necessarily in the same WC. The parent
+ * of DST_ABSPATH must be a versioned directory.
+ *
+ * This move is NOT recursive. It simply establishes this one node, plus
+ * incomplete nodes for the children.
+ *
+ * Add WORK_ITEMS to the work queue. */
svn_error_t *
svn_wc__db_op_move(svn_wc__db_t *db,
const char *src_abspath,
const char *dst_abspath,
+ const char *dst_op_root_abspath,
+ const svn_skel_t *work_items,
apr_pool_t *scratch_pool);