Author: gstein
Date: Fri Mar 12 01:27:41 2010
New Revision: 922105
URL: http://svn.apache.org/viewvc?rev=922105&view=rev
Log:
Fix a property handling bug introduced in r909093: a rename was switched
to the wrong ordering. A test was added to demonstrate the old problem,
and to verify the fix.
Some other rename/deletion simplifications were made.
* subversion/libsvn_wc/workqueue.c:
(move_if_present): add docstring
(run_delete): switch to using move_if_present, as it will do the ENOENT
testing. remove the ENOENT testing from the remove_file2 calls, since
it already has a parameter to do exactly that(!)
* subversion/tests/cmdline/prop_tests.py:
(rm_of_replaced_files): new test to ensure props on a replaced file are
restored after a deletion of the replacement
(test_list): add the new test
Modified:
subversion/trunk/subversion/libsvn_wc/workqueue.c
subversion/trunk/subversion/tests/cmdline/prop_tests.py
Modified: subversion/trunk/subversion/libsvn_wc/workqueue.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/workqueue.c?rev=922105&r1=922104&r2=922105&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/trunk/subversion/libsvn_wc/workqueue.c Fri Mar 12 01:27:41 2010
@@ -117,7 +117,9 @@ copy_and_translate(svn_wc__db_t *db,
}
-/* */
+/* If SOURCE_ABSPATH is present, then move it to DEST_ABSPATH. Ignore any
+ ENOENT message for a missing source, which may indicate the move has
+ already been performed. */
static svn_error_t *
move_if_present(const char *source_abspath,
const char *dest_abspath,
@@ -1757,16 +1759,12 @@ run_delete(svn_wc__db_t *db,
if (was_replaced && was_copied)
{
const char *props_base, *props_revert;
- svn_error_t *err;
SVN_ERR(svn_wc__prop_path(&props_base, local_abspath, kind,
svn_wc__props_base, scratch_pool));
SVN_ERR(svn_wc__prop_path(&props_revert, local_abspath, kind,
svn_wc__props_revert, scratch_pool));
- err = svn_io_file_rename(props_base, props_revert, scratch_pool);
- if (err && !APR_STATUS_IS_ENOENT(err->apr_err))
- return svn_error_quick_wrap(err, _("Can't move source to dest"));
- svn_error_clear(err);
+ SVN_ERR(move_if_present(props_revert, props_base, scratch_pool));
if (kind != svn_wc__db_kind_dir)
{
@@ -1774,33 +1772,22 @@ run_delete(svn_wc__db_t *db,
SVN_ERR(svn_wc__text_base_path(&text_base, db, local_abspath,
FALSE, scratch_pool));
-
SVN_ERR(svn_wc__text_revert_path(&text_revert, db,
local_abspath, scratch_pool));
- err = svn_io_file_rename(text_revert, text_base, scratch_pool);
- if (err && !APR_STATUS_IS_ENOENT(err->apr_err))
- return svn_error_quick_wrap(err, _("Can't move source to dest"));
- svn_error_clear(err);
+ SVN_ERR(move_if_present(text_revert, text_base, scratch_pool));
}
}
if (was_added)
{
const char *props_base, *props_working;
- svn_error_t *err;
SVN_ERR(svn_wc__prop_path(&props_base, local_abspath, kind,
svn_wc__props_base, scratch_pool));
SVN_ERR(svn_wc__prop_path(&props_working, local_abspath, kind,
svn_wc__props_working, scratch_pool));
- err = svn_io_remove_file2(props_base, TRUE, scratch_pool);
- if (err && !APR_STATUS_IS_ENOENT(err->apr_err))
- return svn_error_quick_wrap(err, _("Can't move source to dest"));
- svn_error_clear(err);
- err = svn_io_remove_file2(props_working, TRUE, scratch_pool);
- if (err && !APR_STATUS_IS_ENOENT(err->apr_err))
- return svn_error_quick_wrap(err, _("Can't move source to dest"));
- svn_error_clear(err);
+ SVN_ERR(svn_io_remove_file2(props_base, TRUE, scratch_pool));
+ SVN_ERR(svn_io_remove_file2(props_working, TRUE, scratch_pool));
}
return SVN_NO_ERROR;
Modified: subversion/trunk/subversion/tests/cmdline/prop_tests.py
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/prop_tests.py?rev=922105&r1=922104&r2=922105&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/prop_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/prop_tests.py Fri Mar 12 01:27:41
2010
@@ -1734,6 +1734,51 @@ def post_revprop_change_hook(sbox):
'ps', '--revprop', '-r0', 'p', 'v',
wc_dir)
+def rm_of_replaced_file(sbox):
+ """properties after a removal of a replaced file"""
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ # Add some properties to iota and mu
+ iota_path = os.path.join(wc_dir, 'iota')
+ svntest.main.run_svn(None, 'propset', 'red', 'rojo', iota_path)
+ svntest.main.run_svn(None, 'propset', 'blue', 'lagoon', iota_path)
+
+ mu_path = os.path.join(wc_dir, 'A', 'mu')
+ svntest.main.run_svn(None, 'propset', 'yellow', 'submarine', mu_path)
+ svntest.main.run_svn(None, 'propset', 'orange', 'toothpick', mu_path)
+
+ svntest.main.run_svn(None, 'ci', '-m', 'log message', wc_dir)
+
+ # Copy iota over the top of mu
+ svntest.main.run_svn(None, 'rm', mu_path)
+ svntest.main.run_svn(None, 'cp', iota_path, mu_path)
+
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.tweak('iota', props={'red': 'rojo', 'blue': 'lagoon'})
+ expected_disk.tweak('A/mu', props={'red': 'rojo', 'blue': 'lagoon'},
+ contents="This is the file 'iota'.\n")
+ actual_disk_tree = svntest.tree.build_tree_from_wc(wc_dir, 1)
+ svntest.tree.compare_trees("disk", actual_disk_tree,
+ expected_disk.old_tree())
+
+ # Remove the copy. Properties should go back to mu's original props.
+ svntest.main.run_svn(None, 'rm', '--force', mu_path)
+
+ exit_code, output, errput = svntest.main.run_svn(None,
+ 'proplist', '-v', mu_path)
+ expected_output = svntest.verify.UnorderedRegexOutput([
+ 'Properties on',
+ ' yellow',
+ ' submarine',
+ ' orange',
+ ' toothpick',
+ ])
+ svntest.verify.compare_and_display_lines('message', 'label',
+ expected_output, output)
+ svntest.verify.verify_exit_code(None, exit_code, 0)
+
########################################################################
# Run the tests
@@ -1775,6 +1820,7 @@ test_list = [ None,
added_moved_file,
delete_nonexistent_property,
XFail(post_revprop_change_hook, svntest.main.is_ra_type_dav),
+ rm_of_replaced_file,
]
if __name__ == '__main__':