You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2013/01/15 23:39:25 UTC

svn commit: r1433715 - /subversion/trunk/subversion/libsvn_client/merge.c

Author: rhuijben
Date: Tue Jan 15 22:39:24 2013
New Revision: 1433715

URL: http://svn.apache.org/viewvc?rev=1433715&view=rev
Log:
Switch the last merge function that determined obstructions itself over to the
common obstruction/tree conflict code.

* subversion/libsvn_client/merge.c
  (merge_dir_added): Simplify code by using perform_obstruction_check().

Modified:
    subversion/trunk/subversion/libsvn_client/merge.c

Modified: subversion/trunk/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/merge.c?rev=1433715&r1=1433714&r2=1433715&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/merge.c (original)
+++ subversion/trunk/subversion/libsvn_client/merge.c Tue Jan 15 22:39:24 2013
@@ -2283,11 +2283,10 @@ merge_dir_added(svn_wc_notify_state_t *s
   const char *local_abspath = svn_dirent_join(merge_b->target->abspath,
                                               local_relpath, scratch_pool);
   svn_node_kind_t kind;
-  const char *copyfrom_url = NULL, *child;
+  const char *copyfrom_url = NULL;
   svn_revnum_t copyfrom_rev = SVN_INVALID_REVNUM;
-  const char *parent_abspath;
-  svn_boolean_t is_versioned;
   svn_boolean_t is_deleted;
+  svn_boolean_t add_existing = FALSE;
 
   /* Easy out: We are only applying mergeinfo differences. */
   if (merge_b->record_only)
@@ -2296,16 +2295,19 @@ merge_dir_added(svn_wc_notify_state_t *s
       return SVN_NO_ERROR;
     }
 
-  parent_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
-
-  child = svn_dirent_is_child(merge_b->target->abspath, local_abspath, NULL);
-  SVN_ERR_ASSERT(child != NULL);
 
   /* If this is a merge from the same repository as our working copy,
      we handle adds as add-with-history.  Otherwise, we'll use a pure
      add. */
   if (merge_b->same_repos)
     {
+      const char *parent_abspath;
+      const char *child;
+
+      parent_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
+      child = svn_dirent_is_child(merge_b->target->abspath, local_abspath, NULL);
+      SVN_ERR_ASSERT(child != NULL);
+
       copyfrom_url = svn_path_url_add_component2(merge_b->merge_source.loc2->url,
                                                  child, scratch_pool);
       copyfrom_rev = rev;
@@ -2323,8 +2325,6 @@ merge_dir_added(svn_wc_notify_state_t *s
                                       merge_b, local_abspath, svn_node_unknown,
                                       scratch_pool));
 
-    is_versioned = (kind == svn_node_dir) || (kind == svn_node_file);
-
     /* In this case of adding a directory, we have an exception to the usual
      * "skip if it's inconsistent" rule. If the directory exists on disk
      * unexpectedly, we simply make it versioned, because we can do so without
@@ -2341,7 +2341,7 @@ merge_dir_added(svn_wc_notify_state_t *s
         if (disk_kind == svn_node_dir)
           {
             obstr_state = svn_wc_notify_state_inapplicable;
-            kind = svn_node_dir; /* Take over existing directory */
+            add_existing = TRUE; /* Take over existing directory */
           }
       }
 
@@ -2364,108 +2364,54 @@ merge_dir_added(svn_wc_notify_state_t *s
       kind = svn_node_none;
   }
 
