Author: pburba
Date: Thu Nov 29 15:34:17 2012
New Revision: 1415214

URL: http://svn.apache.org/viewvc?rev=1415214&view=rev
Log:
Fix potential for erroneous --dry-run merge output when an unversioned
directory obstructs an incoming directory.

See: http://svn.haxx.se/dev/archive-2012-11/0696.shtml

Found by: julianfoad

* subversion/libsvn_client/merge.c

  (cache_last_added_dir): New.

  (merge_dir_added): Use new helper above rather than duplicating code.
   Also (and most importantly) we now populate both the
   dry_run_last_added_dir and the dry_run_added members of the merge command
   baton when an unversioned dir is found obstructing an incoming dir add.

* subversion/tests/cmdline/merge_tests.py

  (add_with_history): Add some unversioned directories in the merge target
   which obstruct some incoming directory additions from the merge.  This
   should work without a problem and the --dry-run and actual merge output
   should be the same.

Modified:
    subversion/trunk/subversion/libsvn_client/merge.c
    subversion/trunk/subversion/tests/cmdline/merge_tests.py

Modified: subversion/trunk/subversion/libsvn_client/merge.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/merge.c?rev=1415214&r1=1415213&r2=1415214&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/merge.c (original)
+++ subversion/trunk/subversion/libsvn_client/merge.c Thu Nov 29 15:34:17 2012
@@ -2306,6 +2306,24 @@ merge_file_deleted(svn_wc_notify_state_t
   return SVN_NO_ERROR;
 }
 
+/* Upate dry run list of added directories.
+
+   If the merge is a dry run, then set MERGE_B->DRY_RUN_LAST_ADDED_DIR to a
+   copy of ADDED_DIR_ABSPATH, allocated in MERGE_B->POOL. Add the same copy
+   to MERGE_B->DRY_RUN_ADDED. Do nothing if the merge is not a dry run. */
+static void
+cache_last_added_dir(merge_cmd_baton_t *merge_b,
+                     const char *added_dir_abspath)
+{
+  if (merge_b->dry_run)
+    {
+      merge_b->dry_run_last_added_dir = apr_pstrdup(merge_b->pool,
+                                                   added_dir_abspath);
+      apr_hash_set(merge_b->dry_run_added, merge_b->dry_run_last_added_dir,
+                  APR_HASH_KEY_STRING, merge_b->dry_run_last_added_dir);
+    }
+}
+
 /* An svn_wc_diff_callbacks4_t function. */
 static svn_error_t *
 merge_dir_added(svn_wc_notify_state_t *state,
@@ -2412,10 +2430,7 @@ merge_dir_added(svn_wc_notify_state_t *s
       /* Unversioned or schedule-delete */
       if (merge_b->dry_run)
         {
-          merge_b->dry_run_last_added_dir =
-            apr_pstrdup(merge_b->pool, local_abspath);
-          apr_hash_set(merge_b->dry_run_added, merge_b->dry_run_last_added_dir,
-                       APR_HASH_KEY_STRING, merge_b->dry_run_last_added_dir);
+          cache_last_added_dir(merge_b, local_abspath);
         }
       else
         {
@@ -2451,8 +2466,7 @@ merge_dir_added(svn_wc_notify_state_t *s
             }
           else
             {
-              merge_b->dry_run_last_added_dir =
-                apr_pstrdup(merge_b->pool, local_abspath);
+              cache_last_added_dir(merge_b, local_abspath);
             }
           if (state)
             *state = svn_wc_notify_state_changed;

Modified: subversion/trunk/subversion/tests/cmdline/merge_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/merge_tests.py?rev=1415214&r1=1415213&r2=1415214&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/merge_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/merge_tests.py Thu Nov 29 
15:34:17 2012
@@ -526,6 +526,13 @@ def add_with_history(sbox):
 
   expected_skip = wc.State(C_path, { })
 
+  # Add some unversioned directory obstructions to the incoming
+  # additions.  This should be tolerated and *not* result in any
+  # difference between the --dry-run and actual merge.
+  # See http://svn.haxx.se/dev/archive-2012-11/0696.shtml
+  os.mkdir(sbox.ospath('A/C/Q'))
+  os.mkdir(sbox.ospath('A/C/Q2'))
+
   svntest.actions.run_and_verify_merge(C_path, '1', '2', F_url, None,
                                        expected_output,
                                        expected_mergeinfo_output,


Reply via email to