Author: danielsh
Date: Mon Apr  4 09:56:58 2011
New Revision: 1088533

URL: http://svn.apache.org/viewvc?rev=1088533&view=rev
Log:
Resolve issue #3469 (tree conflict under a directory external).

Review by: rhuijben

* subversion/libsvn_client/merge.c
  (merge_cmd_baton_t): Add TARGET_WCROOT_ABSPATH member.
  (do_merge): Initialize new member.
  (merge_file_added):
    Skip files that belong to externals or to disjoint working copies.
    Exploit knowledge of libsvn_wc implementations details (queries on
    directories are faster) to make the check cheaper.

* subversion/tests/cmdline/tree_conflict_tests.py
  (at_directory_external):
    Expect it to pass.

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

Modified: subversion/trunk/subversion/libsvn_client/merge.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/merge.c?rev=1088533&r1=1088532&r2=1088533&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/merge.c (original)
+++ subversion/trunk/subversion/libsvn_client/merge.c Mon Apr  4 09:56:58 2011
@@ -249,6 +249,8 @@ typedef struct merge_cmd_baton_t {
                                          versioned dir (dry-run only) */
   const char *target_abspath;         /* Absolute working copy target of
                                          the merge. */
+  const char *target_wcroot_abspath;  /* Absolute path to root of wc that
+                                         TARGET_ABSPATH belongs to. */
 
   /* The left and right URLs and revs.  The value of this field changes to
      reflect the merge_source_t *currently* being merged by do_merge(). */
@@ -1555,6 +1557,32 @@ merge_file_added(const char *local_dir_a
   if (tree_conflicted)
     *tree_conflicted = FALSE;
 
+  /* Easy out: not the same working copy.  (So, a disjoint working copy or
+     an external.) */
+  {
+    const char *mine_wcroot_abspath;
+
+    /* ### White-box optimization:
+
+       The code knows that MINE_ABSPATH is not a directory (it's an added
+       file), and we know that internally libsvn_wc queries are faster for
+       directories (this is an implementation detail).  Therefore, query for
+       the wcroot of the containing directory of MINE_ABSPATH.
+       
+       (We rely on the implementation detail only for performance, not for
+       correctness; under any implementation it would be valid to query for
+       the parent's wcroot.)
+     */
+    SVN_ERR(svn_wc_get_wc_root(&mine_wcroot_abspath, merge_b->ctx->wc_ctx,
+                               svn_dirent_dirname(mine_abspath, scratch_pool),
+                               scratch_pool, scratch_pool));
+    if (strcmp(mine_wcroot_abspath, merge_b->target_wcroot_abspath))
+      {
+        *content_state = svn_wc_notify_state_obstructed;
+        return SVN_NO_ERROR;
+      }
+  }
+
   /* Apply the prop changes to a new hash table. */
   file_props = apr_hash_copy(subpool, original_props);
   for (i = 0; i < prop_changes->nelts; ++i)
@@ -8674,6 +8702,9 @@ do_merge(apr_hash_t **modified_subtrees,
   merge_cmd_baton.target_missing_child = FALSE;
   merge_cmd_baton.reintegrate_merge = reintegrate_merge;
   merge_cmd_baton.target_abspath = target_abspath;
+  SVN_ERR(svn_wc_get_wc_root(&merge_cmd_baton.target_wcroot_abspath,
+                             ctx->wc_ctx, merge_cmd_baton.target_abspath,
+                             pool, subpool));
   merge_cmd_baton.pool = subpool;
   merge_cmd_baton.merge_options = merge_options;
   merge_cmd_baton.diff3_cmd = diff3_cmd;

Modified: subversion/trunk/subversion/tests/cmdline/tree_conflict_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/tree_conflict_tests.py?rev=1088533&r1=1088532&r2=1088533&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/tree_conflict_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/tree_conflict_tests.py Mon Apr  4 
09:56:58 2011
@@ -1078,13 +1078,12 @@ def lock_update_only(sbox):
 
 
 #----------------------------------------------------------------------
-# Currently, it fails at the merge that adds a file:
+# This used to at the merge that adds a file:
 #    subversion/libsvn_client/repos_diff.c:984: (apr_err=155005)
 #    subversion/libsvn_client/merge.c:1708: (apr_err=155005)
 #    subversion/libsvn_wc/update_editor.c:5055: (apr_err=155005)
 #    subversion/libsvn_wc/lock.c:1437: (apr_err=155005)
 #    svn: E155005: No write-lock in 
'/.../svn-test-work/working_copies/tree_conflict_tests-22/E'
-@XFail()
 @Issue(3469)
 def at_directory_external(sbox):
   "tree conflict at directory external"


Reply via email to