Author: philip
Date: Fri May 6 19:09:07 2011
New Revision: 1100338
URL: http://svn.apache.org/viewvc?rev=1100338&view=rev
Log:
Make delete remove actual nodes with tree conflicts, thus resolving them.
* subversion/libsvn_wc/wc_db.h
(svn_wc__db_base_add_file): Add insert_base_deleted parameter.
* subversion/libsvn_wc/wc_db.c
(struct insert_base_baton_t): Add member.
(insert_base_node): Insert base-deleted node.
(svn_wc__db_base_add_file): Add insert_base_deleted parameter.
(op_delete_txn): Delete actual nodes with tree conflicts.
* subversion/tests/libsvn_wc/db-test.c
(test_inserting_nodes): Adjust svn_wc__db_base_add_file call.
* subversion/libsvn_wc/update_editor.c
(add_directory): Set tree conflict after deleting directory.
(close_file): Use svn_wc__db_base_add_file to insert base-deleted
rather than calling svn_wc__db_op_delete.
* subversion/tests/cmdline/tree_conflict_tests.py
(query_absent_tree_conflicted_dir): Adjust expectations.
* subversion/tests/cmdline/changelist_tests.py
(tree_conflicts_and_changelists_on_commit2): Don't delete absent
dir, adjust expectations.
(tree_conflicts_and_changelists_on_commit3): Remove since it is now
equivalent to tree_conflicts_and_changelists_on_commit2.
* subversion/tests/libsvn_wc/op-depth-test.c
(do_delete): Add actual before and after parameters.
(test_op_delete): Adjust do_delete calls, add actual node test.
Modified:
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/cmdline/changelist_tests.py
subversion/trunk/subversion/tests/cmdline/tree_conflict_tests.py
subversion/trunk/subversion/tests/libsvn_wc/db-test.c
subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c
Modified: subversion/trunk/subversion/libsvn_wc/update_editor.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=1100338&r1=1100337&r2=1100338&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/update_editor.c Fri May 6 19:09:07
2011
@@ -2011,20 +2011,6 @@ add_directory(const char *path,
}
}
- if (tree_conflict != NULL)
- {
- /* Queue this conflict in the parent so that its descendants
- are skipped silently. */
- SVN_ERR(svn_wc__db_op_set_tree_conflict(eb->db, db->local_abspath,
- tree_conflict, pool));
-
- db->already_notified = TRUE;
-
- do_notification(eb, db->local_abspath, svn_node_dir,
- svn_wc_notify_tree_conflict, pool);
- }
-
-
SVN_ERR(svn_wc__db_temp_op_set_new_dir_to_incomplete(eb->db,
db->local_abspath,
db->new_relpath,
@@ -2054,6 +2040,21 @@ add_directory(const char *path,
pool));
}
+ if (tree_conflict != NULL)
+ {
+ /* Queue this conflict in the parent so that its descendants
+ are skipped silently. */
+ SVN_ERR(svn_wc__db_op_set_tree_conflict(eb->db, db->local_abspath,
+ tree_conflict, pool));
+
+ db->already_notified = TRUE;
+
+ do_notification(eb, db->local_abspath, svn_node_dir,
+ svn_wc_notify_tree_conflict, pool);
+ }
+
+
+
/* If this add was obstructed by dir scheduled for addition without
history let close_file() handle the notification because there
might be properties to deal with. If PATH was added inside a locally
@@ -3957,20 +3958,10 @@ close_file(void *file_baton,
(! fb->shadowed) && new_base_props,
new_actual_props,
keep_recorded_info,
+ (fb->shadowed && fb->obstruction_found),
all_work_items,
scratch_pool));
- /* ### We can't record an unversioned obstruction yet, so
- ### we record a delete instead, which will allow resolving the conflict
- ### to theirs with 'svn revert'. */
- if (fb->shadowed && fb->obstruction_found)
- {
- SVN_ERR(svn_wc__db_op_delete(eb->db, fb->local_abspath,
- NULL, NULL /* notification */,
- eb->cancel_func, eb->cancel_baton,
- scratch_pool));
- }
-
/* ### ugh. deal with preserving the file external value in the database.
### there is no official API, so we do it this way. maybe we should
### have a temp API into wc_db. */
Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1100338&r1=1100337&r2=1100338&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Fri May 6 19:09:07
2011
@@ -517,17 +517,6 @@ WHERE wc_id = ?1 AND (local_relpath = ?2
OR local_relpath LIKE ?3 ESCAPE '#')
AND kind = 'file'))
--- STMT_DELETE_ACTUAL_LEAVING_CHANGELIST_AND_CONFLICT
-DELETE FROM actual_node
-WHERE wc_id = ?1 AND (local_relpath = ?2 OR local_relpath LIKE ?3 ESCAPE '#')
- AND tree_conflict_data IS NULL
- AND (changelist IS NULL
- OR local_relpath NOT IN (SELECT local_relpath FROM nodes_current
- WHERE wc_id = ?1
- AND (local_relpath = ?2
- OR local_relpath LIKE ?3 ESCAPE '#')
- AND kind = 'file'))
-
-- STMT_CLEAR_ACTUAL_NODE_LEAVING_CHANGELIST
UPDATE actual_node
SET properties = NULL,
@@ -556,19 +545,6 @@ SET properties = NULL,
right_checksum = NULL
WHERE wc_id = ?1 AND (local_relpath = ?2 OR local_relpath LIKE ?3 ESCAPE '#')
--- STMT_CLEAR_ACTUAL_LEAVING_CHANGELIST_AND_CONFLICT
-UPDATE actual_node
-SET properties = NULL,
- text_mod = NULL,
- conflict_old = NULL,
- conflict_new = NULL,
- conflict_working = NULL,
- prop_reject = NULL,
- older_checksum = NULL,
- left_checksum = NULL,
- right_checksum = NULL
-WHERE wc_id = ?1 AND (local_relpath = ?2 OR local_relpath LIKE ?3 ESCAPE '#')
-
-- STMT_UPDATE_NODE_BASE_DEPTH
UPDATE nodes SET depth = ?3
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1100338&r1=1100337&r2=1100338&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Fri May 6 19:09:07 2011
@@ -178,6 +178,9 @@ typedef struct insert_base_baton_t {
/* maybe we should copy information from a previous record? */
svn_boolean_t keep_recorded_info;
+ /* insert a base-deleted working node as well as a base node */
+ svn_boolean_t insert_base_deleted;
+
/* may have work items to queue in this transaction */
const svn_skel_t *work_items;
@@ -886,6 +889,17 @@ insert_base_node(void *baton,
}
}
+ if (pibb->insert_base_deleted)
+ {
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+
STMT_INSERT_WORKING_NODE_FROM_BASE_COPY_PRESENCE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isit",
+ wcroot->wc_id, local_relpath,
+ relpath_depth(local_relpath),
+ presence_map, svn_wc__db_status_base_deleted));
+ SVN_ERR(svn_sqlite__step_done(stmt));
+ }
+
SVN_ERR(add_work_items(wcroot->sdb, pibb->work_items, scratch_pool));
return SVN_NO_ERROR;
@@ -1564,6 +1578,7 @@ svn_wc__db_base_add_file(svn_wc__db_t *d
svn_boolean_t update_actual_props,
apr_hash_t *new_actual_props,
svn_boolean_t keep_recorded_info,
+ svn_boolean_t insert_base_deleted,
const svn_skel_t *work_items,
apr_pool_t *scratch_pool)
{
@@ -1613,6 +1628,7 @@ svn_wc__db_base_add_file(svn_wc__db_t *d
}
ibb.keep_recorded_info = keep_recorded_info;
+ ibb.insert_base_deleted = insert_base_deleted;
/* ### hmm. if this used to be a directory, we should remove children.
### or maybe let caller deal with that, if there is a possibility
@@ -5207,13 +5223,13 @@ op_delete_txn(void *baton,
### I don't know why we leave tree conflicts. */
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_DELETE_ACTUAL_LEAVING_CHANGELIST_AND_CONFLICT));
+
STMT_DELETE_ACTUAL_NODE_LEAVING_CHANGELIST_RECURSIVE));
SVN_ERR(svn_sqlite__bindf(stmt, "iss",
wcroot->wc_id, local_relpath, like_arg));
SVN_ERR(svn_sqlite__step_done(stmt));
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_CLEAR_ACTUAL_LEAVING_CHANGELIST_AND_CONFLICT));
+ STMT_CLEAR_ACTUAL_NODE_LEAVING_CHANGELIST_RECURSIVE));
SVN_ERR(svn_sqlite__bindf(stmt, "iss",
wcroot->wc_id, local_relpath, like_arg));
SVN_ERR(svn_sqlite__step_done(stmt));
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=1100338&r1=1100337&r2=1100338&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Fri May 6 19:09:07 2011
@@ -517,6 +517,7 @@ svn_wc__db_base_add_file(svn_wc__db_t *d
svn_boolean_t update_actual_props,
apr_hash_t *new_actual_props,
svn_boolean_t keep_recorded_info,
+ svn_boolean_t insert_base_deleted,
const svn_skel_t *work_items,
apr_pool_t *scratch_pool);
Modified: subversion/trunk/subversion/tests/cmdline/changelist_tests.py
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/changelist_tests.py?rev=1100338&r1=1100337&r2=1100338&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/changelist_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/changelist_tests.py Fri May 6
19:09:07 2011
@@ -952,16 +952,6 @@ def tree_conflicts_and_changelists_on_co
svntest.actions.run_and_verify_status(wc_dir, expected_status)
# So far so good. We have a tree-conflict on an absent dir A/C.
- # To twist the situation a little, delete it with --keep-local.
- # The result is the unversioning of the tree-conflict, as bad as it gets.
- # ### Note: As tree-conflict behaviour changes, we might not be able
- # to produce such bad specimen with --keep-local or --force anymore.
- # The aim here is to tickle bail_on_tree_conflicted_children()'s
- # changelists if-clause in libsvn_client/commit_util.c.
- svntest.main.run_svn(None, 'delete', C, '--keep-local')
- expected_status.tweak('A/C', status='? ', copied=None, wc_rev=None)
-
- svntest.actions.run_and_verify_status(wc_dir, expected_status)
# Verify that the current situation does not commit.
expected_error = "svn: E155015: Aborting commit:.* remains in .*conflict";
@@ -991,88 +981,6 @@ def tree_conflicts_and_changelists_on_co
"list")
-def tree_conflicts_and_changelists_on_commit3(sbox):
- "more tree conflicts, changelists and commit"
-
- sbox.build()
- wc_dir = sbox.wc_dir
-
- iota = os.path.join(wc_dir, "iota")
- A = os.path.join(wc_dir, "A",)
- C = os.path.join(A, "C")
-
- # Make a tree-conflict on A/C:
- # Remove it, warp back, add a prop, update.
- svntest.main.run_svn(None, 'delete', C)
-
- expected_output = svntest.verify.UnorderedRegexOutput(
- ["Deleting.*" + re.escape(C)],
- False)
- svntest.actions.run_and_verify_svn(None, expected_output, [],
- 'commit', '-m', 'delete A/C', C)
-
- expected_output = svntest.verify.UnorderedRegexOutput(
- "A.*" + re.escape(C), False)
- svntest.actions.run_and_verify_svn(None, expected_output, [],
- 'update', C, "-r1")
-
- expected_output = svntest.verify.UnorderedRegexOutput(
- ".*'propname' set on '" + re.escape(C)
- + "'", False)
- svntest.actions.run_and_verify_svn(None, expected_output, [],
- 'propset', 'propname', 'propval', C)
-
- expected_output = svntest.verify.UnorderedRegexOutput(
- " C " + re.escape(C), False)
- svntest.actions.run_and_verify_svn(None, expected_output, [],
- 'update', wc_dir)
-
-
- expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
- expected_status.tweak('A/C', status='A ', copied='+',
- treeconflict='C', wc_rev='-')
-
- svntest.actions.run_and_verify_status(wc_dir, expected_status)
-
- # So far so good. We have a tree-conflict on an absent dir A/C.
- # To twist the situation a little, delete it with --force.
- # The result is the unversioning of the tree-conflict, as bad as it gets.
- # ### Note: As tree-conflict behaviour changes, we might not be able
- # to produce such bad specimen with --keep-local or --force anymore.
- # The aim here is to tickle bail_on_tree_conflicted_children()'s
- # changelists if-clause in libsvn_client/commit_util.c.
- svntest.main.run_svn(None, 'delete', C, '--force')
- expected_status.tweak('A/C', status='! ', copied=None, wc_rev=None)
-
- svntest.actions.run_and_verify_status(wc_dir, expected_status)
-
- # Verify that the current situation does not commit.
- expected_error = "svn: E155015: Aborting commit:.* remains in .*conflict";
-
- svntest.actions.run_and_verify_commit(wc_dir,
- None, None,
- expected_error,
- wc_dir)
-
- # Now try to commit with a changelist, not letting the
- # tree-conflict get in the way.
- svntest.main.file_append(iota, "More stuff in iota")
- svntest.main.run_svn(None, "changelist", "list", iota)
-
- expected_output = svntest.wc.State(wc_dir, {
- 'iota' : Item(verb='Sending'),
- })
-
- expected_status.tweak('iota', wc_rev=3, status=' ')
-
- svntest.actions.run_and_verify_commit(wc_dir,
- expected_output,
- expected_status,
- None,
- wc_dir,
- "--changelist",
- "list")
-
#----------------------------------------------------------------------
def move_keeps_changelist(sbox):
@@ -1221,7 +1129,6 @@ test_list = [ None,
update_with_changelists,
tree_conflicts_and_changelists_on_commit1,
tree_conflicts_and_changelists_on_commit2,
- tree_conflicts_and_changelists_on_commit3,
move_keeps_changelist,
move_added_keeps_changelist,
change_to_dir,
Modified: subversion/trunk/subversion/tests/cmdline/tree_conflict_tests.py
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/tree_conflict_tests.py?rev=1100338&r1=1100337&r2=1100338&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/tree_conflict_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/tree_conflict_tests.py Fri May 6
19:09:07 2011
@@ -951,11 +951,10 @@ def query_absent_tree_conflicted_dir(sbo
'delete', C_path, '--keep-local')
expected_status.tweak('A/C', status='D ')
- expected_status.tweak('A/C/C', status='? ', copied=None, wc_rev=None)
+ expected_status.remove('A/C/C')
run_and_verify_status(wc_dir, expected_status)
# Try to access the absent tree-conflict as explicit target.
- # They should succeed without error. We don't care what they return.
# These used to fail like this:
## CMD: svn status -v -u -q
## [...]
@@ -967,14 +966,14 @@ def query_absent_tree_conflicted_dir(sbo
## subversion/libsvn_wc/wc_db.c:3288: (apr_err=155035)
## svn: Expected node '/.../tree_conflict_tests-20/A/C' to be added.
- # using status:
+ # A/C/C is now unversioned, using status:
expected_output = wc.State(wc_dir, {
- 'A/C/C' : Item(status='? ', treeconflict='C'),
})
run_and_verify_status(C_C_path, expected_output)
# using info:
- run_and_verify_svn(None, None, [], 'info', C_C_path)
+ run_and_verify_svn(None, None, ".*W155010.*The node.*was not found.*",
+ 'info', C_C_path)
#----------------------------------------------------------------------
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=1100338&r1=1100337&r2=1100338&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/db-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/db-test.c Fri May 6 19:09:07
2011
@@ -693,7 +693,7 @@ test_inserting_nodes(apr_pool_t *pool)
props,
1, TIME_1a, AUTHOR_1,
checksum,
- NULL, NULL, FALSE, NULL, FALSE, NULL,
+ NULL, NULL, FALSE, NULL, FALSE, FALSE, NULL,
pool));
/* Create a new symlink node. */
Modified: subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c?rev=1100338&r1=1100337&r2=1100338&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Fri May 6
19:09:07 2011
@@ -2789,17 +2789,22 @@ static svn_error_t *
do_delete(svn_test__sandbox_t *b,
const char *local_relpath,
nodes_row_t *before,
- nodes_row_t *after)
+ nodes_row_t *after,
+ actual_row_t *actual_before,
+ actual_row_t *actual_after)
{
const char *local_abspath = wc_path(b, local_relpath);
SVN_ERR(insert_dirs(b, before));
+ SVN_ERR(insert_actual(b, actual_before));
SVN_ERR(check_db_rows(b, "", before));
+ SVN_ERR(check_db_actual(b, actual_before));
SVN_ERR(svn_wc__db_op_delete(b->wc_ctx->db, local_abspath,
NULL, NULL /* notification */,
NULL, NULL /* cancellation */,
b->pool));
SVN_ERR(check_db_rows(b, "", after));
+ SVN_ERR(check_db_actual(b, actual_after));
return SVN_NO_ERROR;
}
@@ -2833,8 +2838,8 @@ test_op_delete(const svn_test_opts_t *op
{ 1, "A/B", "base-deleted", NO_COPY_FROM },
{ 0 }
};
- SVN_ERR(do_delete(&b, "A", before1, after));
- SVN_ERR(do_delete(&b, "A", before2, after));
+ SVN_ERR(do_delete(&b, "A", before1, after, NULL, NULL));
+ SVN_ERR(do_delete(&b, "A", before2, after, NULL, NULL));
}
{
@@ -2850,7 +2855,7 @@ test_op_delete(const svn_test_opts_t *op
{ 0, "A", "normal", 5, "A" },
{ 0 }
};
- SVN_ERR(do_delete(&b, "A/B", before, after));
+ SVN_ERR(do_delete(&b, "A/B", before, after, NULL, NULL));
}
{
@@ -2888,8 +2893,8 @@ test_op_delete(const svn_test_opts_t *op
{ 1, "A/B/C", "base-deleted", NO_COPY_FROM },
{ 0 }
};
- SVN_ERR(do_delete(&b, "A/B", before, after1));
- SVN_ERR(do_delete(&b, "A", before, after2));
+ SVN_ERR(do_delete(&b, "A/B", before, after1, NULL, NULL));
+ SVN_ERR(do_delete(&b, "A", before, after2, NULL, NULL));
}
{
@@ -2913,7 +2918,7 @@ test_op_delete(const svn_test_opts_t *op
{ 1, "A/B/C", "base-deleted", NO_COPY_FROM },
{ 0 }
};
- SVN_ERR(do_delete(&b, "A", before, after));
+ SVN_ERR(do_delete(&b, "A", before, after, NULL, NULL));
}
{
@@ -2959,9 +2964,39 @@ test_op_delete(const svn_test_opts_t *op
{ 1, "A/B/C/D", "base-deleted", NO_COPY_FROM },
{ 0 }
};
- SVN_ERR(do_delete(&b, "A/B/C/D", state1, state2));
- SVN_ERR(do_delete(&b, "A/B", state2, state3));
- SVN_ERR(do_delete(&b, "A", state3, state4));
+ SVN_ERR(do_delete(&b, "A/B/C/D", state1, state2, NULL, NULL));
+ SVN_ERR(do_delete(&b, "A/B", state2, state3, NULL, NULL));
+ SVN_ERR(do_delete(&b, "A", state3, state4, NULL, NULL));
+ }
+
+ {
+ nodes_row_t before[] = {
+ { 0, "", "normal", 5, "" },
+ { 0, "A", "normal", 5, "" },
+ { 0, "A/f", "normal", 5, "" },
+ { 2, "A/B", "normal", 5, "" },
+ { 0 }
+ };
+ nodes_row_t after[] = {
+ { 0, "", "normal", 5, "" },
+ { 0, "A", "normal", 5, "" },
+ { 0, "A/f", "normal", 5, "" },
+ { 1, "A", "base-deleted", NO_COPY_FROM},
+ { 1, "A/f", "base-deleted", NO_COPY_FROM},
+ { 0 }
+ };
+ actual_row_t before_actual[] = {
+ { "A", NULL },
+ { "A/f", "qq" },
+ { "A/B", NULL },
+ { "A/B/C", NULL },
+ { 0 },
+ };
+ actual_row_t after_actual[] = {
+ { "A/f", "qq" },
+ { 0 },
+ };
+ SVN_ERR(do_delete(&b, "A", before, after, before_actual, after_actual));
}
return SVN_NO_ERROR;