Author: stsp Date: Wed Jul 27 18:59:52 2011 New Revision: 1151590 URL: http://svn.apache.org/viewvc?rev=1151590&view=rev Log: Make svn_wc__db_scan_addition() provide information the local source of a move for nodes with a 'moved-here' status.
Some future callers will only want to act on the op-roots involved in a move, e.g. the commit code detecting whether both halfs of a move are among the commit targets. Other future callers might want to act directly on children of the op-roots, e.g. code performing automatic tree conflict resolution. So scan_addition() provides both the moved_from abspath and the abspath of the operation root of the delete-half of the move. This should satisfy either use case to some degree. It might not be the optimal solution for all use cases but won't hurt, either. * subversion/libsvn_wc/wc_db.c (svn_wc__db_scan_addition, scan_addition): New output parameters MOVED_FROM_ABSPATH and DELETE_OP_ROOT_ABSPATH. (get_moved_from_info): New helper function which computes values for above new output parameters. (scan_addition_baton_t): Add MOVED_FROM_ABSPATH and DELETE_OP_ROOT_ABSPATH. (scan_addition_txn): Run get_moved_from_info() for 'moved-here' nodes. (get_info_for_copy, read_url_txn, svn_wc__db_global_relocate): Update scan_addition() calls. * subversion/libsvn_wc/wc_db.h (svn_wc__db_scan_addition): Update declaration and docstring. * subversion/libsvn_wc/wc-queries.sql (STMT_SELECT_MOVED_FROM_RELPATH): New query which selects the 'moved-from' path corresponding to a 'moved-here' node. * subversion/tests/libsvn_wc/db-test.c (TESTING_DATA): Create another row for the delete-half of a move. svn_wc__db_scan_addition() now treats a move without a delete-half as if it was a normal a copy. (We've been recording delete-halfs since r1151166.) (test_scan_addition): Check for moved-from information scan_addition() now returns for 'moved-here' nodes. The remaining items list updated callers of svn_wc__db_scan_addition(). All of them pass NULL for the new output parameters. * subversion/libsvn_wc/props.c (svn_wc__get_pristine_props): Update svn_wc__db_scan_addition() call. * subversion/libsvn_wc/adm_ops.c (check_can_add_to_parent): Update svn_wc__db_scan_addition() call. * subversion/libsvn_wc/adm_crawler.c (svn_wc_restore, report_revisions_and_depths, svn_wc_crawl_revisions5): Update svn_wc__db_scan_addition() calls. * subversion/libsvn_wc/diff_local.c (file_diff): Update svn_wc__db_scan_addition() call. * subversion/libsvn_wc/diff_editor.c (file_diff, report_wc_file_as_added, close_file): Update svn_wc__db_scan_addition() calls. * subversion/libsvn_wc/adm_files.c (svn_wc__internal_ensure_adm): Update svn_wc__db_scan_addition() call. * subversion/libsvn_wc/update_editor.c (create_tree_conflict, add_directory, add_file): Update svn_wc__db_scan_addition() calls. * subversion/libsvn_wc/info.c (build_info_for_node): Update svn_wc__db_scan_addition() call. * subversion/libsvn_wc/copy.c (copy_or_move): Update svn_wc__db_scan_addition() calls. * subversion/libsvn_wc/status.c (get_repos_root_url_relpath): Update svn_wc__db_scan_addition() call. * subversion/libsvn_wc/lock.c (child_is_disjoint): Update svn_wc__db_scan_addition() call. * subversion/libsvn_wc/entries.c (get_info_for_deleted, read_one_entry): Update svn_wc__db_scan_addition() calls. * subversion/libsvn_wc/node.c (svn_wc__internal_get_repos_info, svn_wc__node_get_repos_relpath, svn_wc__internal_get_copyfrom_info, svn_wc__internal_get_commit_base_rev, svn_wc__internal_get_origin): Update svn_wc__db_scan_addition() calls. Modified: subversion/trunk/subversion/libsvn_wc/adm_crawler.c subversion/trunk/subversion/libsvn_wc/adm_files.c subversion/trunk/subversion/libsvn_wc/adm_ops.c subversion/trunk/subversion/libsvn_wc/copy.c subversion/trunk/subversion/libsvn_wc/diff_editor.c subversion/trunk/subversion/libsvn_wc/diff_local.c subversion/trunk/subversion/libsvn_wc/entries.c subversion/trunk/subversion/libsvn_wc/info.c subversion/trunk/subversion/libsvn_wc/lock.c subversion/trunk/subversion/libsvn_wc/node.c subversion/trunk/subversion/libsvn_wc/props.c subversion/trunk/subversion/libsvn_wc/status.c subversion/trunk/subversion/libsvn_wc/update_editor.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 subversion/trunk/subversion/tests/libsvn_wc/db-test.c Modified: subversion/trunk/subversion/libsvn_wc/adm_crawler.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_crawler.c?rev=1151590&r1=1151589&r2=1151590&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/adm_crawler.c (original) +++ subversion/trunk/subversion/libsvn_wc/adm_crawler.c Wed Jul 27 18:59:52 2011 @@ -124,9 +124,9 @@ svn_wc_restore(svn_wc_context_t *wc_ctx, if (status == svn_wc__db_status_added) SVN_ERR(svn_wc__db_scan_addition(&status, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, - wc_ctx->db, local_abspath, - scratch_pool, scratch_pool)); + 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_copied @@ -385,7 +385,7 @@ report_revisions_and_depths(svn_wc__db_t if (wrk_status == svn_wc__db_status_added) SVN_ERR(svn_wc__db_scan_addition(&wrk_status, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - db, this_abspath, + NULL, NULL, db, this_abspath, iterpool, iterpool)); if (wrk_status == svn_wc__db_status_normal @@ -736,7 +736,7 @@ svn_wc_crawl_revisions5(svn_wc_context_t if (wrk_status == svn_wc__db_status_added) SVN_ERR(svn_wc__db_scan_addition(&wrk_status, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, db, local_abspath, scratch_pool, scratch_pool)); Modified: subversion/trunk/subversion/libsvn_wc/adm_files.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_files.c?rev=1151590&r1=1151589&r2=1151590&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/adm_files.c (original) +++ subversion/trunk/subversion/libsvn_wc/adm_files.c Wed Jul 27 18:59:52 2011 @@ -484,8 +484,8 @@ svn_wc__internal_ensure_adm(svn_wc__db_t &db_repos_relpath, &db_repos_root_url, &db_repos_uuid, - NULL, NULL, NULL, NULL, - db, local_abspath, + NULL, NULL, NULL, NULL, NULL, + NULL, db, local_abspath, scratch_pool, scratch_pool)); else SVN_ERR(svn_wc__db_scan_base_repos(&db_repos_relpath, Modified: subversion/trunk/subversion/libsvn_wc/adm_ops.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_ops.c?rev=1151590&r1=1151589&r2=1151590&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/adm_ops.c (original) +++ subversion/trunk/subversion/libsvn_wc/adm_ops.c Wed Jul 27 18:59:52 2011 @@ -834,7 +834,7 @@ check_can_add_to_parent(const char **rep if (parent_status == svn_wc__db_status_added) SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, repos_root_url, repos_uuid, NULL, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, db, parent_abspath, result_pool, scratch_pool)); else Modified: subversion/trunk/subversion/libsvn_wc/copy.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/copy.c?rev=1151590&r1=1151589&r2=1151590&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/copy.c (original) +++ subversion/trunk/subversion/libsvn_wc/copy.c Wed Jul 27 18:59:52 2011 @@ -642,7 +642,7 @@ copy_or_move(svn_wc_context_t *wc_ctx, SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, &src_repos_root_url, &src_repos_uuid, NULL, NULL, NULL, - NULL, + NULL, NULL, NULL, db, src_abspath, scratch_pool, scratch_pool)); else @@ -659,7 +659,7 @@ copy_or_move(svn_wc_context_t *wc_ctx, SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, &dst_repos_root_url, &dst_repos_uuid, NULL, NULL, NULL, - NULL, + NULL, NULL, NULL, db, dstdir_abspath, scratch_pool, scratch_pool)); else Modified: subversion/trunk/subversion/libsvn_wc/diff_editor.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/diff_editor.c?rev=1151590&r1=1151589&r2=1151590&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/diff_editor.c (original) +++ subversion/trunk/subversion/libsvn_wc/diff_editor.c Wed Jul 27 18:59:52 2011 @@ -569,7 +569,7 @@ file_diff(struct edit_baton *eb, if (status == svn_wc__db_status_added) SVN_ERR(svn_wc__db_scan_addition(&status, NULL, NULL, NULL, NULL, &original_repos_relpath, NULL, NULL, - NULL, db, local_abspath, + NULL, NULL, NULL, db, local_abspath, scratch_pool, scratch_pool)); /* A wc-wc diff of replaced files actually shows a diff against the @@ -959,8 +959,8 @@ report_wc_file_as_added(struct edit_bato if (status == svn_wc__db_status_added) SVN_ERR(svn_wc__db_scan_addition(&status, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, db, local_abspath, - scratch_pool, scratch_pool)); + NULL, NULL, NULL, NULL, NULL, db, + local_abspath, scratch_pool, scratch_pool)); /* We can't show additions for files that don't exist. */ SVN_ERR_ASSERT(status != svn_wc__db_status_deleted || eb->use_text_base); @@ -1659,7 +1659,7 @@ close_file(void *file_baton, if (status == svn_wc__db_status_added) SVN_ERR(svn_wc__db_scan_addition(&status, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, eb->db, + NULL, NULL, NULL, NULL, NULL, eb->db, fb->local_abspath, scratch_pool, scratch_pool)); Modified: subversion/trunk/subversion/libsvn_wc/diff_local.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/diff_local.c?rev=1151590&r1=1151589&r2=1151590&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/diff_local.c (original) +++ subversion/trunk/subversion/libsvn_wc/diff_local.c Wed Jul 27 18:59:52 2011 @@ -205,7 +205,7 @@ file_diff(struct diff_baton *eb, if (status == svn_wc__db_status_added) SVN_ERR(svn_wc__db_scan_addition(&status, NULL, NULL, NULL, NULL, &original_repos_relpath, NULL, NULL, - NULL, db, local_abspath, + NULL, NULL, NULL, db, local_abspath, scratch_pool, scratch_pool)); Modified: subversion/trunk/subversion/libsvn_wc/entries.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/entries.c?rev=1151590&r1=1151589&r2=1151590&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/entries.c (original) +++ subversion/trunk/subversion/libsvn_wc/entries.c Wed Jul 27 18:59:52 2011 @@ -285,7 +285,7 @@ get_info_for_deleted(svn_wc_entry_t *ent &parent_repos_relpath, &entry->repos, &entry->uuid, - NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, db, parent_abspath, result_pool, scratch_pool)); @@ -615,6 +615,7 @@ read_one_entry(const svn_wc_entry_t **ne &scanned_original_relpath, NULL, NULL, /* original_root|uuid */ &original_revision, + NULL, NULL, db, entry_abspath, result_pool, scratch_pool)); @@ -716,9 +717,8 @@ read_one_entry(const svn_wc_entry_t **ne NULL, NULL, NULL, &parent_repos_relpath, &parent_root_url, - NULL, NULL, - db, - parent_abspath, + NULL, NULL, NULL, NULL, + db, parent_abspath, scratch_pool, scratch_pool); if (err) Modified: subversion/trunk/subversion/libsvn_wc/info.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/info.c?rev=1151590&r1=1151589&r2=1151590&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/info.c (original) +++ subversion/trunk/subversion/libsvn_wc/info.c Wed Jul 27 18:59:52 2011 @@ -153,7 +153,7 @@ build_info_for_node(svn_wc__info2_t **in SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, &repos_relpath, &tmpinfo->repos_root_URL, &tmpinfo->repos_UUID, - NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, db, local_abspath, result_pool, scratch_pool)); @@ -214,7 +214,7 @@ build_info_for_node(svn_wc__info2_t **in &tmpinfo->repos_root_URL, &tmpinfo->repos_UUID, NULL, NULL, NULL, - &tmpinfo->rev, + &tmpinfo->rev, NULL, NULL, db, added_abspath, result_pool, scratch_pool)); Modified: subversion/trunk/subversion/libsvn_wc/lock.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/lock.c?rev=1151590&r1=1151589&r2=1151590&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/lock.c (original) +++ subversion/trunk/subversion/libsvn_wc/lock.c Wed Jul 27 18:59:52 2011 @@ -1104,7 +1104,7 @@ child_is_disjoint(svn_boolean_t *disjoin SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, &parent_repos_relpath, &parent_repos_root, &parent_repos_uuid, - NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, db, parent_abspath, scratch_pool, scratch_pool)); else Modified: subversion/trunk/subversion/libsvn_wc/node.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/node.c?rev=1151590&r1=1151589&r2=1151590&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/node.c (original) +++ subversion/trunk/subversion/libsvn_wc/node.c Wed Jul 27 18:59:52 2011 @@ -193,7 +193,7 @@ svn_wc__internal_get_repos_info(const ch else if (wrk_del_abspath) SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, repos_root_url, repos_uuid, - NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, db, svn_dirent_dirname( wrk_del_abspath, scratch_pool), @@ -205,7 +205,7 @@ svn_wc__internal_get_repos_info(const ch repository location by scanning up the tree. */ SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, repos_root_url, repos_uuid, - NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, db, local_abspath, result_pool, scratch_pool)); } @@ -381,7 +381,7 @@ svn_wc__node_get_repos_relpath(const cha { SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, repos_relpath, NULL, NULL, NULL, NULL, - NULL, NULL, + NULL, NULL, NULL, NULL, wc_ctx->db, local_abspath, result_pool, scratch_pool)); } @@ -527,8 +527,8 @@ svn_wc__internal_get_copyfrom_info(const SVN_ERR(svn_wc__db_scan_addition(&status, &op_root_abspath, NULL, NULL, NULL, &original_repos_relpath, &original_root_url, NULL, - &original_revision, db, local_abspath, - result_pool, scratch_pool)); + &original_revision, NULL, NULL, db, + local_abspath, result_pool, scratch_pool)); if (status == svn_wc__db_status_copied || status == svn_wc__db_status_moved_here) { @@ -977,7 +977,7 @@ svn_wc__internal_get_commit_base_rev(svn 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, - db, local_abspath, + NULL, NULL, db, local_abspath, scratch_pool, scratch_pool)); @@ -999,7 +999,7 @@ svn_wc__internal_get_commit_base_rev(svn * revision. */ SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - commit_base_revision, + commit_base_revision, NULL, NULL, db, svn_dirent_dirname(work_del_abspath, scratch_pool), @@ -1394,8 +1394,8 @@ svn_wc__internal_get_origin(svn_boolean_ SVN_ERR(svn_wc__db_scan_addition(&status, &op_root_abspath, NULL, NULL, NULL, &original_repos_relpath, repos_root_url, - repos_uuid, - revision, db, local_abspath, + repos_uuid, revision, NULL, NULL, + db, local_abspath, result_pool, scratch_pool)); if (status == svn_wc__db_status_added) Modified: subversion/trunk/subversion/libsvn_wc/props.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/props.c?rev=1151590&r1=1151589&r2=1151590&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/props.c (original) +++ subversion/trunk/subversion/libsvn_wc/props.c Wed Jul 27 18:59:52 2011 @@ -1929,7 +1929,7 @@ svn_wc__get_pristine_props(apr_hash_t ** while a simple add does not. */ SVN_ERR(svn_wc__db_scan_addition(&status, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, db, local_abspath, scratch_pool, scratch_pool)); } Modified: subversion/trunk/subversion/libsvn_wc/status.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/status.c?rev=1151590&r1=1151589&r2=1151590&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/status.c (original) +++ subversion/trunk/subversion/libsvn_wc/status.c Wed Jul 27 18:59:52 2011 @@ -336,7 +336,7 @@ get_repos_root_url_relpath(const char ** SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, repos_relpath, repos_root_url, repos_uuid, NULL, NULL, NULL, NULL, - db, local_abspath, + NULL, NULL, db, local_abspath, result_pool, scratch_pool)); } else if (info->have_base) Modified: subversion/trunk/subversion/libsvn_wc/update_editor.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=1151590&r1=1151589&r2=1151590&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/update_editor.c (original) +++ subversion/trunk/subversion/libsvn_wc/update_editor.c Wed Jul 27 18:59:52 2011 @@ -1300,8 +1300,8 @@ create_tree_conflict(svn_wc_conflict_des SVN_ERR(svn_wc__db_scan_addition(&added_status, NULL, &added_repos_relpath, &repos_root_url, - NULL, NULL, NULL, NULL, NULL, - eb->db, local_abspath, + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, eb->db, local_abspath, result_pool, scratch_pool)); /* This better really be an added status. */ @@ -2128,7 +2128,7 @@ add_directory(const char *path, /* Is the local add a copy? */ if (status == svn_wc__db_status_added) SVN_ERR(svn_wc__db_scan_addition(&add_status, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, eb->db, db->local_abspath, pool, pool)); @@ -3155,7 +3155,7 @@ add_file(const char *path, /* Is the local node a copy or move */ if (status == svn_wc__db_status_added) SVN_ERR(svn_wc__db_scan_addition(&status, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, eb->db, fb->local_abspath, scratch_pool, scratch_pool)); Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1151590&r1=1151589&r2=1151590&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original) +++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Wed Jul 27 18:59:52 2011 @@ -1331,6 +1331,10 @@ WHERE wc_id = ?1 AND presence='normal' AND file_external IS NULL +-- STMT_SELECT_MOVED_FROM_RELPATH +SELECT local_relpath FROM nodes_current +WHERE wc_id = ?1 AND moved_to = ?2 + /* ------------------------------------------------------------------------- */ /* Queries for verification. */ Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1151590&r1=1151589&r2=1151590&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/wc_db.c (original) +++ subversion/trunk/subversion/libsvn_wc/wc_db.c Wed Jul 27 18:59:52 2011 @@ -366,6 +366,8 @@ scan_addition(svn_wc__db_status_t *statu const char **original_repos_relpath, apr_int64_t *original_repos_id, svn_revnum_t *original_revision, + const char **moved_from_abspath, + const char **delete_op_root_abspath, svn_wc__db_wcroot_t *wcroot, const char *local_relpath, apr_pool_t *result_pool, @@ -3343,7 +3345,7 @@ get_info_for_copy(apr_int64_t *copyfrom_ SVN_ERR(scan_addition(NULL, &op_root_relpath, NULL, NULL, /* repos_* */ copyfrom_relpath, copyfrom_id, copyfrom_rev, - wcroot, local_relpath, + NULL, NULL, wcroot, local_relpath, scratch_pool, scratch_pool)); if (*copyfrom_relpath) { @@ -3372,7 +3374,7 @@ get_info_for_copy(apr_int64_t *copyfrom_ SVN_ERR(scan_addition(NULL, &op_root_relpath, NULL, NULL, /* repos_* */ copyfrom_relpath, copyfrom_id, copyfrom_rev, - wcroot, parent_del_relpath, + NULL, NULL, wcroot, parent_del_relpath, scratch_pool, scratch_pool)); *copyfrom_relpath = svn_relpath_join(*copyfrom_relpath, @@ -7266,7 +7268,7 @@ read_url_txn(void *baton, if (status == svn_wc__db_status_added) { SVN_ERR(scan_addition(NULL, NULL, &repos_relpath, &repos_id, NULL, - NULL, NULL, wcroot, local_relpath, + NULL, NULL, NULL, NULL, wcroot, local_relpath, scratch_pool, scratch_pool)); } else if (status == svn_wc__db_status_deleted) @@ -7299,7 +7301,7 @@ read_url_txn(void *baton, scratch_pool); SVN_ERR(scan_addition(NULL, NULL, &repos_relpath, &repos_id, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, wcroot, work_relpath, scratch_pool, scratch_pool)); @@ -8048,7 +8050,7 @@ svn_wc__db_global_relocate(svn_wc__db_t if (status == svn_wc__db_status_added) { SVN_ERR(scan_addition(NULL, NULL, NULL, &rb.old_repos_id, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, wcroot, local_dir_relpath, scratch_pool, scratch_pool)); } @@ -8959,6 +8961,113 @@ svn_wc__db_scan_base_repos(const char ** } +/* A helper for scan_addition(). + * Compute moved-from information for the node at LOCAL_RELPATH which + * has been determined as having been moved-here. + * Return an appropriate status in *STATUS (usually "moved-here"). + * If MOVED_FROM_ABSPATH is not NULL, set *MOVED_FROM_ABSPATH to the + * absolute path of the move-source node in *MOVED_FROM_ABSPATH. + * If DELETE_OP_ROOT_ABSPATH is not NULL, set *DELETE_OP_ROOT_ABSPATH + * to the absolute path of the op-root of the delete-half of the move. + * If moved-from information cannot be derived, set both *MOVED_FROM_ABSPATH + * and *DELETE_OP_ROOT_ABSPATH to NULL, and return a "copied" status. + * COPY_OPT_ROOT_RELPATH is the relpath of the op-root of the copied-half + * of the move. */ +static svn_error_t * +get_moved_from_info(svn_wc__db_status_t *status, + const char **moved_from_abspath, + const char **delete_op_root_abspath, + const char *copy_op_root_relpath, + svn_wc__db_wcroot_t *wcroot, + const char *local_relpath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + svn_sqlite__stmt_t *stmt; + svn_boolean_t have_row; + + /* Run a query to get the moved-from path from the DB. */ + SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, + STMT_SELECT_MOVED_FROM_RELPATH)); + SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, copy_op_root_relpath)); + SVN_ERR(svn_sqlite__step(&have_row, stmt)); + + if (!have_row) + { + /* The move was only recorded at the copy-half, possibly because + * the move operation was interrupted mid-way between the copy + * and the delete. Treat this node as a normal copy. */ + *status = svn_wc__db_status_copied; + if (moved_from_abspath) + *moved_from_abspath = NULL; + if (delete_op_root_abspath) + *delete_op_root_abspath = NULL; + + SVN_ERR(svn_sqlite__reset(stmt)); + return SVN_NO_ERROR; + } + + /* It's a properly recorded move. */ + *status = svn_wc__db_status_moved_here; + + if (moved_from_abspath || delete_op_root_abspath) + { + const char *delete_op_root_relpath; + + /* The moved-from path from the DB is the relpath of + * the op_root of the delete-half of the move. */ + delete_op_root_relpath = svn_sqlite__column_text(stmt, 0, scratch_pool); + + /* Return the abspath of the op_root of the delete-half. */ + if (delete_op_root_abspath) + *delete_op_root_abspath = svn_dirent_join(wcroot->abspath, + delete_op_root_relpath, + result_pool); + + if (moved_from_abspath) + { + if (strcmp(copy_op_root_relpath, local_relpath) == 0) + { + /* LOCAL_RELPATH is the op_root of the copied-half of the + * move, so the correct MOVED_FROM_ABSPATH is the op-root + * of the delete-half. */ + *moved_from_abspath = svn_dirent_join(wcroot->abspath, + delete_op_root_relpath, + result_pool); + } + else + { + const char *child_relpath; + + /* LOCAL_RELPATH is a child that was copied along with the + * op_root of the copied-half of the move. Construct the + * corresponding path beneath the op_root of the delete-half. */ + + /* Grab the child path relative to the path of the + * copied-half's op_root. */ + child_relpath = svn_relpath_skip_ancestor(copy_op_root_relpath, + local_relpath); + + SVN_ERR_ASSERT(child_relpath && strlen(child_relpath) > 0); + + /* This join is valid because LOCAL_RELPATH has not been moved + * within the copied-half of the move yet -- else, it would + * be its own op_root. */ + *moved_from_abspath = svn_dirent_join( + wcroot->abspath, + svn_relpath_join(delete_op_root_relpath, + child_relpath, + scratch_pool), + result_pool); + } + } + } + + SVN_ERR(svn_sqlite__reset(stmt)); + + return SVN_NO_ERROR; +} + struct scan_addition_baton_t { svn_wc__db_status_t *status; @@ -8968,6 +9077,8 @@ struct scan_addition_baton_t const char **original_repos_relpath; apr_int64_t *original_repos_id; svn_revnum_t *original_revision; + const char **moved_from_abspath; + const char **delete_op_root_abspath; apr_pool_t *result_pool; }; @@ -9109,7 +9220,13 @@ scan_addition_txn(void *baton, if (sab->status) { if (svn_sqlite__column_boolean(stmt, 13 /* moved_here */)) - *sab->status = svn_wc__db_status_moved_here; + SVN_ERR(get_moved_from_info(sab->status, + sab->moved_from_abspath, + sab->delete_op_root_abspath, + current_relpath, wcroot, + local_relpath, + sab->result_pool, + scratch_pool)); else *sab->status = svn_wc__db_status_copied; } @@ -9225,6 +9342,8 @@ scan_addition(svn_wc__db_status_t *statu const char **original_repos_relpath, apr_int64_t *original_repos_id, svn_revnum_t *original_revision, + const char **moved_from_abspath, + const char **delete_op_root_abspath, svn_wc__db_wcroot_t *wcroot, const char *local_relpath, apr_pool_t *result_pool, @@ -9239,6 +9358,8 @@ scan_addition(svn_wc__db_status_t *statu sab.original_repos_relpath = original_repos_relpath; sab.original_repos_id = original_repos_id; sab.original_revision = original_revision; + sab.moved_from_abspath = moved_from_abspath; + sab.delete_op_root_abspath = delete_op_root_abspath; sab.result_pool = result_pool; return svn_error_trace(svn_wc__db_with_txn(wcroot, local_relpath, @@ -9257,6 +9378,8 @@ svn_wc__db_scan_addition(svn_wc__db_stat const char **original_root_url, const char **original_uuid, svn_revnum_t *original_revision, + const char **moved_from_abspath, + const char **delete_op_root_abspath, svn_wc__db_t *db, const char *local_abspath, apr_pool_t *result_pool, @@ -9280,7 +9403,8 @@ svn_wc__db_scan_addition(svn_wc__db_stat SVN_ERR(scan_addition(status, &op_root_relpath, repos_relpath, repos_id_p, original_repos_relpath, original_repos_id_p, - original_revision, wcroot, local_relpath, + original_revision, moved_from_abspath, + delete_op_root_abspath, wcroot, local_relpath, result_pool, scratch_pool)); if (op_root_abspath) Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=1151590&r1=1151589&r2=1151590&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/wc_db.h (original) +++ subversion/trunk/subversion/libsvn_wc/wc_db.h Wed Jul 27 18:59:52 2011 @@ -2416,6 +2416,11 @@ svn_wc__db_scan_base_repos(const char ** BASE node. And again, the REPOS_* values are implied by this node's position in the subtree under the ancestor unshadowed BASE node. ORIGINAL_* will indicate the source of the move. + Additionally, information about the local move source is provided. + If MOVED_FROM_ABSPATH is not NULL, set *MOVED_FROM_ABSPATH to the + absolute path of the move source node in the working copy. + If DELETE_OP_ROOT_ABSPATH is not NULL, set *DELETE_OP_ROOT_ABSPATH + to the absolute path of the op-root of the delete-half of the move. All OUT parameters may be NULL to indicate a lack of interest in that piece of information. @@ -2446,6 +2451,8 @@ svn_wc__db_scan_addition(svn_wc__db_stat const char **original_root_url, const char **original_uuid, svn_revnum_t *original_revision, + const char **moved_from_abspath, + const char **delete_op_root_abspath, svn_wc__db_t *db, const char *local_abspath, apr_pool_t *result_pool, Modified: subversion/trunk/subversion/tests/libsvn_wc/db-test.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_wc/db-test.c?rev=1151590&r1=1151589&r2=1151590&view=diff ============================================================================== --- subversion/trunk/subversion/tests/libsvn_wc/db-test.c (original) +++ subversion/trunk/subversion/tests/libsvn_wc/db-test.c Wed Jul 27 18:59:52 2011 @@ -228,6 +228,10 @@ static const char * const TESTING_DATA = " 1, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 2, " TIME_2s ", '" AUTHOR_2 "'," " 10, null, null, null);" "insert into nodes values (" + " 1, 'moved/file', 0, 'moved', 2, 'moved/file', 2, 'base-deleted'," + " 0, 'J/J-d', 'file', '()', null, '$sha1$" SHA1_1 "', null, 2, " TIME_2s ", '" AUTHOR_2 "'," + " 10, null, null, null);" + "insert into nodes values (" " 1, 'J/J-e', 1, 'J', null, null, null, 'normal'," " 0, 'other/place', 'dir', '()', null, null, null, null, null, null," " null, null, null, null);" @@ -888,6 +892,8 @@ test_scan_addition(apr_pool_t *pool) const char *original_root_url; const char *original_uuid; svn_revnum_t original_revision; + const char *moved_from_abspath; + const char *delete_op_root_abspath; SVN_ERR(create_open(&db, &local_abspath, "test_scan_addition", pool)); @@ -896,7 +902,7 @@ test_scan_addition(apr_pool_t *pool) &status, &op_root_abspath, &repos_relpath, &repos_root_url, &repos_uuid, &original_repos_relpath, &original_root_url, &original_uuid, - &original_revision, + &original_revision, NULL, NULL, db, svn_dirent_join(local_abspath, "J", pool), pool, pool)); SVN_TEST_ASSERT(status == svn_wc__db_status_added); @@ -914,7 +920,7 @@ test_scan_addition(apr_pool_t *pool) &status, &op_root_abspath, &repos_relpath, &repos_root_url, &repos_uuid, &original_repos_relpath, &original_root_url, &original_uuid, - &original_revision, + &original_revision, NULL, NULL, db, svn_dirent_join(local_abspath, "J/J-a", pool), pool, pool)); SVN_TEST_ASSERT(status == svn_wc__db_status_added); @@ -932,12 +938,16 @@ test_scan_addition(apr_pool_t *pool) &status, &op_root_abspath, &repos_relpath, &repos_root_url, &repos_uuid, &original_repos_relpath, &original_root_url, &original_uuid, - &original_revision, + &original_revision, &moved_from_abspath, &delete_op_root_abspath, db, svn_dirent_join(local_abspath, "J/J-d", pool), pool, pool)); SVN_TEST_ASSERT(status == svn_wc__db_status_moved_here); SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-d", op_root_abspath, pool)); + SVN_TEST_ASSERT(validate_abspath(local_abspath, "moved/file", + moved_from_abspath, pool)); + SVN_TEST_ASSERT(validate_abspath(local_abspath, "moved/file", + delete_op_root_abspath, pool)); SVN_TEST_STRING_ASSERT(repos_relpath, "J/J-d"); SVN_TEST_STRING_ASSERT(repos_root_url, ROOT_ONE); SVN_TEST_STRING_ASSERT(repos_uuid, UUID_ONE); @@ -951,7 +961,7 @@ test_scan_addition(apr_pool_t *pool) &status, &op_root_abspath, &repos_relpath, &repos_root_url, &repos_uuid, &original_repos_relpath, &original_root_url, &original_uuid, - &original_revision, + &original_revision, NULL, NULL, db, svn_dirent_join(local_abspath, "J/J-b", pool), pool, pool)); SVN_TEST_ASSERT(status == svn_wc__db_status_copied); @@ -970,7 +980,7 @@ test_scan_addition(apr_pool_t *pool) &status, &op_root_abspath, &repos_relpath, &repos_root_url, &repos_uuid, &original_repos_relpath, &original_root_url, &original_uuid, - &original_revision, + &original_revision, NULL, NULL, db, svn_dirent_join(local_abspath, "J/J-b/J-b-a", pool), pool, pool)); SVN_TEST_ASSERT(status == svn_wc__db_status_copied); @@ -989,7 +999,7 @@ test_scan_addition(apr_pool_t *pool) &status, &op_root_abspath, &repos_relpath, &repos_root_url, &repos_uuid, &original_repos_relpath, &original_root_url, &original_uuid, - &original_revision, + &original_revision, NULL, NULL, db, svn_dirent_join(local_abspath, "J/J-b/J-b-b", pool), pool, pool)); SVN_TEST_ASSERT(status == svn_wc__db_status_copied);