Author: rhuijben
Date: Thu Feb 5 20:46:53 2015
New Revision: 1657686
URL: http://svn.apache.org/r1657686
Log:
Turn the replace_moved_layer() function in the move-update logic into an
internal wc_db function. This allows hiding a few more functions that are
too easy to abuse. And this function might be useful outside the move logic.
* subversion/libsvn_wc/wc-queries.sql
(STMT_SELECT_DESCENDANTS_OP_DEPTH_RV): Handle incomplete presence.
(STMT_SELECT_NO_LONGER_MOVED_RV): Obtain shadowing information.
(STMT_DELETE_NO_LOWER_LAYER): Remove unused statement.
* subversion/libsvn_wc/wc_db.c
(svn_wc__db_extend_parent_delete): Make static and rename to...
(db_extend_parent_delete): ... this.
(svn_wc__db_retract_parent_delete): Make static and rename to...
(db_retract_parent_delete): ... this.
(insert_base_node,
db_base_remove): Update caller.
(svn_wc__db_op_copy_layer_internal): New function.
* subversion/libsvn_wc/wc_db_private.h
(svn_wc__db_extend_parent_delete,
svn_wc__db_retract_parent_delete): Remove functions.
(svn_wc__db_op_copy_layer_internal): New function.
* subversion/libsvn_wc/wc_db_update_move.c
(delete_move_leaf): Remove function. Folded queries to fold this
function into its only caller.
(replace_moved_layer): Moved to wc_db.c as svn_wc__db_op_copy_layer_internal.
(drive_tree_conflict_editor): Update caller. Verify lock.
(bump_moved_layer): Update caller. Verify lock on origin.
Modified:
subversion/trunk/subversion/libsvn_wc/wc-queries.sql
subversion/trunk/subversion/libsvn_wc/wc_db.c
subversion/trunk/subversion/libsvn_wc/wc_db_private.h
subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c
Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1657686&r1=1657685&r2=1657686&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Thu Feb 5 20:46:53
2015
@@ -291,7 +291,7 @@ FROM nodes
WHERE wc_id = ?1
AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
AND op_depth = ?3
- AND presence = MAP_NORMAL
+ AND presence in (MAP_NORMAL, MAP_INCOMPLETE)
ORDER BY local_relpath DESC
-- STMT_COPY_NODE_MOVE
@@ -314,11 +314,17 @@ FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3
-- STMT_SELECT_NO_LONGER_MOVED_RV
-SELECT d.local_relpath, RELPATH_SKIP_JOIN(?2, ?4, d.local_relpath) srp
+SELECT d.local_relpath, RELPATH_SKIP_JOIN(?2, ?4, d.local_relpath) srp,
+ b.presence, b.op_depth
FROM nodes d
-WHERE wc_id = ?1
- AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
- AND op_depth = ?3
+LEFT OUTER JOIN nodes b ON b.wc_id = ?1 AND b.local_relpath = d.local_relpath
+ AND b.op_depth = (SELECT MAX(x.op_depth) FROM nodes x
+ WHERE x.wc_id = ?1
+ AND x.local_relpath = b.local_relpath
+ AND x.op_depth < ?3)
+WHERE d.wc_id = ?1
+ AND IS_STRICT_DESCENDANT_OF(d.local_relpath, ?2)
+ AND d.op_depth = ?3
AND NOT EXISTS(SELECT * FROM nodes s
WHERE s.wc_id = ?1
AND s.local_relpath = srp
@@ -968,17 +974,6 @@ INSERT INTO nodes (
parent_relpath, presence, kind)
VALUES(?1, ?2, ?3, ?4, MAP_BASE_DELETED, ?5)
--- STMT_DELETE_NO_LOWER_LAYER
-DELETE FROM nodes
- WHERE wc_id = ?1
- AND local_relpath = ?2
- AND op_depth = ?3
- AND NOT EXISTS (SELECT 1 FROM nodes n
- WHERE n.wc_id = ?1
- AND n.local_relpath = nodes.local_relpath
- AND n.op_depth = ?4
- AND n.presence IN (MAP_NORMAL, MAP_INCOMPLETE))
-
-- STMT_REPLACE_WITH_BASE_DELETED
INSERT OR REPLACE INTO nodes (wc_id, local_relpath, op_depth, parent_relpath,
kind, moved_to, presence)
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1657686&r1=1657685&r2=1657686&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Thu Feb 5 20:46:53 2015
@@ -569,13 +569,54 @@ blank_ibb(insert_base_baton_t *pibb)
}
-svn_error_t *
-svn_wc__db_extend_parent_delete(svn_boolean_t *added_delete,
- svn_wc__db_wcroot_t *wcroot,
- const char *local_relpath,
- svn_node_kind_t kind,
- int op_depth,
- apr_pool_t *scratch_pool)
+/* Extend any delete of the parent of LOCAL_RELPATH to LOCAL_RELPATH.
+
+ ### What about KIND and OP_DEPTH? KIND ought to be redundant; I'm
+ discussing on dev@ whether we can let that be null for presence
+ == base-deleted. OP_DEPTH is the op-depth of what, and why?
+ It is used to select the lowest working node higher than OP_DEPTH,
+ so, in terms of the API, OP_DEPTH means ...?
+
+ Given a wc:
+
+ 0 1 2 3 4
+ normal
+ A normal
+ A/B normal normal
+ A/B/C not-pres normal
+ A/B/C/D normal
+
+ That is checkout, delete A/B, copy a replacement A/B, delete copied
+ child A/B/C, add replacement A/B/C, add A/B/C/D.
+
+ Now an update that adds base nodes for A/B/C, A/B/C/D and A/B/C/D/E
+ must extend the A/B deletion:
+
+ 0 1 2 3 4
+ normal
+ A normal
+ A/B normal normal
+ A/B/C normal not-pres normal
+ A/B/C/D normal base-del normal
+ A/B/C/D/E normal base-del
+
+ When adding a node if the parent has a higher working node then the
+ parent node is deleted (or replaced) and the delete must be extended
+ to cover new node.
+
+ In the example above A/B/C/D and A/B/C/D/E are the nodes that get
+ the extended delete, A/B/C is already deleted.
+
+ If ADDED_DELETE is not NULL, set *ADDED_DELETE to TRUE if a new delete
+ was recorded, otherwise to FALSE.
+ */
+static svn_error_t *
+db_extend_parent_delete(svn_boolean_t *added_delete,
+ svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ svn_node_kind_t kind,
+ int op_depth,
+ apr_pool_t *scratch_pool)
{
svn_boolean_t have_row;
svn_sqlite__stmt_t *stmt;
@@ -623,7 +664,7 @@ svn_wc__db_extend_parent_delete(svn_bool
}
-/* This is the reverse of svn_wc__db_extend_parent_delete.
+/* This is the reverse of db_extend_parent_delete.
When removing a node if the parent has a higher working node then
the parent node and this node are both deleted or replaced and any
@@ -633,11 +674,11 @@ svn_wc__db_extend_parent_delete(svn_bool
only uses this function within an sqlite transaction if atomic
behavior is needed.
*/
-svn_error_t *
-svn_wc__db_retract_parent_delete(svn_wc__db_wcroot_t *wcroot,
- const char *local_relpath,
- int op_depth,
- apr_pool_t *scratch_pool)
+static svn_error_t *
+db_retract_parent_delete(svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ int op_depth,
+ apr_pool_t *scratch_pool)
{
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
@@ -840,17 +881,17 @@ insert_base_node(const insert_base_baton
|| (pibb->status == svn_wc__db_status_incomplete))
&& ! pibb->file_external)
{
- SVN_ERR(svn_wc__db_extend_parent_delete(NULL,
- wcroot, local_relpath,
- pibb->kind, 0,
- scratch_pool));
+ SVN_ERR(db_extend_parent_delete(NULL,
+ wcroot, local_relpath,
+ pibb->kind, 0,
+ scratch_pool));
}
else if (pibb->status == svn_wc__db_status_not_present
|| pibb->status == svn_wc__db_status_server_excluded
|| pibb->status == svn_wc__db_status_excluded)
{
- SVN_ERR(svn_wc__db_retract_parent_delete(wcroot, local_relpath, 0,
- scratch_pool));
+ SVN_ERR(db_retract_parent_delete(wcroot, local_relpath, 0,
+ scratch_pool));
}
}
@@ -2395,8 +2436,7 @@ db_base_remove(svn_wc__db_wcroot_t *wcro
SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__step_done(stmt));
- SVN_ERR(svn_wc__db_retract_parent_delete(wcroot, local_relpath, 0,
- scratch_pool));
+ SVN_ERR(db_retract_parent_delete(wcroot, local_relpath, 0, scratch_pool));
/* Step 6: Delete actual node if we don't keep working */
if (! keep_working)
@@ -4804,6 +4844,185 @@ svn_wc__db_op_copy(svn_wc__db_t *db,
return SVN_NO_ERROR;
}
+
+svn_error_t *
+svn_wc__db_op_copy_layer_internal(svn_wc__db_wcroot_t *wcroot,
+ const char *src_op_relpath,
+ int src_op_depth,
+ const char *dst_op_relpath,
+ svn_skel_t *conflict,
+ svn_skel_t *work_items,
+ apr_pool_t *scratch_pool)
+{
+ svn_sqlite__stmt_t *stmt, *stmt2;
+ svn_boolean_t have_row;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+ int dst_op_depth = relpath_depth(dst_op_relpath);
+ svn_boolean_t locked;
+ svn_error_t *err = NULL;
+
+ SVN_ERR(svn_wc__db_wclock_owns_lock_internal(&locked, wcroot, dst_op_relpath,
+ FALSE, scratch_pool));
+
+ if (!locked)
+ return svn_error_createf(SVN_ERR_WC_NOT_LOCKED, NULL,
+ _("No write-lock in '%s'"),
+ path_for_error_message(wcroot, dst_op_relpath,
+ scratch_pool));
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt2, wcroot->sdb,
+ STMT_COPY_NODE_MOVE));
+
+ /* Replace entire subtree at one op-depth. */
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ STMT_SELECT_LAYER_FOR_REPLACE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isdsd", wcroot->wc_id,
+ src_op_relpath, src_op_depth,
+ dst_op_relpath, dst_op_depth));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ while (have_row)
+ {
+ const char *src_relpath;
+ const char *dst_relpath;
+ svn_boolean_t exists;
+
+ svn_pool_clear(iterpool);
+
+ src_relpath = svn_sqlite__column_text(stmt, 0, iterpool);
+ dst_relpath = svn_sqlite__column_text(stmt, 2, iterpool);
+
+ exists = !svn_sqlite__column_is_null(stmt, 3);
+
+ err = svn_sqlite__bindf(stmt2, "isdsds", wcroot->wc_id,
+ src_relpath, src_op_depth,
+ dst_relpath, dst_op_depth,
+ svn_relpath_dirname(dst_relpath, iterpool));
+ if (!err)
+ err = svn_sqlite__step_done(stmt2);
+
+ /* stmt2 is reset (never modified or by step_done) */
+
+ if (err)
+ break;
+
+ if (strlen(dst_relpath) > strlen(dst_op_relpath))
+ {
+ svn_boolean_t added_delete = FALSE;
+ svn_node_kind_t kind = svn_sqlite__column_token(stmt, 1, kind_map);
+
+ /* The op root can't be shadowed, so extension of a parent delete
+ is only needed when the parent can be deleted */
+ if (relpath_depth(dst_relpath) > (dst_op_depth+1))
+ {
+ err = db_extend_parent_delete(&added_delete, wcroot, dst_relpath,
+ kind, dst_op_depth, iterpool);
+
+ if (err)
+ break;
+ }
+
+ if (exists)
+ {
+ svn_wc__db_status_t presence;
+
+ presence = svn_sqlite__column_token(stmt, 3, presence_map);
+
+ if (presence == svn_wc__db_status_not_present)
+ exists = FALSE;
+ }
+
+ /* ### Fails in a few tests... Needs further research */
+ /*SVN_ERR_ASSERT(!(exists && added_delete));*/
+
+ if (!exists)
+ {
+ svn_boolean_t shadowed;
+
+ shadowed = svn_sqlite__column_int(stmt, 4);
+
+ /*if (!shadowed && !added_delete)
+ {
+ err = svn_error_createf(
+ SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
+ _("Node '%s' was unexpectedly added unshadowed"),
+ path_for_error_message(wcroot, dst_relpath,
+ iterpool));
+ break;
+ }*/
+ }
+ }
+
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ }
+
+ SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
+
+ /* And now remove the records that are no longer needed */
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ STMT_SELECT_NO_LONGER_MOVED_RV));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isdsd", wcroot->wc_id,
+ dst_op_relpath, dst_op_depth,
+ src_op_relpath, src_op_depth));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ while (have_row)
+ {
+ const char *dst_relpath;
+ svn_wc__db_status_t shadowed_presence;
+
+ svn_pool_clear(iterpool);
+
+ dst_relpath = svn_sqlite__column_text(stmt, 0, iterpool);
+
+ if (!svn_sqlite__column_is_null(stmt, 2))
+ shadowed_presence = svn_sqlite__column_token(stmt, 2, presence_map);
+ else
+ shadowed_presence = svn_wc__db_status_not_present;
+
+ if (shadowed_presence != svn_wc__db_status_normal
+ && shadowed_presence != svn_wc__db_status_incomplete)
+ {
+ err = svn_sqlite__get_statement(&stmt2, wcroot->sdb,
+ STMT_DELETE_NODE);
+ }
+ else
+ {
+ err =svn_sqlite__get_statement(&stmt2, wcroot->sdb,
+ STMT_REPLACE_WITH_BASE_DELETED);
+ }
+
+ if (!err)
+ err = svn_sqlite__bindf(stmt2, "isd", wcroot->wc_id, dst_relpath,
+ dst_op_depth);
+
+ if (!err)
+ err = svn_sqlite__step_done(stmt2);
+
+ /* stmt2 is reset (never modified or by step_done) */
+
+ if (err)
+ break;
+
+ /* Retract base-delete for the node itself */
+ err = db_retract_parent_delete(wcroot, dst_relpath, dst_op_depth,
+ scratch_pool);
+
+ if (err)
+ break;
+
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ }
+ svn_pool_destroy(iterpool);
+
+ SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
+
+ SVN_ERR(add_work_items(wcroot->sdb, work_items, scratch_pool));
+
+ if (conflict)
+ SVN_ERR(svn_wc__db_mark_conflict_internal(wcroot, dst_op_relpath /* ## */,
+ conflict, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
/* The txn body of svn_wc__db_op_handle_move_back */
static svn_error_t *
Modified: subversion/trunk/subversion/libsvn_wc/wc_db_private.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db_private.h?rev=1657686&r1=1657685&r2=1657686&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db_private.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db_private.h Thu Feb 5 20:46:53
2015
@@ -394,61 +394,18 @@ svn_wc__db_get_children_op_depth(apr_has
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
-
-/* Extend any delete of the parent of LOCAL_RELPATH to LOCAL_RELPATH.
-
- ### What about KIND and OP_DEPTH? KIND ought to be redundant; I'm
- discussing on dev@ whether we can let that be null for presence
- == base-deleted. OP_DEPTH is the op-depth of what, and why?
- It is used to select the lowest working node higher than OP_DEPTH,
- so, in terms of the API, OP_DEPTH means ...?
-
- Given a wc:
-
- 0 1 2 3 4
- normal
- A normal
- A/B normal normal
- A/B/C not-pres normal
- A/B/C/D normal
-
- That is checkout, delete A/B, copy a replacement A/B, delete copied
- child A/B/C, add replacement A/B/C, add A/B/C/D.
-
- Now an update that adds base nodes for A/B/C, A/B/C/D and A/B/C/D/E
- must extend the A/B deletion:
-
- 0 1 2 3 4
- normal
- A normal
- A/B normal normal
- A/B/C normal not-pres normal
- A/B/C/D normal base-del normal
- A/B/C/D/E normal base-del
-
- When adding a node if the parent has a higher working node then the
- parent node is deleted (or replaced) and the delete must be extended
- to cover new node.
-
- In the example above A/B/C/D and A/B/C/D/E are the nodes that get
- the extended delete, A/B/C is already deleted.
-
- If ADDED_DELETE is not NULL, set *ADDED_DELETE to TRUE if a new delete
- was recorded, otherwise to FALSE.
- */
+/* Update the single op-depth layer in the move destination subtree
+ rooted at DST_RELPATH to make it match the move source subtree
+ rooted at SRC_RELPATH. */
svn_error_t *
-svn_wc__db_extend_parent_delete(svn_boolean_t *added_delete,
- svn_wc__db_wcroot_t *wcroot,
- const char *local_relpath,
- svn_node_kind_t kind,
- int op_depth,
- apr_pool_t *scratch_pool);
+svn_wc__db_op_copy_layer_internal(svn_wc__db_wcroot_t *wcroot,
+ const char *src_op_relpath,
+ int src_op_depth,
+ const char *dst_op_relpath,
+ svn_skel_t *conflict,
+ svn_skel_t *work_items,
+ apr_pool_t *scratch_pool);
-svn_error_t *
-svn_wc__db_retract_parent_delete(svn_wc__db_wcroot_t *wcroot,
- const char *local_relpath,
- int op_depth,
- apr_pool_t *scratch_pool);
/* Extract the moved-to information for LOCAL_RELPATH at OP-DEPTH by
examining the lowest working node above OP_DEPTH. The output paths
Modified: subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c?rev=1657686&r1=1657685&r2=1657686&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c Thu Feb 5
20:46:53 2015
@@ -1233,63 +1233,6 @@ tc_editor_delete(update_move_baton_t *b,
return SVN_NO_ERROR;
}
-/* Delete handling for a node and its shadowing */
-static svn_error_t *
-delete_move_leaf(svn_wc__db_wcroot_t *wcroot,
- const char *local_relpath,
- int op_depth,
- apr_pool_t *scratch_pool)
-{
- svn_sqlite__stmt_t *stmt;
- svn_boolean_t have_row;
- int op_depth_below;
-
- /* Deleting the ROWS is valid as long as we update the parent before
- committing the transaction. The removed rows could have been
- replacing a lower layer in which case we need to add base-deleted
- rows. */
- SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_SELECT_HIGHEST_WORKING_NODE));
- SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
- svn_relpath_dirname(local_relpath, scratch_pool),
- op_depth));
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- if (have_row)
- op_depth_below = svn_sqlite__column_int(stmt, 0);
- SVN_ERR(svn_sqlite__reset(stmt));
- if (have_row)
- {
- /* Remove non-shadowing nodes. */
- SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_DELETE_NO_LOWER_LAYER));
- SVN_ERR(svn_sqlite__bindf(stmt, "isdd", wcroot->wc_id, local_relpath,
- op_depth, op_depth_below));
- SVN_ERR(svn_sqlite__step_done(stmt));
-
- /* Convert remaining shadowing nodes to presence='base-deleted'. */
- SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_REPLACE_WITH_BASE_DELETED));
- SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
- op_depth));
- SVN_ERR(svn_sqlite__step_done(stmt));
- }
- else
- {
- SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_DELETE_NODE));
- SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
- op_depth));
- SVN_ERR(svn_sqlite__step_done(stmt));
- }
-
- /* Retract base-delete for the node itself */
- SVN_ERR(svn_wc__db_retract_parent_delete(wcroot, local_relpath, op_depth,
- scratch_pool));
-
- return SVN_NO_ERROR;
-}
-
-
/*
* Driver code.
*
@@ -1633,142 +1576,6 @@ update_moved_away_node(update_move_baton
return SVN_NO_ERROR;
}
-/* Update the single op-depth layer in the move destination subtree
- rooted at DST_RELPATH to make it match the move source subtree
- rooted at SRC_RELPATH. */
-static svn_error_t *
-replace_moved_layer(svn_wc__db_wcroot_t *wcroot,
- const char *src_op_relpath,
- int src_op_depth,
- const char *dst_op_relpath,
- apr_pool_t *scratch_pool)
-{
- svn_sqlite__stmt_t *stmt, *stmt2;
- svn_boolean_t have_row;
- apr_pool_t *iterpool = svn_pool_create(scratch_pool);
- int dst_op_depth = relpath_depth(dst_op_relpath);
- svn_error_t *err = NULL;
-
- SVN_ERR(verify_write_lock(wcroot, src_op_relpath, scratch_pool));
- SVN_ERR(verify_write_lock(wcroot, dst_op_relpath, scratch_pool));
-
- SVN_ERR(svn_sqlite__get_statement(&stmt2, wcroot->sdb,
- STMT_COPY_NODE_MOVE));
-
- /* Replace entire subtree at one op-depth. */
- SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_SELECT_LAYER_FOR_REPLACE));
- SVN_ERR(svn_sqlite__bindf(stmt, "isdsd", wcroot->wc_id,
- src_op_relpath, src_op_depth,
- dst_op_relpath, dst_op_depth));
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- while (have_row)
- {
- const char *src_relpath;
- const char *dst_relpath;
- svn_boolean_t exists;
-
- svn_pool_clear(iterpool);
-
- src_relpath = svn_sqlite__column_text(stmt, 0, iterpool);
- dst_relpath = svn_sqlite__column_text(stmt, 2, iterpool);
-
- exists = !svn_sqlite__column_is_null(stmt, 3);
-
- err = svn_sqlite__bindf(stmt2, "isdsds", wcroot->wc_id,
- src_relpath, src_op_depth,
- dst_relpath, dst_op_depth,
- svn_relpath_dirname(dst_relpath, iterpool));
- if (!err)
- err = svn_sqlite__step_done(stmt2);
-
- /* stmt2 is reset (never modified or by step_done) */
-
- if (err)
- break;
-
- if (strlen(dst_relpath) > strlen(dst_op_relpath))
- {
- svn_boolean_t added_delete = FALSE;
- svn_node_kind_t kind = svn_sqlite__column_token(stmt, 1, kind_map);
-
- /* The op root can't be shadowed, so extension of a parent delete
- is only needed when the parent can be deleted */
- if (relpath_depth(dst_relpath) > (dst_op_depth+1))
- {
- err = svn_wc__db_extend_parent_delete(&added_delete,
- wcroot, dst_relpath, kind,
- dst_op_depth, iterpool);
-
- if (err)
- break;
- }
-
- if (exists)
- {
- svn_wc__db_status_t presence;
-
- presence = svn_sqlite__column_token(stmt, 3, presence_map);
-
- if (presence == svn_wc__db_status_not_present)
- exists = FALSE;
- }
-
- /* ### Fails in a few tests... Needs further research */
- /*SVN_ERR_ASSERT(!(exists && added_delete));*/
-
- if (!exists)
- {
- svn_boolean_t shadowed;
-
- shadowed = svn_sqlite__column_int(stmt, 4);
-
- /*if (!shadowed && !added_delete)
- {
- err = svn_error_createf(
- SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
- _("Node '%s' was unexpectedly added unshadowed"),
- path_for_error_message(wcroot, dst_relpath,
- iterpool));
- break;
- }*/
- }
- }
-
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- }
-
- SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
-
- /* And now remove the records that are no longer needed */
- SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_SELECT_NO_LONGER_MOVED_RV));
- SVN_ERR(svn_sqlite__bindf(stmt, "isdsd", wcroot->wc_id,
- dst_op_relpath, dst_op_depth,
- src_op_relpath, src_op_depth));
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- while (have_row)
- {
- const char *dst_relpath;
-
- svn_pool_clear(iterpool);
-
- dst_relpath = svn_sqlite__column_text(stmt, 0, iterpool);
-
- err = delete_move_leaf(wcroot, dst_relpath, dst_op_depth,
- iterpool);
-
- if (err)
- break;
-
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- }
- svn_pool_destroy(iterpool);
-
- SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
- return SVN_NO_ERROR;
-}
-
/* Transfer changes from the move source to the move destination.
*
* Drive the editor with the difference between DST_RELPATH
@@ -1796,6 +1603,8 @@ drive_tree_conflict_editor(update_move_b
void *cancel_baton,
apr_pool_t *scratch_pool)
{
+ SVN_ERR(verify_write_lock(wcroot, src_relpath, scratch_pool));
+ SVN_ERR(verify_write_lock(wcroot, dst_relpath, scratch_pool));
/*
* Refuse to auto-resolve unsupported tree conflicts.
*/
@@ -1815,8 +1624,9 @@ drive_tree_conflict_editor(update_move_b
dst_relpath, FALSE /* never shadowed */,
db, scratch_pool));
- SVN_ERR(replace_moved_layer(wcroot, src_relpath, src_op_depth, dst_relpath,
- scratch_pool));
+ SVN_ERR(svn_wc__db_op_copy_layer_internal(wcroot, src_relpath, src_op_depth,
+ dst_relpath, NULL, NULL,
+ scratch_pool));
return SVN_NO_ERROR;
}
@@ -2318,10 +2128,13 @@ bump_moved_layer(svn_boolean_t *recurse,
if (!conflict)
{
/* ### TODO: verify moved_here? */
- SVN_ERR(replace_moved_layer(wcroot,
- src_relpath, op_depth,
- dst_relpath,
- scratch_pool));
+
+ SVN_ERR(verify_write_lock(wcroot, src_relpath, scratch_pool));
+
+ SVN_ERR(svn_wc__db_op_copy_layer_internal(wcroot,
+ src_relpath, op_depth,
+ dst_relpath, NULL, NULL,
+ scratch_pool));
*recurse = TRUE;
}