subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From julianf...@apache.org
Subject svn commit: r1229329 - in /subversion/trunk/subversion: libsvn_client/merge.c tests/cmdline/input_validation_tests.py tests/cmdline/tree_conflict_tests.py
Date Mon, 09 Jan 2012 19:53:22 GMT
Author: julianfoad
Date: Mon Jan  9 19:53:22 2012
New Revision: 1229329

URL: http://svn.apache.org/viewvc?rev=1229329&view=rev
Log:
In the merge code, encapsulate several details of the target node in a
structure.

* subversion/libsvn_client/merge.c
  (url_uuid_t): Move this structure up a bit so we can reference it.
  (merge_target_t): New structure.
  (merge_cmd_baton_t): Add 'target'. Remove 'target_abspath' and
    'repos_root_url'. Track these changes throughout the file.
  (do_merge): Take 'target' instead of 'target_abspath'. No need to find
    its kind and repos info here, because we already have it.
  (merge_cousins_and_supplement_mergeinfo): Take 'target' instead of
    'target_abspath'.
  (target_node_location): New function.
  (merge_locked, merge_reintegrate_locked, merge_peg_locked): Initialize a
    'target' structure and pass it on.

* subversion/tests/cmdline/input_validation_tests.py
  (invalid_merge_args): Adjust the expected error message.

* subversion/tests/cmdline/tree_conflict_tests.py
  (actual_only_node_behaviour): Same.

Modified:
    subversion/trunk/subversion/libsvn_client/merge.c
    subversion/trunk/subversion/tests/cmdline/input_validation_tests.py
    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=1229329&r1=1229328&r2=1229329&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/merge.c (original)
+++ subversion/trunk/subversion/libsvn_client/merge.c Mon Jan  9 19:53:22 2012
@@ -156,6 +156,14 @@
 
 /*** Repos-Diff Editor Callbacks ***/
 
+/* Repository root and UUID for a repository. */
+typedef struct url_uuid_t
+{
+  const char *url;
+  const char *uuid;
+} url_uuid_t;
+
+/* */
 typedef struct merge_source_t
 {
   /* "left" side URL and revision (inclusive iff youngest) */
@@ -168,6 +176,24 @@ typedef struct merge_source_t
 
 } merge_source_t;
 
