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 2010/06/15 12:16:22 UTC

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

Author: rhuijben
Date: Tue Jun 15 10:16:21 2010
New Revision: 954789

URL: http://svn.apache.org/viewvc?rev=954789&view=rev
Log:
Update the last few remaining places in the merge code to assume absolute
paths instead of converting to them on every invocation.

* subversion/libsvn_client/merge.c
  (obstructed_or_missing): Accept only absolute paths.
  (merge_props_changed): Pass absolute paths
  (merge_file_changed): Don't convert paths and update callers. Move
    file instead of copy + delete.
  (merge_file_added, merge_file_deleted, merge_dir_added,
   merge_dir_deleted): Assume absolute paths are passed.

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=954789&r1=954788&r2=954789&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/merge.c (original)
+++ subversion/trunk/subversion/libsvn_client/merge.c Tue Jun 15 10:16:21 2010
@@ -368,7 +368,7 @@ is_path_conflicted_by_merge(merge_cmd_ba
 }
 
 /* Return a state indicating whether the WC metadata matches the
- * node kind on disk of the local path PATH.
+ * node kind on disk of the local path LOCAL_ABSPATH.
  * Use MERGE_B to determine the dry-run details; particularly, if a dry run
  * noted that it deleted this path, assume matching node kinds (as if both
  * kinds were svn_node_none).
@@ -379,26 +379,25 @@ is_path_conflicted_by_merge(merge_cmd_ba
  *   - Return 'missing' if there is no node on disk but one is expected.
  *     Also return 'missing' for absent nodes (not here due to authz).*/
 static svn_wc_notify_state_t
