Author: ehu
Date: Fri Oct 15 14:59:20 2010
New Revision: 1022959
URL: http://svn.apache.org/viewvc?rev=1022959&view=rev
Log:
Simplify revert processing: all reverts go through revert_admin_things(),
instead of sometimes routing through
svn_wc__internal_remove_from_revision_control() and sometimes through
revert_admin_things().
* subversion/tests/libsvn_wc/revert_tests.py
(status_of_missing_dir_after_revert_replaced_with_history): Adjust
expected output to see only the notification of the op_root,
same as normal/non-replacing adds.
* subversion/libsvn_wc/adm_ops.c
(revert_admin_things): Add revert_root parameter to pass around to
the wc_db functions which need it now.
(revert_entry): Take a revert_root parameter to pass to
revert_admin_things(). Don't use the 'remove from revision control'
APIs anymore for added and copied paths, instead use the
'revert admin things' route for all cases.
(revert_internal): Take a revert_root parameter to pass around.
To mimic svn_wc__internal_remove_from_version_control(), disable
notifications on copy/move-reversals. Like the aforementioned function,
call svn_wc__adm_destroy() after reverting an added (not replaced)
directory.
* subversion/libsvn_wc/workqueue.c
(run_revert): Move decision to call svn_wc__db_temp_op_remove_working()
to svn_wc__wq_add_revert().
(svn_wc__wq_add_revert): Take a revert_root parameter. In the issue #2101
handling, check explicitly for deletes (wich is what the issue is about),
instead of the node type. Implement logic to determine whether
run_revert() should call svn_wc__db_temp_op_remove_working().
Modified:
subversion/trunk/subversion/libsvn_wc/adm_ops.c
subversion/trunk/subversion/libsvn_wc/workqueue.c
subversion/trunk/subversion/libsvn_wc/workqueue.h
subversion/trunk/subversion/tests/cmdline/revert_tests.py
Modified: subversion/trunk/subversion/libsvn_wc/adm_ops.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_ops.c?rev=1022959&r1=1022958&r2=1022959&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/trunk/subversion/libsvn_wc/adm_ops.c Fri Oct 15 14:59:20 2010
@@ -1250,11 +1250,13 @@ svn_wc__register_file_external(svn_wc_co
static svn_error_t *
revert_admin_things(svn_boolean_t *reverted,
svn_wc__db_t *db,
+ const char *revert_root,
const char *local_abspath,
svn_boolean_t use_commit_times,
apr_pool_t *pool)
{
- SVN_ERR(svn_wc__wq_add_revert(reverted, db, local_abspath, use_commit_times,
+ SVN_ERR(svn_wc__wq_add_revert(reverted, db,
+ revert_root, local_abspath, use_commit_times,
pool));
SVN_ERR(svn_wc__wq_run(db, local_abspath, NULL, NULL, pool));
@@ -1277,6 +1279,7 @@ revert_admin_things(svn_boolean_t *rever
static svn_error_t *
revert_entry(svn_depth_t *depth,
svn_wc__db_t *db,
+ const char *revert_root,
const char *local_abspath,
svn_node_kind_t disk_kind,
svn_boolean_t use_commit_times,
@@ -1326,89 +1329,9 @@ revert_entry(svn_depth_t *depth,
else
is_add_root = FALSE;
- /* Additions. */
- if (!replaced
- && is_add_root)
- {
- const char *repos_relpath;
- const char *repos_root_url;
- const char *repos_uuid;
- /* Before removing item from revision control, notice if the
- BASE_NODE is in a 'not-present' state. */
- svn_boolean_t was_not_present = FALSE;
-
- /* NOTE: if WAS_NOT_PRESENT gets set, then we have BASE nodes.
- The code below will then figure out the repository information, so
- that we can later insert a node for the same repository. */
-
- if (have_base
- && base_status == svn_wc__db_status_not_present)
- {
- /* Remember the BASE revision. (already handled) */
- /* Remember the repository this node is associated with. */
-
- was_not_present = TRUE;
-
- SVN_ERR(svn_wc__db_scan_base_repos(&repos_relpath,
- &repos_root_url,
- &repos_uuid,
- db, local_abspath,
- pool, pool));
- }
-
- /* ### much of this is probably bullshit. we should be able to just
- ### remove the WORKING and ACTUAL rows, and be done. but we're
- ### not quite there yet, so nodes get fully removed and then
- ### shoved back into the database. this is why we need to record
- ### the repository information, and the BASE revision. */
-
- if (kind == svn_wc__db_kind_file
- || kind == svn_wc__db_kind_dir)
- {
- SVN_ERR(svn_wc__internal_remove_from_revision_control(db,
- local_abspath,
- FALSE, FALSE,
- cancel_func,
- cancel_baton,
- pool));
- }
- else /* Else it's `none', or something exotic like a symlink... */
- {
- return svn_error_createf(SVN_ERR_NODE_UNKNOWN_KIND, NULL,
- _("Unknown or unexpected kind for path "
- "'%s'"),
- svn_dirent_local_style(local_abspath,
- pool));
-
- }
-
- /* Recursivity is taken care of by svn_wc_remove_from_revision_control,
- and we've definitely reverted PATH at this point. */
- *depth = svn_depth_empty;
- reverted = TRUE;
-
- /* If the removed item was *also* in a 'not-present' state, make
- sure we leave a not-present node behind */
- if (was_not_present)
- {
- SVN_ERR(svn_wc__db_base_add_not_present_node(
- db, local_abspath,
- repos_relpath, repos_root_url, repos_uuid,
- base_revision,
- base_kind,
- NULL, NULL,
- pool));
- }
- }
- /* Regular prop and text edit. */
- /* Deletions and replacements. */
- else if (status == svn_wc__db_status_normal
- || status == svn_wc__db_status_deleted
- || replaced
- || (status == svn_wc__db_status_added && !is_add_root))
{
/* Revert the prop and text mods (if any). */
- SVN_ERR(revert_admin_things(&reverted, db, local_abspath,
+ SVN_ERR(revert_admin_things(&reverted, db, revert_root, local_abspath,
use_commit_times, pool));
/* Force recursion on replaced directories. */
@@ -1496,6 +1419,7 @@ verify_revert_depth(svn_wc__db_t *db,
documentation. */
static svn_error_t *
revert_internal(svn_wc__db_t *db,
+ const char *revert_root,
const char *local_abspath,
svn_depth_t depth,
svn_boolean_t use_commit_times,
@@ -1510,7 +1434,9 @@ revert_internal(svn_wc__db_t *db,
svn_wc__db_status_t status;
svn_wc__db_kind_t db_kind;
svn_boolean_t unversioned;
+ svn_boolean_t have_base;
const svn_wc_conflict_description2_t *tree_conflict;
+ const char *op_root_abspath = NULL;
svn_error_t *err;
/* Check cancellation here, so recursive calls get checked early. */
@@ -1523,7 +1449,7 @@ revert_internal(svn_wc__db_t *db,
err = svn_wc__db_read_info(&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, &have_base, NULL, NULL,
NULL,
db, local_abspath, pool, pool);
@@ -1595,17 +1521,17 @@ revert_internal(svn_wc__db_t *db,
_("Cannot revert '%s': unsupported node kind in working copy"),
svn_dirent_local_style(local_abspath, pool));
+ if (status == svn_wc__db_status_added)
+ SVN_ERR(svn_wc__db_scan_addition(NULL, &op_root_abspath, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL,
+ db, local_abspath, pool, pool));
+
/* Safeguard 4: Make sure we don't revert deeper then asked */
if (status == svn_wc__db_status_added
&& db_kind == svn_wc__db_kind_dir
&& depth >= svn_depth_empty
&& depth < svn_depth_infinity)
{
- const char *op_root_abspath;
- SVN_ERR(svn_wc__db_scan_addition(NULL, &op_root_abspath, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL,
- db, local_abspath, pool, pool));
-
/* If this node is an operation root for a copy/add, then reverting
it will change its descendants, if it has any. */
if (strcmp(local_abspath, op_root_abspath) == 0)
@@ -1634,7 +1560,7 @@ revert_internal(svn_wc__db_t *db,
/* Actually revert this entry. If this is a working copy root,
we provide a base_name from the parent path. */
if (!unversioned)
- SVN_ERR(revert_entry(&depth, db, local_abspath, disk_kind,
+ SVN_ERR(revert_entry(&depth, db, revert_root, local_abspath, disk_kind,
use_commit_times,
cancel_func, cancel_baton,
&reverted, pool));
@@ -1647,6 +1573,15 @@ revert_internal(svn_wc__db_t *db,
pool);
}
+
+ if (op_root_abspath && strcmp(local_abspath, op_root_abspath) == 0)
+ /* If this is a copy or add root, disable notifications for the children,
+ because wc-1.0 used to behave like that. */
+ {
+ notify_func = NULL;
+ notify_baton = NULL;
+ }
+
/* Finally, recurse if requested. */
if (!unversioned && db_kind == svn_wc__db_kind_dir && depth >
svn_depth_empty)
{
@@ -1690,7 +1625,7 @@ revert_internal(svn_wc__db_t *db,
continue;
/* Revert the entry. */
- SVN_ERR(revert_internal(db, node_abspath,
+ SVN_ERR(revert_internal(db, revert_root, node_abspath,
depth_under_here, use_commit_times,
changelist_hash, cancel_func, cancel_baton,
notify_func, notify_baton, iterpool));
@@ -1734,7 +1669,8 @@ revert_internal(svn_wc__db_t *db,
const svn_wc_conflict_description2_t *);
if (conflict->kind == svn_wc_conflict_kind_tree)
- SVN_ERR(revert_internal(db, conflict->local_abspath,
+ SVN_ERR(revert_internal(db, revert_root,
+ conflict->local_abspath,
svn_depth_empty,
use_commit_times, changelist_hash,
cancel_func, cancel_baton,
@@ -1747,6 +1683,14 @@ revert_internal(svn_wc__db_t *db,
svn_pool_destroy(iterpool);
}
+ if (! have_base && status == svn_wc__db_status_added
+ && db_kind == svn_wc__db_kind_dir)
+ {
+ /* Non-replacements have their admin area deleted. wc-1.0 */
+ SVN_ERR(svn_wc__adm_destroy(db, local_abspath,
+ cancel_func, cancel_baton, pool));
+ }
+
return SVN_NO_ERROR;
}
@@ -1769,7 +1713,7 @@ svn_wc_revert4(svn_wc_context_t *wc_ctx,
SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash, changelists, pool));
return svn_error_return(revert_internal(wc_ctx->db,
- local_abspath, depth,
+ local_abspath, local_abspath, depth,
use_commit_times, changelist_hash,
cancel_func, cancel_baton,
notify_func, notify_baton,
Modified: subversion/trunk/subversion/libsvn_wc/workqueue.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/workqueue.c?rev=1022959&r1=1022958&r2=1022959&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/trunk/subversion/libsvn_wc/workqueue.c Fri Oct 15 14:59:20 2010
@@ -186,14 +186,14 @@ run_revert(svn_wc__db_t *db,
const char *parent_abspath;
svn_boolean_t conflicted;
apr_int64_t val;
- svn_boolean_t is_wc_root;
svn_boolean_t reinstall_working;
+ svn_boolean_t remove_working;
/* We need a NUL-terminated path, so copy it out of the skel. */
local_abspath = apr_pstrmemdup(scratch_pool, arg1->data, arg1->len);
- /* ### OP_DEPTH legacy; to be removed. */
SVN_ERR(svn_skel__parse_int(&val, arg1->next, scratch_pool));
+ remove_working = (val != 0);
SVN_ERR(svn_skel__parse_int(&val, arg1->next->next, scratch_pool));
reinstall_working = (val != 0);
@@ -213,14 +213,11 @@ run_revert(svn_wc__db_t *db,
if (kind == svn_wc__db_kind_dir)
{
- SVN_ERR(svn_wc__db_is_wcroot(&is_wc_root, db, local_abspath,
- scratch_pool));
parent_abspath = local_abspath;
}
else
{
parent_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
- is_wc_root = FALSE; /* non-directories can't be roots */
}
if (conflicted)
@@ -294,26 +291,11 @@ run_revert(svn_wc__db_t *db,
}
- if (! is_wc_root) {
- /* A working copy root can't have a working node. Don't try removing. */
- const char *op_root_abspath = NULL;
-
-
-
- /* Remove the WORKING version of the node */
- /* If the node is not the operation root,
- we should not delete the working node */
- if (status == svn_wc__db_status_added)
- SVN_ERR(svn_wc__db_scan_addition(NULL, &op_root_abspath, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL,
- db, local_abspath,
- scratch_pool, scratch_pool));
-
- if (!op_root_abspath
- || (strcmp(op_root_abspath, local_abspath) == 0))
+ if (remove_working)
+ {
SVN_ERR(svn_wc__db_temp_op_remove_working(db, local_abspath,
scratch_pool));
- }
+ }
return SVN_NO_ERROR;
}
@@ -363,6 +345,7 @@ verify_pristine_present(svn_wc__db_t *db
svn_error_t *
svn_wc__wq_add_revert(svn_boolean_t *will_revert,
svn_wc__db_t *db,
+ const char *revert_root,
const char *local_abspath,
svn_boolean_t use_commit_times,
apr_pool_t *scratch_pool)
@@ -370,6 +353,7 @@ svn_wc__wq_add_revert(svn_boolean_t *wil
svn_wc__db_status_t status;
svn_wc__db_kind_t kind;
svn_boolean_t replaced;
+ svn_boolean_t remove_working = FALSE;
svn_boolean_t reinstall_working;
SVN_ERR(svn_wc__db_read_info(
@@ -380,8 +364,11 @@ svn_wc__wq_add_revert(svn_boolean_t *wil
db, local_abspath,
scratch_pool, scratch_pool));
- /* Special handling for issue #2101. */
- if (kind == svn_wc__db_kind_file)
+ /* Special handling for issue #2101, which is specifically
+ about reverting copies of 'deleted' files and dirs, being inserted
+ in the copy as a schedule-delete files, yet can't be reverted. */
+ if (kind == svn_wc__db_kind_file
+ && status == svn_wc__db_status_deleted)
SVN_ERR(verify_pristine_present(db, local_abspath, scratch_pool));
/* Gather a few items *before* the revert work-item has a chance to run.
@@ -447,6 +434,26 @@ svn_wc__wq_add_revert(svn_boolean_t *wil
*will_revert = *will_revert || reinstall_working;
}
+
+ if (status == svn_wc__db_status_added)
+ {
+ /* When looking at an added, non-replacing node, it's entry
+ will have to be removed after revert: if not, it'll look
+ like it's still under version control. */
+ const char *op_root_abspath;
+
+ SVN_ERR(svn_wc__db_scan_addition(NULL, &op_root_abspath, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL,
+ db, local_abspath,
+ scratch_pool, scratch_pool));
+
+ if (svn_dirent_is_ancestor(revert_root, op_root_abspath))
+ remove_working = TRUE;
+ }
+ else
+ remove_working = TRUE;
+
+
/* Don't even bother to queue a work item if there is nothing to do. */
if (*will_revert)
{
@@ -458,10 +465,7 @@ svn_wc__wq_add_revert(svn_boolean_t *wil
we only need the work_item to survive for the duration of wq_add. */
svn_skel__prepend_int(use_commit_times, work_item, scratch_pool);
svn_skel__prepend_int(reinstall_working, work_item, scratch_pool);
-
- /* ### OP_DEPTH The 'replaced' item is here for backward compat;
- the wq-consumer doesn't use this value anymore. */
- svn_skel__prepend_int(replaced, work_item, scratch_pool);
+ svn_skel__prepend_int(remove_working, work_item, scratch_pool);
svn_skel__prepend_str(local_abspath, work_item, scratch_pool);
svn_skel__prepend_str(OP_REVERT, work_item, scratch_pool);
Modified: subversion/trunk/subversion/libsvn_wc/workqueue.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/workqueue.h?rev=1022959&r1=1022958&r2=1022959&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/workqueue.h (original)
+++ subversion/trunk/subversion/libsvn_wc/workqueue.h Fri Oct 15 14:59:20 2010
@@ -188,10 +188,12 @@ svn_wc__wq_build_record_fileinfo(svn_ske
apr_pool_t *result_pool);
-/* Record a work item to revert LOCAL_ABSPATH. */
+/* Record a work item to revert LOCAL_ABSPATH;
+ REVERT_ROOT designates the root of the entire revert operation. */
svn_error_t *
svn_wc__wq_add_revert(svn_boolean_t *will_revert,
svn_wc__db_t *db,
+ const char *revert_root,
const char *local_abspath,
svn_boolean_t use_commit_times,
apr_pool_t *scratch_pool);
Modified: subversion/trunk/subversion/tests/cmdline/revert_tests.py
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/revert_tests.py?rev=1022959&r1=1022958&r2=1022959&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/revert_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/revert_tests.py Fri Oct 15
14:59:20 2010
@@ -847,15 +847,7 @@ def status_of_missing_dir_after_revert_r
dry_run = 0)
# now test if the revert works ok
- revert_paths = [G_path,
- os.path.join(G_path, 'alpha'),
- os.path.join(G_path, 'beta')]
-
- if svntest.main.wc_is_singledb(wc_dir):
- # These nodes are not lost in single-db
- revert_paths += [ os.path.join(G_path, 'pi'),
- os.path.join(G_path, 'rho'),
- os.path.join(G_path, 'tau')]
+ revert_paths = [G_path]
expected_output = svntest.verify.UnorderedOutput([
"Reverted '%s'\n" % path for path in revert_paths])