You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2016/05/30 14:45:26 UTC

svn commit: r1746138 - /subversion/trunk/subversion/libsvn_client/conflicts.c

Author: stsp
Date: Mon May 30 14:45:26 2016
New Revision: 1746138

URL: http://svn.apache.org/viewvc?rev=1746138&view=rev
Log:
In the conflict resolver, start weeding out use of svn_ra_get_deleted_rev().

The ra_get_deleted_rev() function was good enough so far. But it will get
in the way once we start trying to find incoming moves in the log's changed
paths list.

* subversion/libsvn_client/conflicts.c
  (find_deleted_rev): Make the related repos_relpath/revision optional,
   so we can use this function in more contexts (e.g. forward update).
  (find_revision_for_suspected_deletion): Fix comment.
  (conflict_tree_get_details_incoming_delete): Replace use of
   svn_ra_get_deleted_rev() with our custom find_deleted_rev() log scan.

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

Modified: subversion/trunk/subversion/libsvn_client/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/conflicts.c?rev=1746138&r1=1746137&r2=1746138&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/conflicts.c (original)
+++ subversion/trunk/subversion/libsvn_client/conflicts.c Mon May 30 14:45:26 2016
@@ -252,8 +252,8 @@ struct find_deleted_rev_baton
 
 /* Implements svn_log_entry_receiver_t.
  *
- * Find the revision in which a node, ancestrally related to the node
- * specified via find_deleted_rev_baton, was deleted, When the revision
+ * Find the revision in which a node, optionally ancestrally related to the
+ * node specified via find_deleted_rev_baton, was deleted, When the revision
  * was found, store it in BATON->DELETED_REV and abort the log operation
  * by raising SVN_ERR_CANCELLED.
  *
@@ -302,30 +302,41 @@ find_deleted_rev(void *baton,
       if (svn_path_compare_paths(b->deleted_repos_relpath, path) == 0
           && (log_item->action == 'D' || log_item->action == 'R'))
         {
-          svn_client__pathrev_t *yca_loc;
-          svn_client__pathrev_t *loc1;
-          svn_client__pathrev_t *loc2;
-
-          /* We found a deleted node which occupies the correct path.
-           * To be certain that this is the deleted node we're looking for,
-           * we must establish whether it is ancestrally related to the
-           * "related node" specified in our baton. */
-          loc1 = svn_client__pathrev_create_with_relpath(
-                   b->repos_root_url, b->repos_uuid, b->related_repos_peg_rev,
-                   b->related_repos_relpath, iterpool);
-          loc2 = svn_client__pathrev_create_with_relpath(
-                   b->repos_root_url, b->repos_uuid, log_entry->revision - 1,
-                   b->deleted_repos_relpath, iterpool);
-          SVN_ERR(svn_client__get_youngest_common_ancestor(&yca_loc, loc1, loc2,
-                                                           NULL, b->ctx,
-                                                           iterpool,
-                                                           iterpool));
-          if (yca_loc != NULL)
+          svn_boolean_t deleted_node_found = TRUE;
+
+          if (b->related_repos_relpath != NULL &&
+              b->related_repos_peg_rev != SVN_INVALID_REVNUM)
+            {
+              svn_client__pathrev_t *yca_loc = NULL;
+              svn_client__pathrev_t *loc1;
+              svn_client__pathrev_t *loc2;
+
+              /* We found a deleted node which occupies the correct path.
+               * To be certain that this is the deleted node we're looking for,
+               * we must establish whether it is ancestrally related to the
+               * "related node" specified in our baton. */
+              loc1 = svn_client__pathrev_create_with_relpath(
+                       b->repos_root_url, b->repos_uuid,
+                       b->related_repos_peg_rev,
+                       b->related_repos_relpath, iterpool);
+              loc2 = svn_client__pathrev_create_with_relpath(
+                       b->repos_root_url, b->repos_uuid,
+                       log_entry->revision - 1,
+                       b->deleted_repos_relpath, iterpool);
+              SVN_ERR(svn_client__get_youngest_common_ancestor(&yca_loc,
+                                                               loc1, loc2,
+                                                               NULL, b->ctx,
+                                                               iterpool,
+                                                               iterpool));
+              deleted_node_found = (yca_loc != NULL);
+            }
+
+          if (deleted_node_found)
             {
               svn_string_t *author;
+
               /* Found the correct node, we are done. */
               b->deleted_rev = log_entry->revision;
-
               author = svn_hash_gets(log_entry->revprops,
                                      SVN_PROP_REVISION_AUTHOR);
               b->deleted_rev_author = apr_pstrdup(b->result_pool, author->data);
@@ -334,6 +345,7 @@ find_deleted_rev(void *baton,
                 b->replacing_node_kind = log_item->node_kind;
               else
                 b->replacing_node_kind = svn_node_none;
+
               return svn_error_create(SVN_ERR_CANCELLED, NULL, NULL);
             }
         }
