You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by gs...@apache.org on 2010/04/23 18:30:42 UTC
svn commit: r937358 - in /subversion/trunk/subversion: libsvn_wc/wc_db.c
tests/cmdline/schedule_tests.py
Author: gstein
Date: Fri Apr 23 16:30:42 2010
New Revision: 937358
URL: http://svn.apache.org/viewvc?rev=937358&view=rev
Log:
Be wary of obstructions in svn_wc__db_temp_op_delete. There is not enough
information to determine whether the node is an add or a copy/move and
whether this is the root of a copy/move. This information is needed to
properly mark the node for deletion. When the situation is detected, we
now raise SVN_ERR_WC_MISSING. This error will become moot when we reach
single-db mode.
* subversion/libsvn_wc/wc_db.c:
(db_working_get_status): removed, in favor of read_info
(svn_wc__db_temp_op_delete): use read_info, and let it throw
PATH_NOT_FOUND as appropriate, so we don't have to check for a BASE or
WORKING node. synthesize the old WORKING_NONE variable from the new
read_info data. adjust the conditionals a bit for the new status
values, and handle the special obstructed_add case. for
obstructed_delete (and regular delete), we just exit early.
* subversion/tests/cmdline/schedule_tests.py:
(unschedule_missing_added): add a comment explaining the failure
(test_list): mark the above as XFail
Modified:
subversion/trunk/subversion/libsvn_wc/wc_db.c
subversion/trunk/subversion/tests/cmdline/schedule_tests.py
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=937358&r1=937357&r2=937358&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Fri Apr 23 16:30:42 2010
@@ -2472,70 +2472,6 @@ svn_wc__db_base_get_info(svn_wc__db_stat
}
-/* A WORKING version of svn_wc__db_base_get_info, stripped down to
- just the status column.
-
- ### This function should not exist! What I really want is presence
- ### not status, and so it's a mistake to return an
- ### svn_wc__db_status_t here as it doesn't have quite the same
- ### meaning as status returned by other functions. I think I need
- ### to abandon this function and work out how to decode status back
- ### into presence :(
-*/
-static svn_error_t *
-db_working_get_status(svn_wc__db_status_t *status,
- svn_wc__db_t *db,
- const char *local_abspath,
- apr_pool_t *scratch_pool)
-{
- svn_wc__db_pdh_t *pdh;
- const char *local_relpath;
- svn_sqlite__stmt_t *stmt;
- svn_boolean_t have_row;
- svn_error_t *err = SVN_NO_ERROR;
-
- SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-
- SVN_ERR(parse_local_abspath(&pdh, &local_relpath, db, local_abspath,
- svn_sqlite__mode_readonly,
- scratch_pool, scratch_pool));
- VERIFY_USABLE_PDH(pdh);
-
- SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
- STMT_SELECT_WORKING_NODE));
- SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
-
- if (have_row)
- {
- svn_wc__db_kind_t node_kind = svn_sqlite__column_token(stmt, 1,
- kind_map);
-
- *status = svn_sqlite__column_token(stmt, 0, presence_map);
-
- if (node_kind == svn_wc__db_kind_subdir
- && *status == svn_wc__db_status_normal)
- {
- /* We're looking at the subdir record in the *parent* directory,
- which implies per-dir .svn subdirs. We should be looking
- at the subdir itself; therefore, it is missing or obstructed
- in some way. Inform the caller. */
- *status = svn_wc__db_status_obstructed;
- }
- }
- else
- {
- err = svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
- _("The node '%s' was not found."),
- svn_dirent_local_style(local_abspath,
- scratch_pool));
- }
-
-
- return svn_error_compose_create(err, svn_sqlite__reset(stmt));
-}
-
-
svn_error_t *
svn_wc__db_base_get_prop(const svn_string_t **propval,
svn_wc__db_t *db,
@@ -3854,6 +3790,7 @@ svn_wc__db_temp_op_delete(svn_wc__db_t *
svn_error_t *err;
svn_boolean_t base_none, working_none, new_working_none;
svn_wc__db_status_t base_status, working_status, new_working_status;
+ svn_boolean_t base_shadowed;
err = svn_wc__db_base_get_info(&base_status,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -3875,24 +3812,71 @@ svn_wc__db_temp_op_delete(svn_wc__db_t *
if (!base_none && base_status == svn_wc__db_status_absent)
return SVN_NO_ERROR; /* ### should return an error.... WHICH ONE? */
- err = db_working_get_status(&working_status,
- db, local_abspath, scratch_pool);
- if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+ /* No need to check for SVN_ERR_WC_PATH_NOT_FOUND. Something has to
+ be there for us to delete. */
+ SVN_ERR(svn_wc__db_read_info(&working_status, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, &base_shadowed, NULL, NULL,
+ db, local_abspath,
+ scratch_pool, scratch_pool));
+ if (working_status == svn_wc__db_status_deleted
+ || working_status == svn_wc__db_status_obstructed_delete)
{
- working_none = TRUE;
- svn_error_clear(err);
+ /* The node is already deleted. */
+ /* ### return an error? callers should know better. */
+ return SVN_NO_ERROR;
}
- else if (! err)
- working_none = FALSE;
- else
- return svn_error_return(err);
- if (base_none && working_none)
- return SVN_NO_ERROR; /* ### should return PATH_NOT_FOUND */
+ /* We must have a WORKING node if there is no BASE node (gotta have
+ something!). If there IS a BASE node, then we have a WORKING node
+ if BASE_SHADOWED is TRUE. */
+ working_none = !(base_none || base_shadowed);
new_working_none = working_none;
new_working_status = working_status;
- if (working_none)
+
+ if (working_status == svn_wc__db_status_normal
+ || working_status == svn_wc__db_status_not_present
+ || working_status == svn_wc__db_status_obstructed)
+ {
+ /* No structural changes (ie. no WORKING node). Mark the BASE node
+ as deleted. */
+
+ SVN_ERR_ASSERT(working_none);
+
+ new_working_none = FALSE;
+ new_working_status = svn_wc__db_status_base_deleted;
+ }
+ else if (working_status == svn_wc__db_status_obstructed_add)
+ {
+ /* There is a parent stub for some kind of addition.
+
+ ### we cannot tell if this is a local-add or a copied/moved-here.
+ ### when the latter case, if this node is the root of that
+ ### copy/move, then we just "revert" it. otherwise, we're deleting
+ ### a child of that copy/move and marked it as delete. and the
+ ### second proble: we also cannot tell whether this is the root
+ ### or not.
+ ###
+ ### return WC_MISSING here. we need that working copy metadata
+ ###
+ ### when we get to single-db, there are no "obstructed" status
+ ### codes, so this will magically work... */
+ SVN_ERR_ASSERT(!working_none);
+
+ return svn_error_createf(SVN_ERR_WC_MISSING, NULL,
+ _("The directory '%s' is missing and cannot "
+ "be marked for deletion."),
+ svn_dirent_local_style(local_abspath,
+ scratch_pool));
+ }
+ /* ### remaining states: added, absent, excluded, incomplete
+ ### the last three have debatable schedule-delete semantics,
+ ### and this code may need to change further, but I'm not
+ ### going to worry about it now
+ */
+ else if (working_none)
{
/* No structural changes */
if (base_status == svn_wc__db_status_normal
@@ -3904,15 +3888,13 @@ svn_wc__db_temp_op_delete(svn_wc__db_t *
new_working_status = svn_wc__db_status_base_deleted;
}
}
- else if ((working_status == svn_wc__db_status_normal
- || working_status == svn_wc__db_status_obstructed)
+ else if (working_status == svn_wc__db_status_added
&& (base_none || base_status == svn_wc__db_status_not_present))
{
- /* ADD */
+ /* ADD/COPY-HERE/MOVE-HERE. There is "no BASE node". */
svn_boolean_t add_or_root_of_copy;
- /* ### this fails for the status_obstructed case. */
SVN_ERR(is_add_or_root_of_copy(&add_or_root_of_copy,
db, local_abspath, scratch_pool));
if (add_or_root_of_copy)
@@ -3920,7 +3902,7 @@ svn_wc__db_temp_op_delete(svn_wc__db_t *
else
new_working_status = svn_wc__db_status_not_present;
}
- else if (working_status == svn_wc__db_status_normal)
+ else if (working_status == svn_wc__db_status_added)
{
/* DELETE + ADD */
svn_boolean_t add_or_root_of_copy;
@@ -5370,7 +5352,6 @@ svn_wc__db_scan_addition(svn_wc__db_stat
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
svn_wc__db_status_t presence;
- svn_boolean_t presence_is_normal;
/* ### is it faster to fetch fewer columns? */
SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
Modified: subversion/trunk/subversion/tests/cmdline/schedule_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/schedule_tests.py?rev=937358&r1=937357&r2=937358&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/schedule_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/schedule_tests.py Fri Apr 23 16:30:42 2010
@@ -453,6 +453,8 @@ def unschedule_missing_added(sbox):
# FILE1_PATH will throw an error. DIR1_PATH will not since the stub is
# still available in the parent directory.
svntest.main.run_svn(svntest.verify.AnyOutput, 'rm', file1_path)
+ ### actually, the stub does not provide enough information to revert
+ ### the addition, so this command will fail. marking as XFail
sbox.simple_rm(dir1_path)
sbox.simple_revert(file2_path, dir2_path)
@@ -656,7 +658,7 @@ test_list = [ None,
SkipUnless(revert_add_executable, svntest.main.is_posix_os),
revert_delete_files,
revert_delete_dirs,
- unschedule_missing_added,
+ XFail(unschedule_missing_added),
delete_missing,
revert_inside_newly_added_dir,
status_add_deleted_directory,