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",


Reply via email to