-obstructed_or_missing(const char *path,
+obstructed_or_missing(const char *local_abspath,
                       const char *local_dir_abspath,
                       const merge_cmd_baton_t *merge_b,
                       apr_pool_t *pool)
 {
   svn_error_t *err;
   svn_node_kind_t kind_expected, kind_on_disk;
-  const char *local_abspath;
+
+  SVN_ERR_ASSERT_NO_RETURN(svn_dirent_is_absolute(local_abspath));
 
   /* In a dry run, make as if nodes "deleted" by the dry run appear so. */
-  if (merge_b->dry_run && dry_run_deleted_p(merge_b, path))
+  if (merge_b->dry_run && dry_run_deleted_p(merge_b, local_abspath))
     return svn_wc_notify_state_inapplicable;
 
   /* Since this function returns no svn_error_t, we make all errors look like
    * no node found in the wc. */
-  err = svn_dirent_get_absolute(&local_abspath, path, pool);
 
-  if (!err)
-    err = svn_wc_read_kind(&kind_expected, merge_b->ctx->wc_ctx,
-                           local_abspath, FALSE, pool);
+  err = svn_wc_read_kind(&kind_expected, merge_b->ctx->wc_ctx,
+                         local_abspath, FALSE, pool);
 
   if (err)
     {
@@ -1063,7 +1062,7 @@ static svn_error_t *
 merge_props_changed(const char *local_dir_abspath,
                     svn_wc_notify_state_t *state,
                     svn_boolean_t *tree_conflicted,
-                    const char *path,
+                    const char *local_abspath,
                     const apr_array_header_t *propchanges,
                     apr_hash_t *original_props,
                     void *baton,
@@ -1074,9 +1073,8 @@ merge_props_changed(const char *local_di
   svn_client_ctx_t *ctx = merge_b->ctx;
   apr_pool_t *subpool = svn_pool_create(merge_b->pool);
   svn_error_t *err;
-  const char *local_abspath;
 
-  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, subpool));
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
   if (tree_conflicted)
     *tree_conflicted = FALSE;
@@ -1085,8 +1083,8 @@ merge_props_changed(const char *local_di
   {
     svn_wc_notify_state_t obstr_state;
 
-    obstr_state = obstructed_or_missing(path, local_dir_abspath, merge_b,
-                                        subpool);
+    obstr_state = obstructed_or_missing(local_abspath, local_dir_abspath,
+                                        merge_b, subpool);
     if (obstr_state != svn_wc_notify_state_inapplicable)
       {
         if (state)
@@ -1274,9 +1272,9 @@ merge_file_changed(const char *local_dir
                    svn_wc_notify_state_t *content_state,
                    svn_wc_notify_state_t *prop_state,
                    svn_boolean_t *tree_conflicted,
-                   const char *mine,
-                   const char *older,
-                   const char *yours,
+                   const char *mine_abspath,
+                   const char *older_abspath,
+                   const char *yours_abspath,
                    svn_revnum_t older_rev,
                    svn_revnum_t yours_rev,
                    const char *mimetype1,
@@ -1290,19 +1288,10 @@ merge_file_changed(const char *local_dir
   apr_pool_t *subpool = svn_pool_create(merge_b->pool);
   svn_boolean_t merge_required = TRUE;
   enum svn_wc_merge_outcome_t merge_outcome;
-  const char *older_abspath;
-  const char *yours_abspath;
-  const char *mine_abspath;
 
-  if (older)
-    SVN_ERR(svn_dirent_get_absolute(&older_abspath, older, merge_b->pool));
-  else
-    older_abspath = NULL;
-  if (yours)
-    SVN_ERR(svn_dirent_get_absolute(&yours_abspath, yours, merge_b->pool));
-  else
-    yours_abspath = NULL;
-  SVN_ERR(svn_dirent_get_absolute(&mine_abspath, mine, merge_b->pool));
+  SVN_ERR_ASSERT(mine_abspath && svn_dirent_is_absolute(mine_abspath));
+  SVN_ERR_ASSERT(!older_abspath || svn_dirent_is_absolute(older_abspath));
+  SVN_ERR_ASSERT(!yours_abspath || svn_dirent_is_absolute(yours_abspath));
 
   if (tree_conflicted)
     *tree_conflicted = FALSE;
@@ -1326,8 +1315,8 @@ merge_file_changed(const char *local_dir
   {
     svn_wc_notify_state_t obstr_state;
 
-    obstr_state = obstructed_or_missing(mine, local_dir_abspath, merge_b,
-                                        subpool);
+    obstr_state = obstructed_or_missing(mine_abspath, local_dir_abspath,
+                                        merge_b, subpool);
     if (obstr_state != svn_wc_notify_state_inapplicable)
       {
         if (content_state)
@@ -1347,7 +1336,7 @@ merge_file_changed(const char *local_dir
 
     SVN_ERR(svn_wc_read_kind(&wc_kind, merge_b->ctx->wc_ctx, mine_abspath,
                              FALSE, subpool));
-    SVN_ERR(svn_io_check_path(mine, &kind, subpool));
+    SVN_ERR(svn_io_check_path(mine_abspath, &kind, subpool));
 
     /* If the file isn't there due to depth restrictions, do not flag
      * a conflict. Non-inheritable mergeinfo will be recorded, allowing
@@ -1415,7 +1404,7 @@ merge_file_changed(const char *local_dir
 
       SVN_ERR(merge_props_changed(local_dir_abspath, prop_state,
                                   &tree_conflicted2,
-                                  mine, prop_changes, original_props,
+                                  mine_abspath, prop_changes, original_props,
                                   baton, scratch_pool));
 
       /* If the prop change caused a tree-conflict, just bail. */
@@ -1440,7 +1429,7 @@ merge_file_changed(const char *local_dir
       return SVN_NO_ERROR;
     }
 
-  if (older)
+  if (older_abspath)
     {
       svn_boolean_t has_local_mods;
       SVN_ERR(svn_wc_text_modified_p2(&has_local_mods, merge_b->ctx->wc_ctx,
@@ -1466,14 +1455,14 @@ merge_file_changed(const char *local_dir
           svn_boolean_t same_contents;
           SVN_ERR(svn_io_files_contents_same_p(&same_contents,
                                                (older_revision_exists ?
-                                                older : yours),
-                                               mine, subpool));
+                                                older_abspath : yours_abspath),
+                                               mine_abspath, subpool));
           if (same_contents)
             {
               if (older_revision_exists && !merge_b->dry_run)
                 {
-                  SVN_ERR(svn_io_copy_file(yours, mine, FALSE, subpool));
-                  SVN_ERR(svn_io_remove_file2(yours, TRUE, subpool));
+                  SVN_ERR(svn_io_file_rename(yours_abspath, mine_abspath,
+                                             subpool));
                 }
               merge_outcome = svn_wc_merge_merged;
               merge_required = FALSE;
@@ -1541,9 +1530,9 @@ merge_file_added(const char *local_dir_a
                  svn_wc_notify_state_t *content_state,
                  svn_wc_notify_state_t *prop_state,
                  svn_boolean_t *tree_conflicted,
-                 const char *mine,
-                 const char *older,
-                 const char *yours,
+                 const char *mine_abspath,
+                 const char *older_abspath,
+                 const char *yours_abspath,
                  svn_revnum_t rev1,
                  svn_revnum_t rev2,
                  const char *mimetype1,
@@ -1561,7 +1550,8 @@ merge_file_added(const char *local_dir_a
   svn_node_kind_t kind;
   int i;
   apr_hash_t *file_props;
-  const char *mine_abspath;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(mine_abspath));
 
   /* Easy out: We are only applying mergeinfo differences. */
   if (merge_b->record_only)
@@ -1576,8 +1566,6 @@ merge_file_added(const char *local_dir_a
       return SVN_NO_ERROR;
     }
 
-  SVN_ERR(svn_dirent_get_absolute(&mine_abspath, mine, subpool));
-
   /* In most cases, we just leave prop_state as unknown, and let the
      content_state what happened, so we set prop_state here to avoid that
      below. */
@@ -1622,7 +1610,7 @@ merge_file_added(const char *local_dir_a
   if (! local_dir_abspath)
     {
       if (merge_b->dry_run && merge_b->added_path
-          && svn_dirent_is_child(merge_b->added_path, mine, subpool))
+          && svn_dirent_is_child(merge_b->added_path, mine_abspath, NULL))
         {
           if (content_state)
             *content_state = svn_wc_notify_state_changed;
@@ -1643,8 +1631,8 @@ merge_file_added(const char *local_dir_a
   {
     svn_wc_notify_state_t obstr_state;
 
-    obstr_state = obstructed_or_missing(mine, local_dir_abspath, merge_b,
-                                        subpool);
+    obstr_state = obstructed_or_missing(mine_abspath, local_dir_abspath,
+                                        merge_b, subpool);
     if (obstr_state != svn_wc_notify_state_inapplicable)
       {
         if (content_state)
@@ -1656,7 +1644,7 @@ merge_file_added(const char *local_dir_a
 
   parent_abspath = local_dir_abspath;
 
-  SVN_ERR(svn_io_check_path(mine, &kind, subpool));
+  SVN_ERR(svn_io_check_path(mine_abspath, &kind, subpool));
   switch (kind)
     {
     case svn_node_none:
@@ -1675,7 +1663,7 @@ merge_file_added(const char *local_dir_a
             if (merge_b->same_repos)
               {
                 const char *child = svn_dirent_is_child(merge_b->target_abspath,
-                                                        mine, subpool);
+                                                        mine_abspath, subpool);
                 if (child != NULL)
                   copyfrom_url = svn_path_url_add_component2(
                                                merge_b->merge_source.url2,
@@ -1688,7 +1676,8 @@ merge_file_added(const char *local_dir_a
                                            copyfrom_url, subpool));
                 new_base_props = file_props;
                 new_props = NULL; /* inherit from new_base_props */
-                SVN_ERR(svn_stream_open_readonly(&new_base_contents, yours,
+                SVN_ERR(svn_stream_open_readonly(&new_base_contents,
+                                                 yours_abspath,
                                                  subpool, subpool));
                 new_contents = NULL; /* inherit from new_base_contents */
               }
@@ -1699,7 +1688,7 @@ merge_file_added(const char *local_dir_a
                 new_base_props = apr_hash_make(subpool);
                 new_props = file_props;
                 new_base_contents = svn_stream_empty(subpool);
-                SVN_ERR(svn_stream_open_readonly(&new_contents, yours,
+                SVN_ERR(svn_stream_open_readonly(&new_contents, yours_abspath,
                                                  subpool, subpool));
               }
 
@@ -1763,7 +1752,8 @@ merge_file_added(const char *local_dir_a
           SVN_ERR(svn_wc_read_kind(&wc_kind, merge_b->ctx->wc_ctx,
                                    mine_abspath, FALSE, subpool));
 
-          if ((wc_kind != svn_node_none) && dry_run_deleted_p(merge_b, mine))
+          if ((wc_kind != svn_node_none) 
+              && dry_run_deleted_p(merge_b, mine_abspath))
             *content_state = svn_wc_notify_state_changed;
           else
             /* this will make the repos_editor send a 'skipped' message */
@@ -1772,7 +1762,7 @@ merge_file_added(const char *local_dir_a
       break;
     case svn_node_file:
       {
-            if (dry_run_deleted_p(merge_b, mine))
+            if (dry_run_deleted_p(merge_b, mine_abspath))
               {
                 if (content_state)
                   *content_state = svn_wc_notify_state_changed;
@@ -1872,9 +1862,9 @@ static svn_error_t *
 merge_file_deleted(const char *local_dir_abspath,
                    svn_wc_notify_state_t *state,
                    svn_boolean_t *tree_conflicted,
-                   const char *mine,
-                   const char *older,
-                   const char *yours,
+                   const char *mine_abspath,
+                   const char *older_abspath,
+                   const char *yours_abspath,
                    const char *mimetype1,
                    const char *mimetype2,
                    apr_hash_t *original_props,
@@ -1884,7 +1874,6 @@ merge_file_deleted(const char *local_dir
   merge_cmd_baton_t *merge_b = baton;
   apr_pool_t *subpool = svn_pool_create(merge_b->pool);
   svn_node_kind_t kind;
-  const char *mine_abspath;
 
   /* Easy out: We are only applying mergeinfo differences. */
   if (merge_b->record_only)
@@ -1897,8 +1886,6 @@ merge_file_deleted(const char *local_dir
       return SVN_NO_ERROR;
     }
 
-  SVN_ERR(svn_dirent_get_absolute(&mine_abspath, mine, subpool));
-
   if (tree_conflicted)
     *tree_conflicted = FALSE;
 
@@ -1918,8 +1905,8 @@ merge_file_deleted(const char *local_dir
   {
     svn_wc_notify_state_t obstr_state;
 
-    obstr_state = obstructed_or_missing(mine, local_dir_abspath, merge_b,
-                                        subpool);
+    obstr_state = obstructed_or_missing(mine_abspath, local_dir_abspath,
+                                        merge_b, subpool);
     if (obstr_state != svn_wc_notify_state_inapplicable)
       {
         if (state)
@@ -1929,15 +1916,12 @@ merge_file_deleted(const char *local_dir
       }
   }
 
-  SVN_ERR(svn_io_check_path(mine, &kind, subpool));
+  SVN_ERR(svn_io_check_path(mine_abspath, &kind, subpool));
   switch (kind)
     {
     case svn_node_file:
       {
         svn_boolean_t same;
-        const char *older_abspath;
-
-        SVN_ERR(svn_dirent_get_absolute(&older_abspath, older, subpool));
 
         /* If the files are identical, attempt deletion */
         SVN_ERR(files_same_p(&same, older_abspath, original_props,
@@ -1946,7 +1930,7 @@ merge_file_deleted(const char *local_dir
           {
             /* Passing NULL for the notify_func and notify_baton because
                repos_diff.c:delete_entry() will do it for us. */
-            SVN_ERR(svn_client__wc_delete(mine, TRUE,
+            SVN_ERR(svn_client__wc_delete(mine_abspath, TRUE,
                                           merge_b->dry_run, FALSE, NULL, NULL,
                                           merge_b->ctx, subpool));
             if (state)
@@ -2013,7 +1997,7 @@ static svn_error_t *
 merge_dir_added(const char *local_dir_abspath,
                 svn_wc_notify_state_t *state,
                 svn_boolean_t *tree_conflicted,
-                const char *path,
+                const char *local_abspath,
                 svn_revnum_t rev,
                 const char *copyfrom_path,
                 svn_revnum_t copyfrom_revision,
@@ -2026,7 +2010,6 @@ merge_dir_added(const char *local_dir_ab
   const char *copyfrom_url = NULL, *child;
   svn_revnum_t copyfrom_rev = SVN_INVALID_REVNUM;
   const char *parent_abspath;
-  const char *local_abspath;
   svn_boolean_t is_versioned;
   svn_boolean_t is_deleted;
   svn_error_t *err;
@@ -2042,7 +2025,6 @@ merge_dir_added(const char *local_dir_ab
       return SVN_NO_ERROR;
     }
 
-  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, subpool));
   parent_abspath = local_dir_abspath;
 
   if (tree_conflicted)
@@ -2057,7 +2039,7 @@ merge_dir_added(const char *local_dir_ab
       if (state)
         {
           if (merge_b->dry_run && merge_b->added_path
-              && svn_dirent_is_child(merge_b->added_path, path, subpool))
+              && svn_dirent_is_child(merge_b->added_path, local_abspath, NULL))
             *state = svn_wc_notify_state_changed;
           else
             *state = svn_wc_notify_state_missing;
@@ -2070,7 +2052,7 @@ merge_dir_added(const char *local_dir_ab
       return SVN_NO_ERROR;
     }
 
-  child = svn_dirent_is_child(merge_b->target_abspath, path, subpool);
+  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,
@@ -2105,14 +2087,14 @@ merge_dir_added(const char *local_dir_ab
       is_versioned = TRUE;
     }
 
-  SVN_ERR(svn_io_check_path(path, &kind, subpool));
+  SVN_ERR(svn_io_check_path(local_abspath, &kind, subpool));
 
   /* Check for an obstructed or missing node on disk. */
   {
     svn_wc_notify_state_t obstr_state;
 
-    obstr_state = obstructed_or_missing(path, local_dir_abspath, merge_b,
-                                        subpool);
+    obstr_state = obstructed_or_missing(local_abspath, local_dir_abspath,
+                                        merge_b, subpool);
 
     /* 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
@@ -2137,10 +2119,10 @@ merge_dir_added(const char *local_dir_ab
     case svn_node_none:
       /* Unversioned or schedule-delete */
       if (merge_b->dry_run)
-        merge_b->added_path = apr_pstrdup(merge_b->pool, path);
+        merge_b->added_path = apr_pstrdup(merge_b->pool, local_abspath);
       else
         {
-          SVN_ERR(svn_io_make_dir_recursively(path, subpool));
+          SVN_ERR(svn_io_make_dir_recursively(local_abspath, subpool));
           SVN_ERR(svn_wc_add4(merge_b->ctx->wc_ctx, local_abspath,
                               svn_depth_infinity,
                               copyfrom_url, copyfrom_rev,
@@ -2168,14 +2150,14 @@ merge_dir_added(const char *local_dir_ab
                                 NULL, NULL, /* no notification func! */
                                 subpool));
           else
-            merge_b->added_path = apr_pstrdup(merge_b->pool, path);
+            merge_b->added_path = apr_pstrdup(merge_b->pool, local_abspath);
           if (state)
             *state = svn_wc_notify_state_changed;
         }
       else
         {
           /* The dir is known to Subversion as already existing. */
-          if (dry_run_deleted_p(merge_b, path))
+          if (dry_run_deleted_p(merge_b, local_abspath))
             {
               if (state)
                 *state = svn_wc_notify_state_changed;
@@ -2198,7 +2180,7 @@ merge_dir_added(const char *local_dir_ab
       if (merge_b->dry_run)
         merge_b->added_path = NULL;
 
-      if (is_versioned && dry_run_deleted_p(merge_b, path))
+      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
@@ -2235,7 +2217,7 @@ static svn_error_t *
 merge_dir_deleted(const char *local_dir_abspath,
                   svn_wc_notify_state_t *state,
                   svn_boolean_t *tree_conflicted,
-                  const char *path,
+                  const char *local_abspath,
                   void *baton,
                   apr_pool_t *scratch_pool)
 {
@@ -2243,7 +2225,6 @@ merge_dir_deleted(const char *local_dir_
   apr_pool_t *subpool = svn_pool_create(merge_b->pool);
   svn_node_kind_t kind;
   svn_error_t *err;
-  const char *local_abspath;
   svn_boolean_t is_versioned;
   svn_boolean_t is_deleted;
 
@@ -2258,8 +2239,6 @@ merge_dir_deleted(const char *local_dir_
       return SVN_NO_ERROR;
     }
 
-  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, subpool));
-
   if (tree_conflicted)
     *tree_conflicted = FALSE;
 
@@ -2303,8 +2282,8 @@ merge_dir_deleted(const char *local_dir_
   {
     svn_wc_notify_state_t obstr_state;
 
-    obstr_state = obstructed_or_missing(path, local_dir_abspath, merge_b,
-                                        subpool);
+    obstr_state = obstructed_or_missing(local_abspath, local_dir_abspath,
+                                        merge_b, subpool);
     if (obstr_state != svn_wc_notify_state_inapplicable)
       {
         if (state)
@@ -2315,7 +2294,7 @@ merge_dir_deleted(const char *local_dir_
   }
 
   /* Switch on the on-disk state of this path */
-  SVN_ERR(svn_io_check_path(path, &kind, subpool));
+  SVN_ERR(svn_io_check_path(local_abspath, &kind, subpool));
   switch (kind)
     {
     case svn_node_dir:
@@ -2331,7 +2310,7 @@ merge_dir_deleted(const char *local_dir_
 
             /* Passing NULL for the notify_func and notify_baton because
                repos_diff.c:delete_entry() will do it for us. */
-            err = svn_client__wc_delete(path, merge_b->force,
+            err = svn_client__wc_delete(local_abspath, merge_b->force,
                                         merge_b->dry_run, FALSE,
                                         NULL, NULL,
                                         merge_b->ctx, subpool);