You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2013/06/11 13:48:46 UTC
svn commit: r1491756 - in /subversion/trunk/subversion: libsvn_client/
libsvn_wc/ tests/cmdline/ tests/libsvn_wc/
Author: rhuijben
Date: Tue Jun 11 11:48:45 2013
New Revision: 1491756
URL: http://svn.apache.org/r1491756
Log:
Fix issue #4364: Correctly remove the stale entries from the lock table when
committing deletions.
* subversion/libsvn_client/commit.c
(post_process_commit_item): always pass the flag to remove locks for deleted
and replaced items.
* subversion/libsvn_wc/wc-queries.sql
Add a new query which removes all lock rows recursively for a node.
* subversion/libsvn_wc/wc_db.h
(svn_wc__db_base_remove): Add a new parameter remove_locks to recursively
remove the lock rows.
* subversion/libsvn_wc/wc_db.c
(svn_wc__db_base_remove): Forward the new remove_locks parameter to
db_base_remove.
(db_base_remove): Add and implement remove_locks.
(commit_node): Also remove the locks recursively for subnodes of the
current node.
(bump_node_revision): Pass FALSE for remove_locks to get the old default
behaviour.
* subversion/libsvn_wc/adm_ops.c
(process_committed_leaf): In the shortcut for deleted nodes, pass TRUE to
remove the locks recursively.
* subversion/libsvn_wc/crop.c
(crop_children): Pass FALSE for remove_locks to get the old default
behaviour.
* subversion/libsvn_wc/externals.c
(svn_wc__external_remove): Pass FALSE for remove_locks to get the old
default behaviour.
* subversion/libsvn_wc/update_editor.c
(delete_entry, close_edit): Pass FALSE for remove_locks to get the old
default behaviour.
* subversion/libsvn_wc/workqueue.c
(run_base_remove): Pass FALSE for remove_locks to get the old default
behaviour.
* subversion/tests/libsvn_wc/op-depth-test.c
(base_dir_insert_remove): Pass FALSE for remove_locks to get the old default
behaviour.
* subversion/tests/cmdline/lock_tests.py
(def drop_locks_on_parent_deletion): Provide a regression test which catches
reappearing locks.
Patch by: Markus Schaber <m.schaber{_AT_}codesys.com>
(minor tweaks by me)
Modified:
subversion/trunk/subversion/libsvn_client/commit.c
subversion/trunk/subversion/libsvn_wc/adm_ops.c
subversion/trunk/subversion/libsvn_wc/crop.c
subversion/trunk/subversion/libsvn_wc/externals.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/libsvn_wc/workqueue.c
subversion/trunk/subversion/tests/cmdline/lock_tests.py
subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c
Modified: subversion/trunk/subversion/libsvn_client/commit.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/commit.c?rev=1491756&r1=1491755&r2=1491756&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/commit.c (original)
+++ subversion/trunk/subversion/libsvn_client/commit.c Tue Jun 11 11:48:45 2013
@@ -240,6 +240,13 @@ post_process_commit_item(svn_wc_committe
remove_lock = (! keep_locks && (item->state_flags
& SVN_CLIENT_COMMIT_ITEM_LOCK_TOKEN));
+ /* When the node was deleted (or replaced), we need to always remove the
+ locks, as they're invalidated on the server. We cannot honor the
+ SVN_CLIENT_COMMIT_ITEM_LOCK_TOKEN flag here because it does not tell
+ us whether we have locked children. */
+ if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)
+ remove_lock = TRUE;
+
return svn_wc_queue_committed3(queue, wc_ctx, item->path,
loop_recurse, item->incoming_prop_changes,
remove_lock, !keep_changelists,
Modified: subversion/trunk/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_ops.c?rev=1491756&r1=1491755&r2=1491756&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/trunk/subversion/libsvn_wc/adm_ops.c Tue Jun 11 11:48:45 2013
@@ -148,6 +148,7 @@ process_committed_leaf(svn_wc__db_t *db,
db, local_abspath,
FALSE /* keep_as_working */,
FALSE /* queue_deletes */,
+ TRUE /* remove_locks */,
(! via_recurse)
? new_revnum : SVN_INVALID_REVNUM,
NULL, NULL,
Modified: subversion/trunk/subversion/libsvn_wc/crop.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/crop.c?rev=1491756&r1=1491755&r2=1491756&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/crop.c (original)
+++ subversion/trunk/subversion/libsvn_wc/crop.c Tue Jun 11 11:48:45 2013
@@ -110,6 +110,7 @@ crop_children(svn_wc__db_t *db,
SVN_ERR(svn_wc__db_base_remove(db, child_abspath,
FALSE /* keep_as_working */,
FALSE /* queue_deletes */,
+ FALSE /* remove_locks */,
SVN_INVALID_REVNUM,
NULL, NULL, iterpool));
Modified: subversion/trunk/subversion/libsvn_wc/externals.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/externals.c?rev=1491756&r1=1491755&r2=1491756&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/externals.c (original)
+++ subversion/trunk/subversion/libsvn_wc/externals.c Tue Jun 11 11:48:45 2013
@@ -1413,6 +1413,7 @@ svn_wc__external_remove(svn_wc_context_t
SVN_ERR(svn_wc__db_base_remove(wc_ctx->db, local_abspath,
FALSE /* keep_as_working */,
TRUE /* queue_deletes */,
+ FALSE /* remove_locks */,
SVN_INVALID_REVNUM,
NULL, NULL, scratch_pool));
SVN_ERR(svn_wc__wq_run(wc_ctx->db, local_abspath,
Modified: subversion/trunk/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=1491756&r1=1491755&r2=1491756&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/update_editor.c Tue Jun 11 11:48:45 2013
@@ -1813,6 +1813,7 @@ delete_entry(const char *path,
SVN_ERR(svn_wc__db_base_remove(eb->db, local_abspath,
FALSE /* keep_as_working */,
FALSE /* queue_deletes */,
+ FALSE /* remove_locks */,
SVN_INVALID_REVNUM /* not_present_rev */,
NULL, NULL,
scratch_pool));
@@ -1909,7 +1910,7 @@ delete_entry(const char *path,
{
/* Delete, and do not leave a not-present node. */
SVN_ERR(svn_wc__db_base_remove(eb->db, local_abspath,
- keep_as_working, queue_deletes,
+ keep_as_working, queue_deletes, FALSE,
SVN_INVALID_REVNUM /* not_present_rev */,
tree_conflict, NULL,
scratch_pool));
@@ -1918,7 +1919,7 @@ delete_entry(const char *path,
{
/* Delete, leaving a not-present node. */
SVN_ERR(svn_wc__db_base_remove(eb->db, local_abspath,
- keep_as_working, queue_deletes,
+ keep_as_working, queue_deletes, FALSE,
*eb->target_revision,
tree_conflict, NULL,
scratch_pool));
@@ -4701,6 +4702,7 @@ close_edit(void *edit_baton,
SVN_ERR(svn_wc__db_base_remove(eb->db, eb->target_abspath,
FALSE /* keep_as_working */,
FALSE /* queue_deletes */,
+ FALSE /* remove_locks */,
SVN_INVALID_REVNUM,
NULL, NULL, 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=1491756&r1=1491755&r2=1491756&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Tue Jun 11 11:48:45 2013
@@ -472,6 +472,10 @@ WHERE wc_id = ?1
DELETE FROM lock
WHERE repos_id = ?1 AND repos_relpath = ?2
+-- STMT_DELETE_LOCK_RECURSIVELY
+DELETE FROM lock
+WHERE repos_id = ?1 AND (repos_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(repos_relpath, ?2))
+
-- STMT_CLEAR_BASE_NODE_RECURSIVE_DAV_CACHE
UPDATE nodes SET dav_cache = NULL
WHERE dav_cache IS NOT NULL AND wc_id = ?1 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=1491756&r1=1491755&r2=1491756&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Tue Jun 11 11:48:45 2013
@@ -2086,6 +2086,7 @@ db_base_remove(svn_wc__db_wcroot_t *wcro
svn_wc__db_t *db, /* For checking conflicts */
svn_boolean_t keep_as_working,
svn_boolean_t queue_deletes,
+ svn_boolean_t remove_locks,
svn_revnum_t not_present_revision,
svn_skel_t *conflict,
svn_skel_t *work_items,
@@ -2106,6 +2107,16 @@ db_base_remove(svn_wc__db_wcroot_t *wcro
wcroot, local_relpath,
scratch_pool, scratch_pool));
+ if (remove_locks)
+ {
+ svn_sqlite__stmt_t *lock_stmt;
+
+ SVN_ERR(svn_sqlite__get_statement(&lock_stmt, wcroot->sdb,
+ STMT_DELETE_LOCK_RECURSIVELY));
+ SVN_ERR(svn_sqlite__bindf(lock_stmt, "is", repos_id, repos_relpath));
+ SVN_ERR(svn_sqlite__step_done(lock_stmt));
+ }
+
if (status == svn_wc__db_status_normal
&& keep_as_working)
{
@@ -2333,6 +2344,7 @@ svn_wc__db_base_remove(svn_wc__db_t *db,
const char *local_abspath,
svn_boolean_t keep_as_working,
svn_boolean_t queue_deletes,
+ svn_boolean_t remove_locks,
svn_revnum_t not_present_revision,
svn_skel_t *conflict,
svn_skel_t *work_items,
@@ -2349,7 +2361,7 @@ svn_wc__db_base_remove(svn_wc__db_t *db,
SVN_WC__DB_WITH_TXN(db_base_remove(wcroot, local_relpath,
db, keep_as_working, queue_deletes,
- not_present_revision,
+ remove_locks, not_present_revision,
conflict, work_items, scratch_pool),
wcroot);
@@ -10814,7 +10826,7 @@ commit_node(svn_wc__db_wcroot_t *wcroot,
svn_sqlite__stmt_t *lock_stmt;
SVN_ERR(svn_sqlite__get_statement(&lock_stmt, wcroot->sdb,
- STMT_DELETE_LOCK));
+ STMT_DELETE_LOCK_RECURSIVELY));
SVN_ERR(svn_sqlite__bindf(lock_stmt, "is", repos_id, repos_relpath));
SVN_ERR(svn_sqlite__step_done(lock_stmt));
}
@@ -11058,7 +11070,7 @@ bump_node_revision(svn_wc__db_wcroot_t *
revision != new_rev)))
{
return svn_error_trace(db_base_remove(wcroot, local_relpath,
- db, FALSE, FALSE,
+ db, FALSE, FALSE, FALSE,
SVN_INVALID_REVNUM,
NULL, NULL, scratch_pool));
}
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=1491756&r1=1491755&r2=1491756&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Tue Jun 11 11:48:45 2013
@@ -702,6 +702,9 @@ svn_wc__db_base_add_not_present_node(svn
(With KEEP_AS_WORKING TRUE, this is a no-op, as everything is
automatically shadowed by the created copy)
+ If REMOVE_LOCKS is TRUE, all locks of this node and any subnodes
+ are also removed. This is to be done during commit of deleted nodes.
+
If NOT_PRESENT_REVISION specifies a valid revision a not-present
node is installed in BASE node with kind NOT_PRESENT_KIND after
deleting.
@@ -715,6 +718,7 @@ svn_wc__db_base_remove(svn_wc__db_t *db,
const char *local_abspath,
svn_boolean_t keep_as_working,
svn_boolean_t queue_deletes,
+ svn_boolean_t remove_locks,
svn_revnum_t not_present_revision,
svn_skel_t *conflict,
svn_skel_t *work_items,
Modified: subversion/trunk/subversion/libsvn_wc/workqueue.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/workqueue.c?rev=1491756&r1=1491755&r2=1491756&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/trunk/subversion/libsvn_wc/workqueue.c Tue Jun 11 11:48:45 2013
@@ -143,6 +143,7 @@ run_base_remove(work_item_baton_t *wqb,
SVN_ERR(svn_wc__db_base_remove(db, local_abspath,
FALSE /* keep_as_working */,
TRUE /* queue_deletes */,
+ FALSE /* remove_locks */,
not_present_rev,
NULL, NULL, scratch_pool));
Modified: subversion/trunk/subversion/tests/cmdline/lock_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/lock_tests.py?rev=1491756&r1=1491755&r2=1491756&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/lock_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/lock_tests.py Tue Jun 11 11:48:45 2013
@@ -1840,6 +1840,56 @@ def commit_stolen_lock(sbox):
err_re,
wc_dir)
+# When removing directories, the locks of contained files were not
+# correctly removed from the working copy database, thus they later
+# magically reappeared when new files or directories with the same
+# pathes were added.
+@Issue(4364)
+def drop_locks_on_parent_deletion(sbox):
+ "drop locks when the parent is deleted"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ # lock some files, and remove them.
+ sbox.simple_lock('A/B/lambda')
+ sbox.simple_lock('A/B/E/alpha')
+ sbox.simple_lock('A/B/E/beta')
+ sbox.simple_rm('A/B')
+
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.remove_subtree('A/B')
+
+ svntest.actions.run_and_verify_commit(wc_dir,
+ [],
+ expected_status,
+ None,
+ wc_dir)
+
+ # now re-add entities to the deleted pathes.
+ sbox.simple_mkdir('A/B')
+ sbox.simple_add_text('new file replacing old file', 'A/B/lambda')
+ sbox.simple_add_text('file replacing former dir', 'A/B/F')
+ # The bug also resurrected locks on directories when their path
+ # matched a former file.
+ sbox.simple_mkdir('A/B/E', 'A/B/E/alpha')
+
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak('A/B',
+ 'A/B/E',
+ 'A/B/E/alpha',
+ 'A/B/F',
+ 'A/B/lambda',
+ wc_rev='3')
+ expected_status.remove('A/B/E/beta')
+
+ svntest.actions.run_and_verify_commit(wc_dir,
+ [],
+ expected_status,
+ None,
+ wc_dir)
+
+
########################################################################
# Run the tests
@@ -1892,6 +1942,7 @@ test_list = [ None,
locks_stick_over_switch,
lock_unlock_deleted,
commit_stolen_lock,
+ drop_locks_on_parent_deletion,
]
if __name__ == '__main__':
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=1491756&r1=1491755&r2=1491756&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Tue Jun 11 11:48:45 2013
@@ -1109,6 +1109,7 @@ base_dir_insert_remove(svn_test__sandbox
SVN_ERR(svn_wc__db_base_remove(b->wc_ctx->db, dir_abspath,
FALSE /* keep_as_Working */,
FALSE /* queue_deletes */,
+ FALSE /* remove_locks */,
SVN_INVALID_REVNUM,
NULL, NULL, b->pool));
SVN_ERR(svn_wc__wq_run(b->wc_ctx->db, dir_abspath,