Author: rhuijben
Date: Sat Jan 19 21:49:03 2013
New Revision: 1435722
URL: http://svn.apache.org/viewvc?rev=1435722&view=rev
Log:
Make the update editor install a 'not-present' node when deleting a switched
subpath as part of the update. This fixes issue #4295, by making missing nodes
reappear on future updates.
* subversion/libsvn_wc/update_editor.c
(delete_entry): Detect when deleting a node that is switched vs its parent,
and in this specific case install a not present node so future updates
will restore possible missing children.
* subversion/tests/cmdline/update_tests.py
(update_removes_switched): Extend test to also cover issue #4295.
Modified:
subversion/trunk/subversion/libsvn_wc/update_editor.c
subversion/trunk/subversion/tests/cmdline/update_tests.py
Modified: subversion/trunk/subversion/libsvn_wc/update_editor.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=1435722&r1=1435721&r2=1435722&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/update_editor.c Sat Jan 19 21:49:03
2013
@@ -1652,6 +1652,7 @@ delete_entry(const char *path,
svn_wc__db_status_t base_status;
apr_pool_t *scratch_pool;
svn_boolean_t deleting_target;
+ svn_boolean_t deleting_switched;
svn_boolean_t keep_as_working = FALSE;
svn_boolean_t queue_deletes = TRUE;
@@ -1708,6 +1709,18 @@ delete_entry(const char *path,
eb->db, local_abspath,
scratch_pool, scratch_pool));
+ if (pb->old_repos_relpath && repos_relpath)
+ {
+ const char *expected_name;
+
+ expected_name = svn_relpath_skip_ancestor(pb->old_repos_relpath,
+ repos_relpath);
+
+ deleting_switched = (!expected_name || strcmp(expected_name, base) != 0);
+ }
+ else
+ deleting_switched = FALSE;
+
/* Is this path a conflict victim? */
if (conflicted)
SVN_ERR(node_already_conflicted(&conflicted, eb->db, local_abspath,
@@ -1830,7 +1843,7 @@ delete_entry(const char *path,
If the thing being deleted is the *target* of this update, then
we need to recreate a 'deleted' entry, so that the parent can give
accurate reports about itself in the future. */
- if (! deleting_target)
+ if (! deleting_target && ! deleting_switched)
{
/* Delete, and do not leave a not-present node. */
SVN_ERR(svn_wc__db_base_remove(eb->db, local_abspath,
@@ -1847,7 +1860,13 @@ delete_entry(const char *path,
*eb->target_revision,
tree_conflict, NULL,
scratch_pool));
- eb->target_deleted = TRUE;
+ if (deleting_target)
+ eb->target_deleted = TRUE;
+ else
+ {
+ /* Don't remove the not-present marker at the final bump */
+ SVN_ERR(remember_skipped_tree(eb, local_abspath, pool));
+ }
}
SVN_ERR(svn_wc__wq_run(eb->db, pb->local_abspath,
Modified: subversion/trunk/subversion/tests/cmdline/update_tests.py
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/update_tests.py?rev=1435722&r1=1435721&r2=1435722&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/update_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/update_tests.py Sat Jan 19
21:49:03 2013
@@ -6201,41 +6201,41 @@ def update_removes_switched(sbox):
None,
expected_status)
- #expected_output = svntest.wc.State(wc_dir, {
- # 'B' : Item(status='A '),
- # 'B/lambda' : Item(status='A '),
- # 'B/E' : Item(status='A '),
- # 'B/E/alpha' : Item(status='A '),
- # 'B/E/beta' : Item(status='A '),
- # 'B/F' : Item(status='A '),
- #})
- #expected_status = svntest.wc.State(wc_dir, {
- # '' : Item(status=' ', wc_rev='3'),
- # 'D' : Item(status=' ', wc_rev='3'),
- # 'D/G' : Item(status=' ', wc_rev='3'),
- # 'D/G/rho' : Item(status=' ', wc_rev='3'),
- # 'D/G/pi' : Item(status=' ', wc_rev='3'),
- # 'D/G/tau' : Item(status=' ', wc_rev='3'),
- # 'D/H' : Item(status=' ', wc_rev='3'),
- # 'D/H/omega' : Item(status=' ', wc_rev='3'),
- # 'D/H/chi' : Item(status=' ', wc_rev='3'),
- # 'D/H/psi' : Item(status=' ', wc_rev='3'),
- # 'D/gamma' : Item(status=' ', wc_rev='3'),
- # 'B' : Item(status=' ', wc_rev='3'),
- # 'B/E' : Item(status=' ', wc_rev='3'),
- # 'B/E/alpha' : Item(status=' ', wc_rev='3'),
- # 'B/E/beta' : Item(status=' ', wc_rev='3'),
- # 'B/F' : Item(status=' ', wc_rev='3'),
- # 'B/lambda' : Item(status=' ', wc_rev='3'),
- # 'C' : Item(status=' ', wc_rev='3'),
- # 'mu' : Item(status=' ', wc_rev='3'),
- #})
- #
- ## But I call it XFail that the node is not brought back in by this update
- #svntest.actions.run_and_verify_update(wc_dir,
- # expected_output,
- # None,
- # None)
+ expected_output = svntest.wc.State(wc_dir, {
+ 'B' : Item(status='A '),
+ 'B/lambda' : Item(status='A '),
+ 'B/E' : Item(status='A '),
+ 'B/E/alpha' : Item(status='A '),
+ 'B/E/beta' : Item(status='A '),
+ 'B/F' : Item(status='A '),
+ })
+ expected_status = svntest.wc.State(wc_dir, {
+ '' : Item(status=' ', wc_rev='3'),
+ 'D' : Item(status=' ', wc_rev='3'),
+ 'D/G' : Item(status=' ', wc_rev='3'),
+ 'D/G/rho' : Item(status=' ', wc_rev='3'),
+ 'D/G/pi' : Item(status=' ', wc_rev='3'),
+ 'D/G/tau' : Item(status=' ', wc_rev='3'),
+ 'D/H' : Item(status=' ', wc_rev='3'),
+ 'D/H/omega' : Item(status=' ', wc_rev='3'),
+ 'D/H/chi' : Item(status=' ', wc_rev='3'),
+ 'D/H/psi' : Item(status=' ', wc_rev='3'),
+ 'D/gamma' : Item(status=' ', wc_rev='3'),
+ 'B' : Item(status=' ', wc_rev='3'),
+ 'B/E' : Item(status=' ', wc_rev='3'),
+ 'B/E/alpha' : Item(status=' ', wc_rev='3'),
+ 'B/E/beta' : Item(status=' ', wc_rev='3'),
+ 'B/F' : Item(status=' ', wc_rev='3'),
+ 'B/lambda' : Item(status=' ', wc_rev='3'),
+ 'C' : Item(status=' ', wc_rev='3'),
+ 'mu' : Item(status=' ', wc_rev='3'),
+ })
+
+ # But I call it XFail that the node is not brought back in by this update
+ svntest.actions.run_and_verify_update(wc_dir,
+ expected_output,
+ None,
+ None)
#######################################################################
# Run the tests