-  /* Switch on the wc state of this path */
-  switch (kind)
+  if (kind != svn_node_none && !add_existing)
     {
-    case svn_node_none:
-      /* Unversioned or schedule-delete */
-      if (merge_b->dry_run)
-        {
-          cache_last_added_dir(merge_b, local_abspath);
-        }
+      /* The directory add the merge wants to carry out is obstructed, so the
+       * directory the merge wants to add is a tree conflict victim.
+       * See notes about obstructions in notes/tree-conflicts/detection.txt.
+       */
+      SVN_ERR(tree_conflict_on_add(merge_b, local_abspath, svn_node_dir,
+                                   svn_wc_conflict_action_add,
+                                   svn_wc_conflict_reason_obstructed));
+      *tree_conflicted = TRUE;
+      *skip = TRUE;
+      *skip_children = TRUE;
+
+      /* directory already exists, is it under version control? */
+      if ((kind != svn_node_none)
+          && dry_run_deleted_p(merge_b, local_abspath))
+        *state = svn_wc_notify_state_changed;
       else
+        /* this will make the repos_editor send a 'skipped' message */
+        *state = svn_wc_notify_state_obstructed;
+
+      return SVN_NO_ERROR;
+    }
+
+
+  /* Unversioned or schedule-delete */
+  if (merge_b->dry_run)
+    {
+      cache_last_added_dir(merge_b, local_abspath);
+    }
+  else
+    {
+      if (!add_existing)
         {
           SVN_ERR(svn_io_dir_make(local_abspath, APR_OS_DEFAULT,
                                   scratch_pool));
-          SVN_ERR(svn_wc_add4(merge_b->ctx->wc_ctx, local_abspath,
-                              svn_depth_infinity,
-                              copyfrom_url, copyfrom_rev,
-                              merge_b->ctx->cancel_func,
-                              merge_b->ctx->cancel_baton,
-                              NULL, NULL, /* don't pass notification func! */
-                              scratch_pool));
-
         }
-      *state = svn_wc_notify_state_changed;
-      break;
-    case svn_node_dir:
-      /* Adding an unversioned directory doesn't destroy data */
-      if (! is_versioned || is_deleted)
-        {
-          /* The dir is not known to Subversion, or is schedule-delete.
-           * We will make it schedule-add. */
-          if (!merge_b->dry_run)
-            {
-              SVN_ERR(svn_wc_add4(merge_b->ctx->wc_ctx, local_abspath,
-                                  svn_depth_infinity,
-                                  copyfrom_url, copyfrom_rev,
-                                  merge_b->ctx->cancel_func,
-                                  merge_b->ctx->cancel_baton,
-                                  NULL, NULL, /* no notification func! */
-                                  scratch_pool));
-            }
-          else
-            {
-              cache_last_added_dir(merge_b, local_abspath);
-            }
-          *state = svn_wc_notify_state_changed;
-        }
-      else
-        {
-          /* The dir is known to Subversion as already existing. */
-          if (dry_run_deleted_p(merge_b, local_abspath))
-            {
-              *state = svn_wc_notify_state_changed;
-            }
-          else
-            {
-              svn_boolean_t moved_here;
-              svn_wc_conflict_reason_t reason;
 
-              /* This is a tree conflict. */
-              SVN_ERR(check_moved_here(&moved_here, merge_b->ctx->wc_ctx,
-                                       local_abspath, scratch_pool));
-              reason = moved_here ? svn_wc_conflict_reason_moved_here
-                                  : svn_wc_conflict_reason_added;
-              SVN_ERR(tree_conflict_on_add(merge_b, local_abspath,
-                                           svn_node_dir,
-                                           svn_wc_conflict_action_add,
-                                           reason));
-              *tree_conflicted = TRUE;
-              *skip = TRUE;
-              *skip_children = TRUE;
-              *state = svn_wc_notify_state_obstructed;
-            }
-        }
-      break;
-    case svn_node_file:
-      if (merge_b->dry_run)
-        merge_b->dry_run_last_added_dir = NULL;
+      SVN_ERR(svn_wc_add4(merge_b->ctx->wc_ctx, local_abspath,
+                          svn_depth_infinity,
+                          copyfrom_url, copyfrom_rev,
+                          merge_b->ctx->cancel_func,
+                          merge_b->ctx->cancel_baton,
+                          NULL, NULL, /* don't pass notification func! */
+                          scratch_pool));
 
-      if (is_versioned && dry_run_deleted_p(merge_b, local_abspath))
-        {
-          /* ### TODO: Retain record of this dir being added to
-             ### avoid problems from subsequent edits which try to
-             ### add children. */
-          *state = svn_wc_notify_state_changed;
-        }
-      else
-        {
-          /* Obstructed: we can't add a dir because there's a file here. */
-          SVN_ERR(tree_conflict_on_add(merge_b, local_abspath, svn_node_dir,
-                                       svn_wc_conflict_action_add,
-                                       svn_wc_conflict_reason_obstructed));
-          *tree_conflicted = TRUE;
-          *skip_children = TRUE;
-          *state = svn_wc_notify_state_obstructed;
-        }
-      break;
-    default:
-      if (merge_b->dry_run)
-        merge_b->dry_run_last_added_dir = NULL;
-      *state = svn_wc_notify_state_unknown;
-      break;
     }
+  *state = svn_wc_notify_state_changed;
 
   return SVN_NO_ERROR;
 }