@@ -841,7 +853,7 @@ find_revision_for_suspected_deletion(svn
       if (err->apr_err == SVN_ERR_CANCELLED &&
           b.deleted_rev != SVN_INVALID_REVNUM)
         {
-          /* Log operation was aborted because we found a YCA. */
+          /* Log operation was aborted because we found deleted rev. */
           svn_error_clear(err);
         }
       else
@@ -2145,11 +2157,23 @@ conflict_tree_get_details_incoming_delet
           svn_ra_session_t *ra_session;
           const char *url;
           const char *corrected_url;
-          svn_revnum_t deleted_rev;
-          svn_string_t *author_revprop;
+          const char *parent_repos_relpath;
+          apr_array_header_t *paths;
+          apr_array_header_t *revprops;
+          struct find_deleted_rev_baton b;
+          svn_error_t *err;
 
           /* The update operation went forward in history. */
-          url = svn_path_url_add_component2(repos_root_url, new_repos_relpath,
+          SVN_ERR(svn_wc__node_get_repos_info(NULL, &parent_repos_relpath,
+                                              NULL, NULL,
+                                              conflict->ctx->wc_ctx,
+                                              svn_dirent_dirname(
+                                                conflict->local_abspath,
+                                                scratch_pool),
+                                              scratch_pool,
+                                              scratch_pool));
+          url = svn_path_url_add_component2(repos_root_url,
+                                            parent_repos_relpath,
                                             scratch_pool);
           SVN_ERR(svn_client__open_ra_session_internal(&ra_session,
                                                        &corrected_url,
@@ -2159,22 +2183,50 @@ conflict_tree_get_details_incoming_delet
                                                        conflict->ctx,
                                                        scratch_pool,
                                                        scratch_pool));
-          SVN_ERR(svn_ra_get_deleted_rev(ra_session, "", old_rev, new_rev,
-                                         &deleted_rev, scratch_pool));
-          SVN_ERR(svn_ra_rev_prop(ra_session, deleted_rev,
-                                  SVN_PROP_REVISION_AUTHOR,
-                                  &author_revprop, scratch_pool));
+          paths = apr_array_make(scratch_pool, 1, sizeof(const char *));
+          APR_ARRAY_PUSH(paths, const char *) = "";
+
+          revprops = apr_array_make(scratch_pool, 1, sizeof(const char *));
+          APR_ARRAY_PUSH(revprops, const char *) = SVN_PROP_REVISION_AUTHOR;
+
+          b.deleted_repos_relpath = new_repos_relpath;
+          b.related_repos_relpath = NULL;
+          b.related_repos_peg_rev = SVN_INVALID_REVNUM;
+          b.deleted_rev = SVN_INVALID_REVNUM;
+          b.replacing_node_kind = svn_node_unknown;
+          b.repos_root_url = repos_root_url;
+          b.repos_uuid = repos_uuid;
+          b.ctx = conflict->ctx;
+          b.result_pool = scratch_pool;
+
+          err = svn_ra_get_log2(ra_session, paths, old_rev, new_rev,
+                                0, /* no limit */
+                                TRUE, /* need the changed paths list */
+                                FALSE, /* need to traverse copies */
+                                FALSE, /* no need for merged revisions */
+                                revprops,
+                                find_deleted_rev, &b,
+                                scratch_pool);
+          if (err)
+            {
+              if (err->apr_err == SVN_ERR_CANCELLED &&
+                  b.deleted_rev != SVN_INVALID_REVNUM)
+                {
+                  /* Log operation was aborted because we found deleted rev. */
+                  svn_error_clear(err);
+                }
+              else
+                return svn_error_trace(err);
+            }
+
           details = apr_pcalloc(conflict->pool, sizeof(*details));
-          details->deleted_rev = deleted_rev;
+          details->deleted_rev = b.deleted_rev;
           details->added_rev = SVN_INVALID_REVNUM;
           details->repos_relpath = apr_pstrdup(conflict->pool,
                                                new_repos_relpath);
           details->rev_author = apr_pstrdup(conflict->pool,
-                                            author_revprop->data);
-          /* Check for replacement. */
-          SVN_ERR(svn_ra_check_path(ra_session, "", deleted_rev,
-                                    &details->replacing_node_kind,
-                                    scratch_pool));
+                                            b.deleted_rev_author);
+          details->replacing_node_kind = b.replacing_node_kind;
         }
       else /* new_rev < old_rev */
         {