Author: stsp
Date: Tue Apr 10 16:49:27 2012
New Revision: 1311860
URL: http://svn.apache.org/viewvc?rev=1311860&view=rev
Log:
Properly show property modifications during 'svn diff --old X --new Y' if
there is a directory 'X/foo' and a file 'Y/foo', each with a set of properties.
* subversion/tests/cmdline/diff_tests.py
(diff_two_working_copies): Test the above scenario.
* subversion/libsvn_client/diff.c
(do_arbitrary_files_diff): New parameter ORIGINAL_PROPS_OVERRIDE. This is
required in the above scenario.
(arbitrary_diff_walker): When diffing a directory against a file, provide
the directory's props as 'original properties' to do_arbitrary_files_diff().
Pass NULL for the ORIGINAL_PROPS_OVERRIDE parameter in all other cases.
(do_arbitrary_nodes_diff): Pass NULL for ORIGINAL_PROPS_OVERRIDE.
Modified:
subversion/trunk/subversion/libsvn_client/diff.c
subversion/trunk/subversion/tests/cmdline/diff_tests.py
Modified: subversion/trunk/subversion/libsvn_client/diff.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/diff.c?rev=1311860&r1=1311859&r2=1311860&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/diff.c (original)
+++ subversion/trunk/subversion/libsvn_client/diff.c Tue Apr 10 16:49:27 2012
@@ -1807,13 +1807,20 @@ get_props(apr_hash_t **props,
* LOCAL_ABSPATH2, using the diff callbacks from CALLBACKS.
* Use PATH as the name passed to diff callbacks.
* FILE1_IS_EMPTY and FILE2_IS_EMPTY are used as hints which diff callback
- * function to use to compare the files (added/deleted/changed). */
+ * function to use to compare the files (added/deleted/changed).
+ *
+ * If ORIGINAL_PROPS_OVERRIDE is not NULL, use it as original properties
+ * instead of reading properties from LOCAL_ABSPATH1. This is required when
+ * a file replaces a directory, where LOCAL_ABSPATH1 is an empty file that
+ * file content must be diffed against, but properties to diff against come
+ * from the replaced directory. */
static svn_error_t *
do_arbitrary_files_diff(const char *local_abspath1,
const char *local_abspath2,
const char *path,
svn_boolean_t file1_is_empty,
svn_boolean_t file2_is_empty,
+ apr_hash_t *original_props_override,
const svn_wc_diff_callbacks4_t *callbacks,
struct diff_cmd_baton *diff_cmd_baton,
svn_client_ctx_t *ctx,
@@ -1837,8 +1844,11 @@ do_arbitrary_files_diff(const char *loca
{
/* Try to get properties from either file. It's OK if the files do not
* have properties, or if they are unversioned. */
- SVN_ERR(get_props(&original_props, local_abspath1, ctx->wc_ctx,
- scratch_pool, scratch_pool));
+ if (original_props_override)
+ original_props = original_props_override;
+ else
+ SVN_ERR(get_props(&original_props, local_abspath1, ctx->wc_ctx,
+ scratch_pool, scratch_pool));
SVN_ERR(get_props(&modified_props, local_abspath2, ctx->wc_ctx,
scratch_pool, scratch_pool));
}
@@ -2140,26 +2150,32 @@ arbitrary_diff_walker(void *baton, const
SVN_ERR(do_arbitrary_files_diff(child1_abspath, b->empty_file_abspath,
svn_relpath_join(child_relpath, name,
iterpool),
- FALSE, TRUE,
+ FALSE, TRUE, NULL,
b->callbacks, b->callback_baton,
b->ctx, iterpool));
/* Files that exist only in dirents2. */
if (dirent2->kind == svn_node_file &&
(dirent1->kind == svn_node_dir || dirent1->kind == svn_node_none))
- SVN_ERR(do_arbitrary_files_diff(b->empty_file_abspath, child2_abspath,
- svn_relpath_join(child_relpath, name,
- iterpool),
- TRUE, FALSE,
- b->callbacks, b->callback_baton,
- b->ctx, iterpool));
+ {
+ apr_hash_t *original_props;
+
+ SVN_ERR(get_props(&original_props, child1_abspath, b->ctx->wc_ctx,
+ scratch_pool, scratch_pool));
+ SVN_ERR(do_arbitrary_files_diff(b->empty_file_abspath,
child2_abspath,
+ svn_relpath_join(child_relpath, name,
+ iterpool),
+ TRUE, FALSE, original_props,
+ b->callbacks, b->callback_baton,
+ b->ctx, iterpool));
+ }
/* Files that exist in dirents1 and dirents2. */
if (dirent1->kind == svn_node_file && dirent2->kind == svn_node_file)
SVN_ERR(do_arbitrary_files_diff(child1_abspath, child2_abspath,
svn_relpath_join(child_relpath, name,
iterpool),
- FALSE, FALSE,
+ FALSE, FALSE, NULL,
b->callbacks, b->callback_baton,
b->ctx, scratch_pool));
@@ -2205,7 +2221,7 @@ do_arbitrary_nodes_diff(const char *loca
SVN_ERR(do_arbitrary_files_diff(local_abspath1, local_abspath2,
svn_dirent_basename(local_abspath2,
scratch_pool),
- FALSE, FALSE,
+ FALSE, FALSE, NULL,
callbacks, callback_baton,
ctx, scratch_pool));
else if (kind1 == svn_node_dir)
Modified: subversion/trunk/subversion/tests/cmdline/diff_tests.py
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/diff_tests.py?rev=1311860&r1=1311859&r2=1311860&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/diff_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/diff_tests.py Tue Apr 10 16:49:27
2012
@@ -3779,9 +3779,12 @@ def diff_two_working_copies(sbox):
sbox.build()
wc_dir = sbox.wc_dir
- # Create a second working copy that will remain unchanged
+ # Create a pristine working copy that will remain mostly unchanged
wc_dir2 = sbox.add_wc_path('2')
svntest.main.run_svn(None, 'co', sbox.repo_url, wc_dir2)
+ # Add a property to A/B/F in the pristine working copy
+ svntest.main.run_svn(None, 'propset', 'newprop', 'propval-old\n',
+ os.path.join(wc_dir2, 'A', 'B', 'F'))
# Make changes to the first working copy:
@@ -3800,6 +3803,12 @@ def diff_two_working_copies(sbox):
sbox.simple_propset('newprop', 'propval', 'A/D/gamma')
svntest.main.file_append(sbox.ospath('A/B/lambda'), 'new text\n')
+ # replaced nodes (files vs. directories) with property mods
+ sbox.simple_rm('A/B/F')
+ svntest.main.file_append(sbox.ospath('A/B/F'), 'new text\n')
+ sbox.simple_add('A/B/F')
+ sbox.simple_propset('newprop', 'propval-new\n', 'A/B/F')
+
src_label = os.path.basename(wc_dir2)
dst_label = os.path.basename(wc_dir)
expected_output = make_diff_header('newdir/newfile', 'working copy',
@@ -3812,7 +3821,15 @@ def diff_two_working_copies(sbox):
src_label, dst_label) + [
"@@ -1 +0,0 @@\n",
"-This is the file 'mu'.\n",
- ] + make_diff_header('A/B/lambda', 'working copy',
+ ] + make_diff_header('A/B/F', 'working copy',
+ 'working copy',
+ src_label, dst_label) + [
+ "@@ -0,0 +1 @@\n",
+ "+new text\n",
+ ] + make_diff_prop_header('A/B/F') + \
+ make_diff_prop_modified("newprop", "propval-old\n",
+ "propval-new\n") + \
+ make_diff_header('A/B/lambda', 'working copy',
'working copy',
src_label, dst_label) + [
"@@ -1 +1,2 @@\n",