+/* Description of the merge target root node (a WC working node) */
+typedef struct merge_target_t
+{
+  /* Absolute path to the WC node */
+  const char *abspath;
+
+  /* Node kind of the WC node (at the start of the merge) */
+  svn_node_kind_t kind;
+
+  /* URL and revision of the node */
+  const char *url;
+  svn_revnum_t rev;
+
+  /* Repository root URL and UUID */
+  url_uuid_t repos_root;
+
+} merge_target_t;
+
 typedef struct merge_cmd_baton_t {
   svn_boolean_t force;
   svn_boolean_t dry_run;
@@ -193,10 +219,7 @@ typedef struct merge_cmd_baton_t {
   const char *added_path;             /* Set to the dir path whenever the
                                          dir is added as a child of a
                                          versioned dir (dry-run only) */
-  const char *target_abspath;         /* Absolute working copy target of
-                                         the merge. */
-  const char *repos_root_url;         /* The repository root of the repository
-                                         containing TARGET_ABSPATH */
+  const merge_target_t *target;       /* Description of merge target node */
 
   /* 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(). */
@@ -297,13 +320,6 @@ typedef struct merge_cmd_baton_t {
 
 /*** Utilities ***/
 
-/* Repository root and UUID for a repository. */
-typedef struct url_uuid_t
-{
-  const char *url;
-  const char *uuid;
-} url_uuid_t;
-
 /* Return SVN_ERR_UNSUPPORTED_FEATURE if URL is not inside the repository
    of LOCAL_ABSPATH.  Use SCRATCH_POOL for temporary allocations. */
 static svn_error_t *
@@ -312,12 +328,12 @@ check_repos_match(merge_cmd_baton_t *mer
                   const char *url,
                   apr_pool_t *scratch_pool)
 {
-  if (!svn_uri__is_ancestor(merge_b->repos_root_url, url))
+  if (!svn_uri__is_ancestor(merge_b->target->repos_root.url, url))
     return svn_error_createf(
         SVN_ERR_UNSUPPORTED_FEATURE, NULL,
          _("Url '%s' of '%s' is not in repository '%s'"),
          url, svn_dirent_local_style(local_abspath, scratch_pool),
-         merge_b->repos_root_url);
+         merge_b->target->repos_root.url);
 
   return SVN_NO_ERROR;
 }
@@ -465,7 +481,7 @@ perform_obstruction_check(svn_wc_notify_
   if (kind == NULL)
     kind = &wc_kind;
 
-  check_root = ! strcmp(local_abspath, merge_b->target_abspath);
+  check_root = ! strcmp(local_abspath, merge_b->target->abspath);
 
   SVN_ERR(svn_wc__check_for_obstructions(obstruction_state,
                                          kind,
@@ -505,7 +521,7 @@ make_conflict_versions(const svn_wc_conf
 
   /* Construct the source URLs of the victim. */
   {
-    const char *child = svn_dirent_skip_ancestor(merge_b->target_abspath,
+    const char *child = svn_dirent_skip_ancestor(merge_b->target->abspath,
                                                  victim_abspath);
     SVN_ERR_ASSERT(child != NULL);
     left_url = svn_path_url_add_component2(merge_b->merge_source.url1,
@@ -1272,7 +1288,7 @@ merge_dir_props_changed(svn_wc_notify_st
                         apr_pool_t *scratch_pool)
 {
   merge_cmd_baton_t *merge_b = diff_baton;
-  const char *local_abspath = svn_dirent_join(merge_b->target_abspath,
+  const char *local_abspath = svn_dirent_join(merge_b->target->abspath,
                                               local_relpath, scratch_pool);
   svn_wc_notify_state_t obstr_state;
 
@@ -1455,7 +1471,7 @@ merge_file_changed(svn_wc_notify_state_t
                    apr_pool_t *scratch_pool)
 {
   merge_cmd_baton_t *merge_b = baton;
-  const char *mine_abspath = svn_dirent_join(merge_b->target_abspath,
+  const char *mine_abspath = svn_dirent_join(merge_b->target->abspath,
                                              mine_relpath, scratch_pool);
   svn_node_kind_t wc_kind;
   svn_boolean_t is_deleted;
@@ -1689,7 +1705,7 @@ merge_file_added(svn_wc_notify_state_t *
                  apr_pool_t *scratch_pool)
 {
   merge_cmd_baton_t *merge_b = baton;
-  const char *mine_abspath = svn_dirent_join(merge_b->target_abspath,
+  const char *mine_abspath = svn_dirent_join(merge_b->target->abspath,
                                              mine_relpath, scratch_pool);
   svn_node_kind_t kind;
   int i;
@@ -1789,7 +1805,7 @@ merge_file_added(svn_wc_notify_state_t *
             if (merge_b->same_repos)
               {
                 const char *child =
-                  svn_dirent_skip_ancestor(merge_b->target_abspath,
+                  svn_dirent_skip_ancestor(merge_b->target->abspath,
                                            mine_abspath);
                 SVN_ERR_ASSERT(child != NULL);
                 copyfrom_url = svn_path_url_add_component2(
@@ -2020,7 +2036,7 @@ merge_file_deleted(svn_wc_notify_state_t
                    apr_pool_t *scratch_pool)
 {
   merge_cmd_baton_t *merge_b = baton;
-  const char *mine_abspath = svn_dirent_join(merge_b->target_abspath,
+  const char *mine_abspath = svn_dirent_join(merge_b->target->abspath,
                                              mine_relpath, scratch_pool);
   svn_node_kind_t kind;
 
@@ -2157,7 +2173,7 @@ merge_dir_added(svn_wc_notify_state_t *s
                 apr_pool_t *scratch_pool)
 {
   merge_cmd_baton_t *merge_b = baton;
-  const char *local_abspath = svn_dirent_join(merge_b->target_abspath,
+  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;
@@ -2176,7 +2192,7 @@ merge_dir_added(svn_wc_notify_state_t *s
 
   parent_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
 
-  child = svn_dirent_is_child(merge_b->target_abspath, local_abspath, NULL);
+  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,
@@ -2358,7 +2374,7 @@ merge_dir_deleted(svn_wc_notify_state_t 
                   apr_pool_t *scratch_pool)
 {
   merge_cmd_baton_t *merge_b = baton;
-  const char *local_abspath = svn_dirent_join(merge_b->target_abspath,
+  const char *local_abspath = svn_dirent_join(merge_b->target->abspath,
                                               local_relpath, scratch_pool);
   svn_node_kind_t kind;
   svn_boolean_t is_versioned;
@@ -2507,7 +2523,7 @@ merge_dir_opened(svn_boolean_t *tree_con
                  apr_pool_t *scratch_pool)
 {
   merge_cmd_baton_t *merge_b = baton;
-  const char *local_abspath = svn_dirent_join(merge_b->target_abspath,
+  const char *local_abspath = svn_dirent_join(merge_b->target->abspath,
                                               local_relpath, scratch_pool);
   svn_node_kind_t wc_kind;
   svn_wc_notify_state_t obstr_state;
@@ -2845,7 +2861,7 @@ notification_receiver(void *baton, const
    * not yet implemented.
    * ### We should stash the info about which moves have been followed and
    * retrieve that info here, instead of querying the WC again here. */
-  notify_abspath = svn_dirent_join(notify_b->merge_b->target_abspath,
+  notify_abspath = svn_dirent_join(notify_b->merge_b->target->abspath,
                                    notify->path, pool);
   if (notify->action == svn_wc_notify_update_update
       && notify->kind == svn_node_file)
@@ -2997,7 +3013,7 @@ notification_receiver(void *baton, const
            && notify_b->nbr_operative_notifications == 1
            && is_operative_notification)
     {
-      notify_merge_begin(notify_b->merge_b->target_abspath, NULL,
+      notify_merge_begin(notify_b->merge_b->target->abspath, NULL,
                          notify_b->merge_b, pool);
     }
 
@@ -3412,7 +3428,7 @@ fix_deleted_subtree_ranges(const merge_s
         {
           const char *child_primary_source_url;
           const char *child_repos_src_path =
-            svn_dirent_is_child(merge_b->target_abspath, child->abspath,
+            svn_dirent_is_child(merge_b->target->abspath, child->abspath,
                                 iterpool);
 
           /* This loop is only processing subtrees, so CHILD->ABSPATH
@@ -4359,7 +4375,7 @@ populate_remaining_ranges(apr_array_head
 
       svn_pool_clear(iterpool);
 
-      child_repos_path = svn_dirent_skip_ancestor(merge_b->target_abspath,
+      child_repos_path = svn_dirent_skip_ancestor(merge_b->target->abspath,
                                                   child->abspath);
       SVN_ERR_ASSERT(child_repos_path != NULL);
       child_source.url1 = svn_path_url_add_component2(source->url1, child_repos_path,
@@ -4705,7 +4721,7 @@ record_skips(const char *mergeinfo_path,
            ### this path which were not also explicitly
            ### skipped? */
     }
-  SVN_ERR(update_wc_mergeinfo(NULL, merge_b->target_abspath,
+  SVN_ERR(update_wc_mergeinfo(NULL, merge_b->target->abspath,
                               mergeinfo_path, merges,
                               is_rollback, merge_b->ctx, iterpool));
   svn_pool_destroy(iterpool);
@@ -5255,7 +5271,7 @@ single_file_merge_notify(notification_re
 
   if (IS_OPERATIVE_NOTIFICATION(notify) && (! *header_sent))
     {
-      notify_merge_begin(notify_baton->merge_b->target_abspath,
+      notify_merge_begin(notify_baton->merge_b->target->abspath,
                          (notify_baton->merge_b->sources_ancestral ? r : NULL),
                          notify_baton->merge_b, pool);
       *header_sent = TRUE;
@@ -5362,7 +5378,7 @@ insert_parent_and_sibs_of_sw_absent_del_
 
   if (!(child->absent
           || (child->switched
-              && strcmp(merge_cmd_baton->target_abspath,
+              && strcmp(merge_cmd_baton->target->abspath,
                         child->abspath) != 0)))
     return SVN_NO_ERROR;
 
@@ -5662,7 +5678,7 @@ get_mergeinfo_paths(apr_array_header_t *
 
   /* Case 1: Subtrees with explicit mergeinfo. */
   SVN_ERR(get_wc_explicit_mergeinfo_catalog(&subtrees_with_mergeinfo,
-                                            merge_cmd_baton->target_abspath,
+                                            merge_cmd_baton->target->abspath,
                                             depth, merge_cmd_baton->ctx,
                                             result_pool, scratch_pool));
   if (subtrees_with_mergeinfo)
@@ -5713,7 +5729,7 @@ get_mergeinfo_paths(apr_array_header_t *
   pre_merge_status_baton.missing_subtrees = missing_subtrees;
   pre_merge_status_baton.pool = scratch_pool;
   SVN_ERR(svn_wc_walk_status(merge_cmd_baton->ctx->wc_ctx,
-                             merge_cmd_baton->target_abspath,
+                             merge_cmd_baton->target->abspath,
                              depth, TRUE, TRUE, TRUE, NULL,
                              pre_merge_status_cb,
                              &pre_merge_status_baton,
@@ -5829,7 +5845,7 @@ get_mergeinfo_paths(apr_array_header_t *
   /* Case 6: Paths absent from disk due to server-side exclusion. */
   SVN_ERR(svn_wc__get_server_excluded_subtrees(&server_excluded_subtrees,
                                                merge_cmd_baton->ctx->wc_ctx,
-                                               merge_cmd_baton->target_abspath,
+                                               merge_cmd_baton->target->abspath,
                                                result_pool, scratch_pool));
   if (server_excluded_subtrees)
     {
@@ -5861,10 +5877,10 @@ get_mergeinfo_paths(apr_array_header_t *
   /* Case 7: The merge target MERGE_CMD_BATON->TARGET_ABSPATH is always
      present. */
   if (!get_child_with_mergeinfo(children_with_mergeinfo,
-                                merge_cmd_baton->target_abspath))
+                                merge_cmd_baton->target->abspath))
     {
       svn_client__merge_path_t *target_child =
-        svn_client__merge_path_create(merge_cmd_baton->target_abspath,
+        svn_client__merge_path_create(merge_cmd_baton->target->abspath,
                                       result_pool);
       insert_child_to_merge(children_with_mergeinfo, target_child,
                             result_pool);
@@ -5882,7 +5898,7 @@ get_mergeinfo_paths(apr_array_header_t *
 
       SVN_ERR(svn_wc__node_get_children_of_working_node(
         &immediate_children, merge_cmd_baton->ctx->wc_ctx,
-        merge_cmd_baton->target_abspath, FALSE, scratch_pool, scratch_pool));
+        merge_cmd_baton->target->abspath, FALSE, scratch_pool, scratch_pool));
 
       for (j = 0; j < immediate_children->nelts; j++)
         {
@@ -6016,7 +6032,7 @@ get_mergeinfo_paths(apr_array_header_t *
                         &mergeinfo, NULL,
                         svn_mergeinfo_nearest_ancestor,
                         child_of_noninheritable->abspath,
-                        merge_cmd_baton->target_abspath, NULL, FALSE,
+                        merge_cmd_baton->target->abspath, NULL, FALSE,
                         merge_cmd_baton->ctx, iterpool, iterpool));
 
                       SVN_ERR(svn_client__record_wc_mergeinfo(
@@ -7402,7 +7418,7 @@ flag_subtrees_needing_mergeinfo(svn_bool
       &operative_immediate_children,
       notify_b->children_with_mergeinfo,
       mergeinfo_fspath, merged_range->start + 1, merged_range->end,
-      merge_b->target_abspath, depth, merge_b->ctx->wc_ctx, merge_b->ra_session1,
+      merge_b->target->abspath, depth, merge_b->ctx->wc_ctx, merge_b->ra_session1,
       scratch_pool, iterpool));
 
   /* Issue #4056: Walk NOTIFY_B->CHILDREN_WITH_MERGEINFO reverse depth-first
@@ -7641,7 +7657,7 @@ record_mergeinfo_for_dir_merge(svn_merge
 
   /* Regardless of what subtrees in MERGE_B->TARGET_ABSPATH might be missing
      could this merge have been operative? */
-  operative_merge = subtree_touched_by_merge(merge_b->target_abspath,
+  operative_merge = subtree_touched_by_merge(merge_b->target->abspath,
                                              notify_b, iterpool);
 
   /* If this couldn't be an operative merge then don't bother with
@@ -7653,7 +7669,7 @@ record_mergeinfo_for_dir_merge(svn_merge
   /* Remove absent children at or under TARGET_WCPATH from
      NOTIFY_B->CHILDREN_WITH_MERGEINFO
      before we calculate the merges performed. */
-  remove_absent_children(merge_b->target_abspath,
+  remove_absent_children(merge_b->target->abspath,
                          notify_b->children_with_mergeinfo);
 
   /* Determine which subtrees of interest need mergeinfo recorded... */
@@ -7677,7 +7693,7 @@ record_mergeinfo_for_dir_merge(svn_merge
 
       if (child->record_mergeinfo)
         {
-          child_repos_path = svn_dirent_skip_ancestor(merge_b->target_abspath,
+          child_repos_path = svn_dirent_skip_ancestor(merge_b->target->abspath,
                                                       child->abspath);
           SVN_ERR_ASSERT(child_repos_path != NULL);
           child_merge_src_fspath = svn_fspath__join(mergeinfo_fspath,
@@ -7775,7 +7791,7 @@ record_mergeinfo_for_dir_merge(svn_merge
               apr_array_header_t *child_merge_src_rangelist;
               const char *old_session_url;
               const char *subtree_mergeinfo_url =
-                svn_path_url_add_component2(merge_b->repos_root_url,
+                svn_path_url_add_component2(merge_b->target->repos_root.url,
                                             child_merge_src_fspath + 1,
                                             iterpool);
 
@@ -7866,7 +7882,7 @@ record_mergeinfo_for_dir_merge(svn_merge
              elide that when the merge is complete. */
           SVN_ERR(svn_client__elide_mergeinfo(
             child->abspath,
-            in_switched_subtree ? NULL : merge_b->target_abspath,
+            in_switched_subtree ? NULL : merge_b->target->abspath,
             merge_b->ctx, iterpool));
         }
     } /* (i = 0; i < notify_b->children_with_mergeinfo->nelts; i++) */
@@ -7961,7 +7977,7 @@ record_mergeinfo_for_added_subtrees(
           /* Create the new mergeinfo path for added_path's mergeinfo.
              (added_abspath had better be a child of target_abspath
              or something is *really* wrong.) */
-          rel_added_path = svn_dirent_is_child(merge_b->target_abspath,
+          rel_added_path = svn_dirent_is_child(merge_b->target->abspath,
                                                added_abspath, iterpool);
           SVN_ERR_ASSERT(rel_added_path);
           added_path_mergeinfo_fspath = svn_fspath__join(mergeinfo_fspath,
@@ -7983,7 +7999,7 @@ record_mergeinfo_for_added_subtrees(
              take the intersection of the naive mergeinfo with
              MERGEINFO_PATH/rel_added_path's history. */
           added_path_mergeinfo_url =
-            svn_path_url_add_component2(merge_b->repos_root_url,
+            svn_path_url_add_component2(merge_b->target->repos_root.url,
                                         added_path_mergeinfo_fspath + 1,
                                         iterpool);
           SVN_ERR(svn_client__ensure_ra_session_url(
@@ -8143,7 +8159,7 @@ log_noop_revs(void *baton,
          can disregard it altogether. */
       if (rel_path == NULL)
         continue;
-      cwmi_abspath = svn_dirent_join(log_gap_baton->merge_b->target_abspath,
+      cwmi_abspath = svn_dirent_join(log_gap_baton->merge_b->target->abspath,
                                      rel_path, scratch_pool);
 
       /* Find any explicit or inherited mergeinfo for PATH. */
@@ -8164,7 +8180,7 @@ log_noop_revs(void *baton,
 
           if (cwmi_abspath[0] == '\0'
               || svn_dirent_is_root(cwmi_abspath, strlen(cwmi_abspath))
-              || svn_path_compare_paths(log_gap_baton->merge_b->target_abspath,
+              || svn_path_compare_paths(log_gap_baton->merge_b->target->abspath,
                                         cwmi_abspath) == 0)
             {
               /* Can't crawl any higher. */
@@ -8317,12 +8333,12 @@ remove_noop_subtree_ranges(const merge_s
   log_gap_baton.children_with_mergeinfo = children_with_mergeinfo;
   SVN_ERR(svn_client__path_relative_to_root(
                     &(log_gap_baton.target_fspath), merge_b->ctx->wc_ctx,
-                    merge_b->target_abspath,
-                    merge_b->repos_root_url, TRUE, NULL,
+                    merge_b->target->abspath,
+                    merge_b->target->repos_root.url, TRUE, NULL,
                     result_pool, scratch_pool));
   SVN_ERR(svn_client__path_relative_to_root(
                     &(log_gap_baton.source_fspath), merge_b->ctx->wc_ctx,
-                    source->url2, merge_b->repos_root_url, TRUE, NULL,
+                    source->url2, merge_b->target->repos_root.url, TRUE, NULL,
                     result_pool, scratch_pool));
   log_gap_baton.merged_ranges = apr_array_make(scratch_pool, 0,
                                                sizeof(svn_revnum_t *));
@@ -8553,7 +8569,7 @@ do_directory_merge(svn_mergeinfo_catalog
                 a range that ends with end_rev.
 
              2. Starting with start_rev, call drive_merge_report_editor()
-                on MERGE_B->target_abspath for start_rev:end_rev.
+                on MERGE_B->target->abspath for start_rev:end_rev.
 
              3. Remove the first element from each
                 NOTIFY_B->CHILDREN_WITH_MERGEINFO element's remaining_ranges
@@ -8622,7 +8638,7 @@ do_directory_merge(svn_mergeinfo_catalog
                         &old_sess2_url, merge_b->ra_session2,
                         real_source->url2, iterpool));
               SVN_ERR(drive_merge_report_editor(
-                merge_b->target_abspath,
+                merge_b->target->abspath,
                 real_source,
                 notify_b->children_with_mergeinfo,
                 depth, notify_b,
@@ -8663,7 +8679,7 @@ do_directory_merge(svn_mergeinfo_catalog
                   conflicted_range.start = start_rev;
                   conflicted_range.end = end_rev;
                   merge_conflict_err = make_merge_conflict_error(
-                                         merge_b->target_abspath,
+                                         merge_b->target->abspath,
                                          &conflicted_range,
                                          scratch_pool);
                   range.end = end_rev;
@@ -8686,7 +8702,7 @@ do_directory_merge(svn_mergeinfo_catalog
              operative merge. */
           notify_b->cur_ancestor_abspath = NULL;
 
-          SVN_ERR(drive_merge_report_editor(merge_b->target_abspath,
+          SVN_ERR(drive_merge_report_editor(merge_b->target->abspath,
                                             source,
                                             NULL,
                                             depth, notify_b,
@@ -8772,7 +8788,7 @@ ensure_ra_session_url(svn_ra_session_t *
   return SVN_NO_ERROR;
 }
 
-/* Drive a merge of MERGE_SOURCES into working copy path TARGET_ABSPATH
+/* Drive a merge of MERGE_SOURCES into working copy node TARGET
    and possibly record mergeinfo describing the merge -- see
    RECORD_MERGEINFO().
 
@@ -8818,7 +8834,7 @@ ensure_ra_session_url(svn_ra_session_t *
    then record mergeinfo describing the merge only on subtrees which contain
    items from RECORD_ONLY_PATHS.  If RECORD_ONLY is true and RECORD_ONLY_PATHS
    is NULL, then record mergeinfo on every subtree with mergeinfo in
-   TARGET_ABSPATH.
+   TARGET.
 
    REINTEGRATE_MERGE is TRUE if this is a reintegrate merge.
 
@@ -8831,7 +8847,7 @@ static svn_error_t *
 do_merge(apr_hash_t **modified_subtrees,
          svn_mergeinfo_catalog_t result_catalog,
          const apr_array_header_t *merge_sources,
-         const char *target_abspath,
+         const merge_target_t *target,
          svn_boolean_t sources_ancestral,
          svn_boolean_t sources_related,
          svn_boolean_t same_repos,
@@ -8856,10 +8872,9 @@ do_merge(apr_hash_t **modified_subtrees,
   int i;
   svn_boolean_t checked_mergeinfo_capability = FALSE;
   svn_ra_session_t *ra_session1 = NULL, *ra_session2 = NULL;
-  svn_node_kind_t target_kind;
   apr_pool_t *iterpool;
 
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(target_abspath));
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(target->abspath));
 
   /* Check from some special conditions when in record-only mode
      (which is a merge-tracking thing). */
@@ -8884,13 +8899,10 @@ do_merge(apr_hash_t **modified_subtrees,
     }
 
   iterpool = svn_pool_create(scratch_pool);
-  SVN_ERR(svn_wc_read_kind(&target_kind, ctx->wc_ctx, target_abspath, FALSE,
-                           iterpool));
-
-  if (target_kind != svn_node_dir && target_kind != svn_node_file)
+  if (target->kind != svn_node_dir && target->kind != svn_node_file)
     return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
                              _("Merge target '%s' does not exist in the "
-                               "working copy"), target_abspath);
+                               "working copy"), target->abspath);
 
   /* Ensure a known depth. */
   if (depth == svn_depth_unknown)
@@ -8917,12 +8929,7 @@ do_merge(apr_hash_t **modified_subtrees,
   merge_cmd_baton.ctx = ctx;
   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__node_get_repos_info(&merge_cmd_baton.repos_root_url, NULL,
-                                      ctx->wc_ctx,
-                                      merge_cmd_baton.target_abspath,
-                                      result_pool,
-                                      iterpool));
+  merge_cmd_baton.target = target;
   merge_cmd_baton.pool = iterpool;
   merge_cmd_baton.merge_options = merge_options;
   merge_cmd_baton.diff3_cmd = diff3_cmd;
@@ -8994,17 +9001,17 @@ do_merge(apr_hash_t **modified_subtrees,
           checked_mergeinfo_capability = TRUE;
         }
 
-      /* Call our merge helpers based on TARGET_ABSPATH's kind. */
-      if (target_kind == svn_node_file)
+      /* Call our merge helpers based on TARGET's kind. */
+      if (target->kind == svn_node_file)
         {
           SVN_ERR(do_file_merge(result_catalog,
-                                source, target_abspath,
+                                source, target->abspath,
                                 sources_related,
                                 squelch_mergeinfo_notifications,
                                 &notify_baton,
                                 &merge_cmd_baton, iterpool));
         }
-      else if (target_kind == svn_node_dir)
+      else if (target->kind == svn_node_dir)
         {
           /* If conflicts occur while merging any but the very last
            * revision range we want an error to be raised that aborts
@@ -9013,7 +9020,7 @@ do_merge(apr_hash_t **modified_subtrees,
           svn_boolean_t abort_on_conflicts = (i < merge_sources->nelts - 1);
 
           SVN_ERR(do_directory_merge(result_catalog,
-                                     source, target_abspath,
+                                     source, target->abspath,
                                      depth, squelch_mergeinfo_notifications,
                                      abort_on_conflicts,
                                      &notify_baton, &merge_cmd_baton,
@@ -9044,12 +9051,12 @@ do_merge(apr_hash_t **modified_subtrees,
 
       /* The final mergeinfo on TARGET_WCPATH may itself elide. */
       if (! dry_run)
-        SVN_ERR(svn_client__elide_mergeinfo(target_abspath, NULL,
+        SVN_ERR(svn_client__elide_mergeinfo(target->abspath, NULL,
                                             ctx, iterpool));
     }
 
   /* Let everyone know we're finished here. */
-  notify_merge_completed(target_abspath, ctx, iterpool);
+  notify_merge_completed(target->abspath, ctx, iterpool);
 
   svn_pool_destroy(iterpool);
   return SVN_NO_ERROR;
@@ -9073,7 +9080,7 @@ do_merge(apr_hash_t **modified_subtrees,
    SCRATCH_POOL is used for all temporary allocations.
  */
 static svn_error_t *
-merge_cousins_and_supplement_mergeinfo(const char *target_abspath,
+merge_cousins_and_supplement_mergeinfo(const merge_target_t *target,
                                        svn_ra_session_t *URL1_ra_session,
                                        svn_ra_session_t *URL2_ra_session,
                                        const merge_source_t *source,
@@ -9098,7 +9105,7 @@ merge_cousins_and_supplement_mergeinfo(c
      subtree mergeinfo, then this will help keep memory use in check. */
   apr_pool_t *subpool = svn_pool_create(scratch_pool);
 
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(target_abspath));
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(target->abspath));
 
   SVN_ERR(normalize_merge_sources_internal(
             &remove_sources, source->url1, source->rev1,
@@ -9118,7 +9125,7 @@ merge_cousins_and_supplement_mergeinfo(c
         apr_array_make(scratch_pool, 1, sizeof(merge_source_t *));
       modified_subtrees = apr_hash_make(scratch_pool);
       APR_ARRAY_PUSH(faux_sources, const merge_source_t *) = source;
-      SVN_ERR(do_merge(&modified_subtrees, NULL, faux_sources, target_abspath,
+      SVN_ERR(do_merge(&modified_subtrees, NULL, faux_sources, target,
                        FALSE, TRUE, same_repos,
                        ignore_ancestry, force, dry_run, FALSE, NULL, TRUE,
                        FALSE, depth, merge_options, use_sleep, ctx,
@@ -9150,17 +9157,17 @@ merge_cousins_and_supplement_mergeinfo(c
       svn_mergeinfo_catalog_t remove_result_catalog =
         apr_hash_make(scratch_pool);
 
-      notify_mergeinfo_recording(target_abspath, NULL, ctx, scratch_pool);
+      notify_mergeinfo_recording(target->abspath, NULL, ctx, scratch_pool);
       svn_pool_clear(subpool);
-      SVN_ERR(do_merge(NULL, add_result_catalog, add_sources, target_abspath,
+      SVN_ERR(do_merge(NULL, add_result_catalog, add_sources, target,
                        TRUE, TRUE, same_repos,
                        ignore_ancestry, force, dry_run, TRUE,
                        modified_subtrees, TRUE,
                        TRUE, depth, merge_options, use_sleep, ctx,
                        scratch_pool, subpool));
       svn_pool_clear(subpool);
-      SVN_ERR(do_merge(NULL, remove_result_catalog, remove_sources,
-                       target_abspath, TRUE, TRUE, same_repos,
+      SVN_ERR(do_merge(NULL, remove_result_catalog, remove_sources, target,
+                       TRUE, TRUE, same_repos,
                        ignore_ancestry, force, dry_run, TRUE,
                        modified_subtrees, TRUE,
                        TRUE, depth, merge_options, use_sleep, ctx,
@@ -9292,6 +9299,47 @@ ensure_wc_path_has_repo_revision(const c
   return SVN_NO_ERROR;
 }
 
+/* Set *TARGET to a new, fully initialized, target description structure. */
+static svn_error_t *
+target_node_location(merge_target_t **target_p,
+                     const char *wc_abspath,
+                     svn_client_ctx_t *ctx,
+                     apr_pool_t *result_pool,
+                     apr_pool_t *scratch_pool)
+{
+  merge_target_t *target = apr_palloc(result_pool, sizeof(*target));
+  const char *relpath;
+
+  target->abspath = wc_abspath;
+  SVN_ERR(svn_wc_read_kind(&target->kind, ctx->wc_ctx, wc_abspath, FALSE,
+                           scratch_pool));
+  SVN_ERR(svn_wc__node_get_origin(NULL /* is_copy */,
+                                  &target->rev, &relpath,
+                                  &target->repos_root.url,
+                                  &target->repos_root.uuid,
+                                  NULL, ctx->wc_ctx, wc_abspath,
+                                  FALSE /* scan_deleted */,
+                                  result_pool, scratch_pool));
+  if (target->repos_root.url && relpath)
+    {
+      target->url = svn_path_url_add_component2(target->repos_root.url,
+                                                relpath, result_pool);
+      SVN_DBG(("tgt node location: r%ld %s\n", target->rev, target->url));
+    }
+  else
+    {
+      target->url = NULL;
+      SVN_ERR(svn_client_get_repos_root(&target->repos_root.url,
+                                        &target->repos_root.uuid,
+                                        wc_abspath,
+                                        ctx, result_pool, scratch_pool));
+      SVN_DBG(("tgt node location: none (local add?)\n"));
+    }
+
+  *target_p = target;
+  return SVN_NO_ERROR;
+}
+
 
 /*-----------------------------------------------------------------------*/
 
@@ -9314,9 +9362,10 @@ merge_locked(const char *source1,
              svn_client_ctx_t *ctx,
              apr_pool_t *scratch_pool)
 {
+  merge_target_t *target;
   merge_source_t source;
   svn_boolean_t related = FALSE, ancestral = FALSE;
-  url_uuid_t wc_repos_root, source_repos_root, source_repos_root2;
+  url_uuid_t source_repos_root, source_repos_root2;
   svn_ra_session_t *ra_session1, *ra_session2;
   apr_array_header_t *merge_sources;
   svn_error_t *err;
@@ -9331,16 +9380,14 @@ merge_locked(const char *source1,
      ancestor of the other -- just call svn_client_merge_peg3() with
      the appropriate args. */
 
+  SVN_ERR(target_node_location(&target, target_abspath,
+                               ctx, scratch_pool, scratch_pool));
+
   /* Do not allow merges into mixed-revision working copies. */
-  SVN_ERR(ensure_wc_is_suitable_merge_target(target_abspath, ctx,
+  SVN_ERR(ensure_wc_is_suitable_merge_target(target->abspath, ctx,
                                              allow_mixed_rev, TRUE, TRUE,
                                              scratch_pool));
 
-  /* Determine the working copy target's repository root URL. */
-  SVN_ERR(svn_client_get_repos_root(&wc_repos_root.url, &wc_repos_root.uuid,
-                                    target_abspath,
-                                    ctx, scratch_pool, scratch_pool));
-
   /* Open RA sessions to both sides of our merge source, and resolve URLs
    * and revisions. */
   sesspool = svn_pool_create(scratch_pool);
@@ -9372,7 +9419,7 @@ merge_locked(const char *source1,
                            FALSE /* strict_urls */, scratch_pool));
 
   /* Do our working copy and sources come from the same repository? */
-  same_repos = is_same_repos(&wc_repos_root, &source_repos_root,
+  same_repos = is_same_repos(&target->repos_root, &source_repos_root,
                              TRUE /* strict_urls */);
 
   /* Unless we're ignoring ancestry, see if the two sources are related.  */
@@ -9428,7 +9475,7 @@ merge_locked(const char *source1,
          side, and merge the right. */
       else
         {
-          err = merge_cousins_and_supplement_mergeinfo(target_abspath,
+          err = merge_cousins_and_supplement_mergeinfo(target,
                                                        ra_session1,
                                                        ra_session2,
                                                        &source,
@@ -9443,7 +9490,7 @@ merge_locked(const char *source1,
           if (err)
             {
               if (use_sleep)
-                svn_io_sleep_for_timestamps(target_abspath, scratch_pool);
+                svn_io_sleep_for_timestamps(target->abspath, scratch_pool);
 
               return svn_error_trace(err);
             }
@@ -9463,7 +9510,7 @@ merge_locked(const char *source1,
       APR_ARRAY_PUSH(merge_sources, merge_source_t *) = &source;
     }
 
-  err = do_merge(NULL, NULL, merge_sources, target_abspath,
+  err = do_merge(NULL, NULL, merge_sources, target,
                  ancestral, related, same_repos,
                  ignore_ancestry, force, dry_run,
                  record_only, NULL, FALSE, FALSE, depth, merge_options,
@@ -9473,7 +9520,7 @@ merge_locked(const char *source1,
   svn_pool_destroy(sesspool);
 
   if (use_sleep)
-    svn_io_sleep_for_timestamps(target_abspath, scratch_pool);
+    svn_io_sleep_for_timestamps(target->abspath, scratch_pool);
 
   if (err)
     return svn_error_trace(err);
@@ -10661,11 +10708,15 @@ merge_reintegrate_locked(const char *sou
                          apr_pool_t *scratch_pool)
 {
   svn_ra_session_t *target_ra_session, *source_ra_session;
+  merge_target_t *target;
   merge_source_t *source;
   svn_revnum_t yc_ancestor_rev;
   svn_boolean_t use_sleep;
   svn_error_t *err;
 
+  SVN_ERR(target_node_location(&target, target_abspath,
+                               ctx, scratch_pool, scratch_pool));
+
   SVN_ERR(find_reintegrate_merge(&target_ra_session, &source_ra_session,
                                  &source, &yc_ancestor_rev,
                                  source_path_or_url, source_peg_revision,
@@ -10682,7 +10733,7 @@ merge_reintegrate_locked(const char *sou
      ### of the other (what's erroneously referred to as "ancestrally
      ### related" in this source file).  We can merge to trunk without
      ### implementing this. */
-  err = merge_cousins_and_supplement_mergeinfo(target_abspath,
+  err = merge_cousins_and_supplement_mergeinfo(target,
                                                target_ra_session,
                                                source_ra_session,
                                                source, yc_ancestor_rev,
@@ -10748,10 +10799,11 @@ merge_peg_locked(const char *source_path
                  svn_client_ctx_t *ctx,
                  apr_pool_t *scratch_pool)
 {
+  merge_target_t *target;
   const char *source_url;
   svn_revnum_t source_peg_revnum;
   apr_array_header_t *merge_sources;
-  url_uuid_t wc_repos_root, source_repos_root;
+  url_uuid_t source_repos_root;
   svn_ra_session_t *ra_session;
   apr_pool_t *sesspool;
   svn_boolean_t use_sleep = FALSE;
@@ -10760,15 +10812,12 @@ merge_peg_locked(const char *source_path
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(target_abspath));
 
+  SVN_ERR(target_node_location(&target, target_abspath,
+                               ctx, scratch_pool, scratch_pool));
   SVN_ERR(ensure_wc_is_suitable_merge_target(target_abspath, ctx,
                                              allow_mixed_rev, TRUE, TRUE,
                                              scratch_pool));
 
-  /* Determine the working copy target's repository root URL. */
-  SVN_ERR(svn_client_get_repos_root(&wc_repos_root.url, &wc_repos_root.uuid,
-                                    target_abspath,
-                                    ctx, scratch_pool, scratch_pool));
-
   /* Open an RA session to our source URL, and determine its root URL. */
   sesspool = svn_pool_create(scratch_pool);
   SVN_ERR(svn_client__ra_session_from_path(
@@ -10786,7 +10835,7 @@ merge_peg_locked(const char *source_path
                                   scratch_pool, scratch_pool));
 
   /* Check for same_repos. */
-  same_repos = is_same_repos(&wc_repos_root, &source_repos_root,
+  same_repos = is_same_repos(&target->repos_root, &source_repos_root,
                              TRUE /* strict_urls */);
 
   /* We're done with our little RA session. */
@@ -10794,7 +10843,7 @@ merge_peg_locked(const char *source_path
 
   /* Do the real merge!  (We say with confidence that our merge
      sources are both ancestral and related.) */
-  err = do_merge(NULL, NULL, merge_sources, target_abspath,
+  err = do_merge(NULL, NULL, merge_sources, target,
                  TRUE, TRUE, same_repos, ignore_ancestry, force, dry_run,
                  record_only, NULL, FALSE, FALSE, depth, merge_options,
                  &use_sleep, ctx, scratch_pool, scratch_pool);

Modified: subversion/trunk/subversion/tests/cmdline/input_validation_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/input_validation_tests.py?rev=1229329&r1=1229328&r2=1229329&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/input_validation_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/input_validation_tests.py Mon Jan  9 19:53:22
2012
@@ -161,13 +161,13 @@ def invalid_merge_args(sbox):
                ('A@HEAD', '^/A')]:
     run_and_verify_svn_in_wc(sbox, "svn: E205000: Merge sources must both "
                              "be either paths or URLs", 'merge', *args)
-  run_and_verify_svn_in_wc(sbox, "svn: E155010: Path '.*' does not exist",
+  run_and_verify_svn_in_wc(sbox, "svn: E155010: .* was not found",
                            'merge', '^/@0', '^/@1', 'nonexistent')
   run_and_verify_svn_in_wc(sbox, "svn: E205000: Too many arguments given",
                           'merge', '-c42', '^/A/B', '^/A/C', 'iota')
   run_and_verify_svn_in_wc(sbox, "svn: E205000: Cannot specify a revision range with" +
                            " two URLs", 'merge', '-c42', '^/mu', '^/')
-  run_and_verify_svn_in_wc(sbox, "svn: E155010: Path '.*' does not exist",
+  run_and_verify_svn_in_wc(sbox, "svn: E155010: .* was not found",
                            'merge', '-c42', '^/mu', 'nonexistent')
 
 def invalid_wcpath_upgrade(sbox):

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=1229329&r1=1229328&r2=1229329&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/tree_conflict_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/tree_conflict_tests.py Mon Jan  9 19:53:22 2012
@@ -1258,7 +1258,7 @@ def actual_only_node_behaviour(sbox):
   # merge
   # note: this is intentionally a no-op merge that does not record mergeinfo
   expected_stdout = None
-  expected_stderr = ".*foo.*does not exist.*"
+  expected_stderr = ".*foo.*was not found.*"
   run_and_verify_svn(None, expected_stdout, expected_stderr,
                      "merge", '--ignore-ancestry', '-c', '4',
                      A_copy_url + '/mu', foo_path)



Mime
View raw message