subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cmpil...@apache.org
Subject svn commit: r1354571 [4/37] - in /subversion/branches/master-passphrase: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ build/win32/ contrib/client-side/emacs/ contrib/server-side/ notes/ notes/api-errata/1.8/ notes/directory-in...
Date Wed, 27 Jun 2012 15:13:42 GMT
Modified: subversion/branches/master-passphrase/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/include/svn_wc.h?rev=1354571&r1=1354570&r2=1354571&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/include/svn_wc.h (original)
+++ subversion/branches/master-passphrase/subversion/include/svn_wc.h Wed Jun 27 15:12:37 2012
@@ -1219,7 +1219,22 @@ typedef enum svn_wc_notify_action_t
 
   /** The operation skipped the path because it was conflicted.
    * @since New in 1.7. */
-  svn_wc_notify_skip_conflicted
+  svn_wc_notify_skip_conflicted,
+
+  /** Just the lock on a file was removed during update.
+   * @since New in 1.8. */
+  svn_wc_notify_update_broken_lock,
+
+  /** Operation failed because a node is obstructed.
+   * @since New in 1.8. */
+  svn_wc_notify_failed_obstruction,
+
+  /** Conflict resolver is starting or done.
+   * This can be used by clients to detect when to display conflict summary
+   * information, for example.
+   * @since New in 1.8. */
+  svn_wc_notify_conflict_resolver_starting,
+  svn_wc_notify_conflict_resolver_done
 
 } svn_wc_notify_action_t;
 
@@ -1634,14 +1649,17 @@ typedef struct svn_wc_conflict_version_t
   svn_revnum_t peg_rev;
 
   /** path within repos; must not start with '/' */
+   /* ### should have been called repos_relpath, but we can't change this. */
   const char *path_in_repos;
-  /* @todo We may decide to add the repository UUID, to handle conflicts
-   * properly during a repository move. */
   /** @} */
 
   /** Info about this node */
   svn_node_kind_t node_kind;  /* note that 'none' is a legitimate value */
 
+  /** UUID of the repository
+   * @since New in 1.8. */
+  const char *repos_uuid;
+
   /* @todo Add metadata about a local copy of the node, if and when
    * we store one. */
 
@@ -1658,8 +1676,23 @@ typedef struct svn_wc_conflict_version_t
  * @a peg_rev and the the @c node_kind to @c node_kind. Make only shallow
  * copies of the pointer arguments.
  *
+ * @since New in 1.8.
+ */
+svn_wc_conflict_version_t *
+svn_wc_conflict_version_create2(const char *repos_root_url,
+                                const char *repos_uuid,
+                                const char *repos_relpath,
+                                svn_revnum_t revision,
+                                svn_node_kind_t kind,
+                                apr_pool_t *result_pool);
+
+/** Similar to svn_wc_conflict_version_create2(), but doesn't set all
+ * required values.
+ *
  * @since New in 1.6.
+ * @deprecated Provided for backward compatibility with the 1.7 API.
  */
+SVN_DEPRECATED
 svn_wc_conflict_version_t *
 svn_wc_conflict_version_create(const char *repos_url,
                                const char *path_in_repos,
@@ -1689,9 +1722,9 @@ svn_wc_conflict_version_dup(const svn_wc
  * @note Fields may be added to the end of this structure in future
  * versions.  Therefore, to preserve binary compatibility, users
  * should not directly allocate structures of this type but should use
- * svn_wc_create_conflict_description_text2() or
- * svn_wc_create_conflict_description_prop2() or
- * svn_wc_create_conflict_description_tree2() instead.
+ * svn_wc_conflict_description_create_text2() or
+ * svn_wc_conflict_description_create_prop2() or
+ * svn_wc_conflict_description_create_tree2() instead.
  *
  * @since New in 1.7.
  */
@@ -2011,7 +2044,10 @@ typedef enum svn_wc_conflict_choice_t
   svn_wc_conflict_choose_mine_full,       /**< own version */
   svn_wc_conflict_choose_theirs_conflict, /**< incoming (for conflicted hunks) */
   svn_wc_conflict_choose_mine_conflict,   /**< own (for conflicted hunks) */
-  svn_wc_conflict_choose_merged           /**< merged version */
+  svn_wc_conflict_choose_merged,          /**< merged version */
+
+  /* @since New in 1.8. */
+  svn_wc_conflict_choose_unspecified      /**< undecided */
 
 } svn_wc_conflict_choice_t;
 
@@ -2616,24 +2652,22 @@ svn_wc_has_binary_prop(svn_boolean_t *ha
  * with regard to the base revision, else set @a *modified_p to zero.
  * @a local_abspath is the absolute path to the file.
  *
- * If @a force_comparison is @c TRUE, this function will not allow
- * early return mechanisms that avoid actual content comparison.
- * Instead, if there is a text base, a full byte-by-byte comparison
- * will be done, and the entry checksum verified as well.  (This means
- * that if the text base is much longer than the working file, every
- * byte of the text base will still be examined.)
+ * This function uses some heuristics to avoid byte-by-byte comparisons
+ * against the base text (eg. file size and its modification time).
  *
  * If @a local_abspath does not exist, consider it unmodified.  If it exists
  * but is not under revision control (not even scheduled for
  * addition), return the error #SVN_ERR_ENTRY_NOT_FOUND.
  *
+ * @a unused is ignored.
+ *
  * @since New in 1.7.
  */
 svn_error_t *
 svn_wc_text_modified_p2(svn_boolean_t *modified_p,
                         svn_wc_context_t *wc_ctx,
                         const char *local_abspath,
-                        svn_boolean_t force_comparison,
+                        svn_boolean_t unused,
                         apr_pool_t *scratch_pool);
 
 /** Similar to svn_wc_text_modified_p2(), but with a relative path and
@@ -5852,23 +5886,6 @@ svn_wc_get_switch_editor(svn_revnum_t *t
  * @{
  */
 
-/* A word about the implementation of working copy property storage:
- *
- * Since properties are key/val pairs, you'd think we store them in
- * some sort of Berkeley DB-ish format, and even store pending changes
- * to them that way too.
- *
- * However, we already have libsvn_subr/hashdump.c working, and it
- * uses a human-readable format.  That will be very handy when we're
- * debugging, and presumably we will not be dealing with any huge
- * properties or property lists initially.  Therefore, we will
- * continue to use hashdump as the internal mechanism for storing and
- * reading from property lists, but note that the interface here is
- * _not_ dependent on that.  We can swap in a DB-based implementation
- * at any time and users of this library will never know the
- * difference.
- */
-
 /** Set @a *props to a hash table mapping <tt>char *</tt> names onto
  * <tt>svn_string_t *</tt> values for all the regular properties of
  * @a local_abspath.  Allocate the table, names, and values in
@@ -6588,7 +6605,7 @@ typedef enum svn_wc_merge_outcome_t
  * receive the changes, then translated back again.
  *
  * If @a target_abspath is absent, or present but not under version
- * control, then set @a *merge_outcome to #svn_wc_merge_no_merge and
+ * control, then set @a *merge_content_outcome to #svn_wc_merge_no_merge and
  * return success without merging anything.  (The reasoning is that if
  * the file is not versioned, then it is probably unrelated to the
  * changes being considered, so they should not be merged into it.
@@ -6606,8 +6623,16 @@ typedef enum svn_wc_merge_outcome_t
  * svn_diff_file_options_parse()).  @a merge_options must contain
  * <tt>const char *</tt> elements.
  *
- * The outcome of the merge is returned in @a *merge_outcome. If there
- * is a conflict and @a dry_run is @c FALSE, then attempt to call @a
+ * If @a merge_props_state is non-NULL @a propchanges is merged before
+ * merging the text. (If @a merge_props_outcome is NULL, no property changes
+*  are merged and @a prop_changes is only used to determine the merge result)
+ * The result of the property merge is stored in @a *merge_props_state. If
+ * there is a conflict and @a dry_run is @c FALSE, then attempt to call @a
+ * conflict_func with @a conflict_baton (if non-NULL).  If the conflict
+ * callback cannot resolve the conflict, then a property conflict is installed.
+ *
+ * The outcome of the text merge is returned in @a *merge_text_outcome. If
+ * there is a conflict and @a dry_run is @c FALSE, then attempt to call @a
  * conflict_func with @a conflict_baton (if non-NULL).  If the
  * conflict callback cannot resolve the conflict, then:
  *
@@ -6642,8 +6667,39 @@ typedef enum svn_wc_merge_outcome_t
  *
  * Use @a scratch_pool for any temporary allocation.
  *
+ * @since New in 1.8.
+ */ /* ### BH: Two kinds of outcome is not how it should be */
+svn_error_t *
+svn_wc_merge5(enum svn_wc_merge_outcome_t *merge_content_outcome,
+              enum svn_wc_notify_state_t *merge_props_state,
+              svn_wc_context_t *wc_ctx,
+              const char *left_abspath,
+              const char *right_abspath,
+              const char *target_abspath,
+              const char *left_label,
+              const char *right_label,
+              const char *target_label,
+              const svn_wc_conflict_version_t *left_version,
+              const svn_wc_conflict_version_t *right_version,
+              svn_boolean_t dry_run,
+              const char *diff3_cmd,
+              const apr_array_header_t *merge_options,
+              apr_hash_t *original_props,
+              const apr_array_header_t *prop_diff,
+              svn_wc_conflict_resolver_func2_t conflict_func,
+              void *conflict_baton,
+              svn_cancel_func_t cancel_func,
+              void *cancel_baton,
+              apr_pool_t *scratch_pool);
+
+/** Similar to svn_wc_merge4() but doesn't allow property changes. Instead of
+ * handling this in a single operation, a separate call to svn_wc_merge_props3()
+ * before calling svn_wc_merge4() is needed
+ *
  * @since New in 1.7.
+ * @deprecated Provided for backwards compatibility with the 1.7 API.
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_wc_merge4(enum svn_wc_merge_outcome_t *merge_outcome,
               svn_wc_context_t *wc_ctx,
@@ -6665,6 +6721,7 @@ svn_wc_merge4(enum svn_wc_merge_outcome_
               void *cancel_baton,
               apr_pool_t *scratch_pool);
 
+
 /** Similar to svn_wc_merge4() but takes relative paths and an access
  * baton. It doesn't support a cancel function or tracking origin version
  * information.

Modified: subversion/branches/master-passphrase/subversion/include/svn_xml.h
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/include/svn_xml.h?rev=1354571&r1=1354570&r2=1354571&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/include/svn_xml.h (original)
+++ subversion/branches/master-passphrase/subversion/include/svn_xml.h Wed Jun 27 15:12:37 2012
@@ -228,7 +228,7 @@ svn_xml_signal_bailout(svn_error_t *erro
  */
 const char *
 svn_xml_get_attr_value(const char *name,
-                       const char **atts);
+                       const char *const *atts);
 
 
 

Modified: subversion/branches/master-passphrase/subversion/libsvn_auth_kwallet/kwallet.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_auth_kwallet/kwallet.cpp?rev=1354571&r1=1354570&r2=1354571&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_auth_kwallet/kwallet.cpp (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_auth_kwallet/kwallet.cpp Wed Jun 27 15:12:37 2012
@@ -60,6 +60,9 @@
 /* KWallet simple provider, puts passwords in KWallet                    */
 /*-----------------------------------------------------------------------*/
 
+static int q_argc = 1;
+static char q_argv0[] = "svn"; // Build non-const char * from string constant
+static char *q_argv[] = { q_argv0 };
 
 static const char *
 get_application_name(apr_hash_t *parameters,
@@ -212,12 +215,11 @@ kwallet_password_get(svn_boolean_t *done
   QCoreApplication *app;
   if (! qApp)
     {
-      int argc = 1;
-      app = new QCoreApplication(argc, (char *[1]) {(char *) "svn"});
+      int argc = q_argc;
+      app = new QCoreApplication(argc, q_argv);
     }
 
-  KCmdLineArgs::init(1,
-                     (char *[1]) {(char *) "svn"},
+  KCmdLineArgs::init(q_argc, q_argv,
                      get_application_name(parameters, pool),
                      "subversion",
                      ki18n(get_application_name(parameters, pool)),
@@ -289,12 +291,11 @@ kwallet_password_set(svn_boolean_t *done
   QCoreApplication *app;
   if (! qApp)
     {
-      int argc = 1;
-      app = new QCoreApplication(argc, (char *[1]) {(char *) "svn"});
+      int argc = q_argc;
+      app = new QCoreApplication(argc, q_argv);
     }
 
-  KCmdLineArgs::init(1,
-                     (char *[1]) {(char *) "svn"},
+  KCmdLineArgs::init(q_argc, q_argv,
                      get_application_name(parameters, pool),
                      "subversion",
                      ki18n(get_application_name(parameters, pool)),

Modified: subversion/branches/master-passphrase/subversion/libsvn_client/add.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_client/add.c?rev=1354571&r1=1354570&r2=1354571&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_client/add.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_client/add.c Wed Jun 27 15:12:37 2012
@@ -898,8 +898,8 @@ mkdir_urls(const apr_array_header_t *url
 
   /* Fetch RA commit editor */
   SVN_ERR(svn_ra__register_editor_shim_callbacks(ra_session,
-                        svn_client__get_shim_callbacks(ctx->wc_ctx,
-                                                       NULL, pool)));
+                        svn_client__get_shim_callbacks(ctx->wc_ctx, NULL,
+                                                       pool)));
   SVN_ERR(svn_ra_get_commit_editor3(ra_session, &editor, &edit_baton,
                                     commit_revprops,
                                     commit_callback,

Modified: subversion/branches/master-passphrase/subversion/libsvn_client/blame.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_client/blame.c?rev=1354571&r1=1354570&r2=1354571&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_client/blame.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_client/blame.c Wed Jun 27 15:12:37 2012
@@ -593,6 +593,7 @@ svn_client_blame5(const char *target,
   struct file_rev_baton frb;
   svn_ra_session_t *ra_session;
   svn_revnum_t start_revnum, end_revnum;
+  svn_client__pathrev_t *end_loc;
   struct blame *walk, *walk_merged = NULL;
   apr_pool_t *iterpool;
   svn_stream_t *last_stream;
@@ -610,9 +611,10 @@ svn_client_blame5(const char *target,
     SVN_ERR(svn_dirent_get_absolute(&target_abspath_or_url, target, pool));
 
   /* Get an RA plugin for this filesystem object. */
-  SVN_ERR(svn_client__ra_session_from_path(&ra_session, &end_revnum, NULL,
-                                           target, NULL, peg_revision, end,
-                                           ctx, pool));
+  SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &end_loc,
+                                            target, NULL, peg_revision, end,
+                                            ctx, pool));
+  end_revnum = end_loc->rev;
 
   SVN_ERR(svn_client__get_revision_number(&start_revnum, NULL, ctx->wc_ctx,
                                           target_abspath_or_url, ra_session,

Modified: subversion/branches/master-passphrase/subversion/libsvn_client/cat.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_client/cat.c?rev=1354571&r1=1354570&r2=1354571&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_client/cat.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_client/cat.c Wed Jun 27 15:12:37 2012
@@ -183,11 +183,10 @@ svn_client_cat2(svn_stream_t *out,
                 apr_pool_t *pool)
 {
   svn_ra_session_t *ra_session;
-  svn_revnum_t rev;
+  svn_client__pathrev_t *loc;
   svn_string_t *eol_style;
   svn_string_t *keywords;
   apr_hash_t *props;
-  const char *url;
   svn_stream_t *output = out;
   svn_error_t *err;
 
@@ -227,20 +226,21 @@ svn_client_cat2(svn_stream_t *out,
     }
 
   /* Get an RA plugin for this filesystem object. */
-  SVN_ERR(svn_client__ra_session_from_path(&ra_session, &rev,
-                                           &url, path_or_url, NULL,
-                                           peg_revision,
-                                           revision, ctx, pool));
+  SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &loc,
+                                            path_or_url, NULL,
+                                            peg_revision,
+                                            revision, ctx, pool));
 
   /* Grab some properties we need to know in order to figure out if anything
      special needs to be done with this file. */
-  err = svn_ra_get_file(ra_session, "", rev, NULL, NULL, &props, pool);
+  err = svn_ra_get_file(ra_session, "", loc->rev, NULL, NULL, &props, pool);
   if (err)
     {
       if (err->apr_err == SVN_ERR_FS_NOT_FILE)
         {
           return svn_error_createf(SVN_ERR_CLIENT_IS_DIRECTORY, err,
-                                   _("URL '%s' refers to a directory"), url);
+                                   _("URL '%s' refers to a directory"),
+                                   loc->url);
         }
       else
         {
@@ -284,7 +284,7 @@ svn_client_cat2(svn_stream_t *out,
           SVN_ERR(svn_subst_build_keywords2
                   (&kw, keywords->data,
                    cmt_rev->data,
-                   url,
+                   loc->url,
                    when,
                    cmt_author ? cmt_author->data : NULL,
                    pool));
@@ -297,7 +297,7 @@ svn_client_cat2(svn_stream_t *out,
                                            eol_str, FALSE, kw, TRUE, pool);
     }
 
-  SVN_ERR(svn_ra_get_file(ra_session, "", rev, output, NULL, NULL, pool));
+  SVN_ERR(svn_ra_get_file(ra_session, "", loc->rev, output, NULL, NULL, pool));
 
   if (out != output)
     /* Close the interjected stream */

Modified: subversion/branches/master-passphrase/subversion/libsvn_client/checkout.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_client/checkout.c?rev=1354571&r1=1354570&r2=1354571&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_client/checkout.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_client/checkout.c Wed Jun 27 15:12:37 2012
@@ -168,7 +168,10 @@ svn_client__checkout_internal(svn_revnum
                                         allow_unver_obstructions,
                                         TRUE /* adds_as_modification */,
                                         FALSE, FALSE,
-                                        use_sleep, ctx, pool);
+                                        use_sleep, ctx,
+                                        ctx->conflict_func2,
+                                        ctx->conflict_baton2,
+                                        pool);
     }
 
   if (err)

Modified: subversion/branches/master-passphrase/subversion/libsvn_client/client.h
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_client/client.h?rev=1354571&r1=1354570&r2=1354571&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_client/client.h (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_client/client.h Wed Jun 27 15:12:37 2012
@@ -198,6 +198,9 @@ svn_client__repos_location_segments(apr_
    LOC1 and LOC2.  If the locations have no common ancestor (including if
    they don't have the same repository root URL), set *ANCESTOR_P to NULL.
 
+   If SESSION is not NULL, use it for retrieving the common ancestor instead
+   of creating a new session.
+
    Use the authentication baton cached in CTX to authenticate against
    the repository.  Use POOL for all allocations.
 
@@ -207,6 +210,7 @@ svn_error_t *
 svn_client__get_youngest_common_ancestor(svn_client__pathrev_t **ancestor_p,
                                          const svn_client__pathrev_t *loc1,
                                          const svn_client__pathrev_t *loc2,
+                                         svn_ra_session_t *session,
                                          svn_client_ctx_t *ctx,
                                          apr_pool_t *result_pool,
                                          apr_pool_t *scratch_pool);
@@ -227,29 +231,15 @@ svn_client__get_youngest_common_ancestor
    for a URL or 'working' for a WC path.  If REVISION->kind is
    'unspecified', the operative revision is the peg revision.
 
-   Store the resulting ra_session in *RA_SESSION_P.  Store the actual
-   revision number of the object in *REV_P, and the final resulting
-   URL in *URL_P. REV_P and/or URL_P may be NULL if not wanted.
+   Store the resulting ra_session in *RA_SESSION_P.  Store the final
+   resolved location of the object in *RESOLVED_LOC_P.  RESOLVED_LOC_P
+   may be NULL if not wanted.
 
    Use authentication baton cached in CTX to authenticate against the
    repository.
 
    Use POOL for all allocations. */
 svn_error_t *
-svn_client__ra_session_from_path(svn_ra_session_t **ra_session_p,
-                                 svn_revnum_t *rev_p,
-                                 const char **url_p,
-                                 const char *path_or_url,
-                                 const char *base_dir_abspath,
-                                 const svn_opt_revision_t *peg_revision,
-                                 const svn_opt_revision_t *revision,
-                                 svn_client_ctx_t *ctx,
-                                 apr_pool_t *pool);
-
-/* Like svn_client__ra_session_from_path() but returning a path-rev
- * instead of separate URL and rev outputs.  RESOLVED_LOC_P may be NULL
- * if not wanted. */
-svn_error_t *
 svn_client__ra_session_from_path2(svn_ra_session_t **ra_session_p,
                                  svn_client__pathrev_t **resolved_loc_p,
                                  const char *path_or_url,
@@ -286,40 +276,6 @@ svn_client__ensure_ra_session_url(const 
                                   const char *session_url,
                                   apr_pool_t *pool);
 
-/* Return the path of ABSPATH_OR_URL relative to the repository root
-   in REL_PATH (URI-decoded), allocated in RESULT_POOL.
-   If INCLUDE_LEADING_SLASH is set, the returned result will have a leading
-   slash; otherwise, it will not.
-
-   REPOS_ROOT and RA_SESSION may be NULL if ABSPATH_OR_URL is a WC path,
-   otherwise at least one of them must be non-null.
-
-   CAUTION:  While having a leading slash on a so-called relative path
-   might work out well for functionality that interacts with
-   mergeinfo, it results in a relative path that cannot be naively
-   svn_path_join()'d with a repository root URL to provide a full URL.
-
-   Use SCRATCH_POOL for temporary allocations.
-*/
-svn_error_t *
-svn_client__path_relative_to_root(const char **rel_path,
-                                  svn_wc_context_t *wc_ctx,
-                                  const char *abspath_or_url,
-                                  const char *repos_root,
-                                  svn_boolean_t include_leading_slash,
-                                  svn_ra_session_t *ra_session,
-                                  apr_pool_t *result_pool,
-                                  apr_pool_t *scratch_pool);
-
-/* A default error handler for use with svn_wc_walk_entries3().  Returns
-   ERR in all cases. */
-svn_error_t *
-svn_client__default_walker_error_handler(const char *path,
-                                         svn_error_t *err,
-                                         void *walk_baton,
-                                         apr_pool_t *pool);
-
-
 /* ---------------------------------------------------------------- */
 
 /*** RA callbacks ***/
@@ -367,21 +323,37 @@ svn_client__open_ra_session_internal(svn
                                      apr_pool_t *pool);
 
 
+svn_error_t *
+svn_client__ra_provide_base(svn_stream_t **contents,
+                            svn_revnum_t *revision,
+                            void *baton,
+                            const char *repos_relpath,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool);
 
-/* ---------------------------------------------------------------- */
-
-/*** Status ***/
 
-/* Verify that the path can be deleted without losing stuff,
-   i.e. ensure that there are no modified or unversioned resources
-   under PATH.  This is similar to checking the output of the status
-   command.  CTX is used for the client's config options.  POOL is
-   used for all temporary allocations. */
-svn_error_t * svn_client__can_delete(const char *path,
-                                     svn_client_ctx_t *ctx,
-                                     apr_pool_t *pool);
+svn_error_t *
+svn_client__ra_provide_props(apr_hash_t **props,
+                             svn_revnum_t *revision,
+                             void *baton,
+                             const char *repos_relpath,
+                             apr_pool_t *result_pool,
+                             apr_pool_t *scratch_pool);
 
 
+svn_error_t *
+svn_client__ra_get_copysrc_kind(svn_kind_t *kind,
+                                void *baton,
+                                const char *repos_relpath,
+                                svn_revnum_t src_revision,
+                                apr_pool_t *scratch_pool);
+
+
+void *
+svn_client__ra_make_cb_baton(svn_wc_context_t *wc_ctx,
+                             apr_hash_t *relpath_map,
+                             apr_pool_t *result_pool);
+
 /* ---------------------------------------------------------------- */
 
 /*** Add/delete ***/
@@ -489,6 +461,10 @@ svn_client__make_local_parents(const cha
    target which are missing from the working copy.
 
    NOTE:  You may not specify both INNERUPDATE and MAKE_PARENTS as true.
+
+   Use CONFLICT_FUNC2 and CONFLICT_BATON2 instead of CTX->CONFLICT_FUNC2
+   and CTX->CONFLICT_BATON2. If CONFLICT_FUNC2 is NULL, postpone all conflicts
+   allowing the caller to perform post-update conflict resolution.
 */
 svn_error_t *
 svn_client__update_internal(svn_revnum_t *result_rev,
@@ -503,6 +479,8 @@ svn_client__update_internal(svn_revnum_t
                             svn_boolean_t innerupdate,
                             svn_boolean_t *timestamp_sleep,
                             svn_client_ctx_t *ctx,
+                            svn_wc_conflict_resolver_func2_t conflict_func2,
+                            void *conflict_baton2,
                             apr_pool_t *pool);
 
 /* Checkout into LOCAL_ABSPATH a working copy of URL at REVISION, and (if not
@@ -879,10 +857,10 @@ svn_client__condense_commit_items(const 
    NOTIFY_PATH_PREFIX will be passed to CTX->notify_func2() as the
    common absolute path prefix of the committed paths.  It can be NULL.
 
-   If MD5_CHECKSUMS is not NULL, set *MD5_CHECKSUMS to a hash containing,
+   If SHA1_CHECKSUMS is not NULL, set *SHA1_CHECKSUMS to a hash containing,
    for each file transmitted, a mapping from the commit-item's (const
-   char *) path to the (const svn_checksum_t *) MD5 checksum of its new text
-   base.  Similarly for SHA1_CHECKSUMS.
+   char *) path to the (const svn_checksum_t *) SHA1 checksum of its new text
+   base.
 
    Use RESULT_POOL for all allocating the resulting hashes and SCRATCH_POOL
    for temporary allocations.
@@ -893,7 +871,6 @@ svn_client__do_commit(const char *base_u
                       const svn_delta_editor_t *editor,
                       void *edit_baton,
                       const char *notify_path_prefix,
-                      apr_hash_t **md5_checksums,
                       apr_hash_t **sha1_checksums,
                       svn_client_ctx_t *ctx,
                       apr_pool_t *result_pool,
@@ -976,11 +953,12 @@ svn_client__export_externals(apr_hash_t 
                              apr_pool_t *pool);
 
 
-/* Perform status operations on each external in TRAVERSAL_INFO.  All
-   other options are the same as those passed to svn_client_status(). */
+/* Perform status operations on each external in EXTERNAL_MAP, a const char *
+   local_abspath of all externals mapping to the const char* defining_abspath.
+   All other options are the same as those passed to svn_client_status(). */
 svn_error_t *
 svn_client__do_external_status(svn_client_ctx_t *ctx,
-                               apr_hash_t *external_defs,
+                               apr_hash_t *external_map,
                                svn_depth_t depth,
                                svn_boolean_t get_all,
                                svn_boolean_t update,
@@ -1082,7 +1060,7 @@ svn_client__get_normalized_stream(svn_st
 /* Return a set of callbacks to use with the Ev2 shims. */
 svn_delta_shim_callbacks_t *
 svn_client__get_shim_callbacks(svn_wc_context_t *wc_ctx,
-                               const char *anchor_abspath,
+                               apr_hash_t *relpath_map,
                                apr_pool_t *result_pool);
 
 /* Return true if KIND is a revision kind that is dependent on the working

Modified: subversion/branches/master-passphrase/subversion/libsvn_client/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_client/commit.c?rev=1354571&r1=1354570&r2=1354571&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_client/commit.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_client/commit.c Wed Jun 27 15:12:37 2012
@@ -49,6 +49,7 @@
 
 #include "client.h"
 #include "private/svn_wc_private.h"
+#include "private/svn_subr_private.h"
 #include "private/svn_ra_private.h"
 #include "private/svn_magic.h"
 
@@ -269,75 +270,48 @@ import_file(const svn_delta_editor_t *ed
 
   /* Finally, close the file. */
   text_checksum =
-    svn_checksum_to_cstring(svn_checksum__from_digest(digest, svn_checksum_md5,
-                                                      pool), pool);
+    svn_checksum_to_cstring(svn_checksum__from_digest_md5(digest, pool), pool);
 
   return editor->close_file(file_baton, text_checksum, pool);
 }
 
 
-/* Import directory LOCAL_ABSPATH into the repository directory indicated by
- * DIR_BATON in EDITOR.  EDIT_PATH is the path imported as the root
- * directory, so all edits are relative to that.
- *
- * DEPTH is the depth at this point in the descent (it may be changed
- * for recursive calls).
- *
- * Accumulate file paths and their batons in FILES, which must be
- * non-null.  (These are used to send postfix textdeltas later).
- *
- * EXCLUDES is a hash whose keys are absolute paths to exclude from
- * the import (values are unused).
- *
- * If NO_IGNORE is FALSE, don't import files or directories that match
- * ignore patterns.
- *
- * If FILTER_CALLBACK is not NULL, call it with FILTER_BATON on each to be
- * imported node below LOCAL_ABSPATH to allow filtering nodes.
- *
- * If CTX->NOTIFY_FUNC is non-null, invoke it with CTX->NOTIFY_BATON for each
- * directory.
+/* Return in CHILDREN a mapping of basenames to dirents for the importable
+ * children of DIR_ABSPATH.  EXCLUDES is a hash of absolute paths to filter
+ * out.  IGNORES, if non-NULL, is a list of basenames to filter out.
+ * FILTER_CALLBACK and FILTER_BATON will be called for each absolute path,
+ * allowing users to further filter the list of returned entries.
  *
- * Use POOL for any temporary allocation.  */
+ * Results are returned in RESULT_POOL; use SCRATCH_POOL for temporary data.*/
 static svn_error_t *
-import_dir(const svn_delta_editor_t *editor,
-           void *dir_baton,
-           const char *local_abspath,
-           const char *edit_path,
-           svn_depth_t depth,
-           apr_hash_t *excludes,
-           svn_boolean_t no_ignore,
-           svn_boolean_t ignore_unknown_node_types,
-           svn_client_import_filter_func_t filter_callback,
-           void *filter_baton,
-           import_ctx_t *import_ctx,
-           svn_client_ctx_t *ctx,
-           apr_pool_t *pool)
+get_filtered_children(apr_hash_t **children,
+                      const char *dir_abspath,
+                      apr_hash_t *excludes,
+                      apr_array_header_t *ignores,
+                      svn_client_import_filter_func_t filter_callback,
+                      void *filter_baton,
+                      svn_client_ctx_t *ctx,
+                      apr_pool_t *result_pool,
+                      apr_pool_t *scratch_pool)
 {
-  apr_pool_t *subpool = svn_pool_create(pool);  /* iteration pool */
   apr_hash_t *dirents;
   apr_hash_index_t *hi;
-  apr_array_header_t *ignores;
-
-  SVN_ERR(svn_path_check_valid(local_abspath, pool));
-
-  if (!no_ignore)
-    SVN_ERR(svn_wc_get_default_ignores(&ignores, ctx->config, pool));
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
 
-  SVN_ERR(svn_io_get_dirents3(&dirents, local_abspath, TRUE, pool, pool));
+  SVN_ERR(svn_io_get_dirents3(&dirents, dir_abspath, TRUE, result_pool,
+                              scratch_pool));
 
-  for (hi = apr_hash_first(pool, dirents); hi; hi = apr_hash_next(hi))
+  for (hi = apr_hash_first(scratch_pool, dirents); hi; hi = apr_hash_next(hi))
     {
-      const char *this_abspath, *this_edit_path;
-      const char *filename = svn__apr_hash_index_key(hi);
+      const char *base_name = svn__apr_hash_index_key(hi);
       const svn_io_dirent2_t *dirent = svn__apr_hash_index_val(hi);
+      const char *local_abspath;
 
-      svn_pool_clear(subpool);
+      svn_pool_clear(iterpool);
 
-      if (ctx->cancel_func)
-        SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
+      local_abspath = svn_dirent_join(dir_abspath, base_name, iterpool);
 
-      if (svn_wc_is_adm_dir(filename, subpool))
+      if (svn_wc_is_adm_dir(base_name, iterpool))
         {
           /* If someone's trying to import a directory named the same
              as our administrative directories, that's probably not
@@ -348,95 +322,130 @@ import_dir(const svn_delta_editor_t *edi
           if (ctx->notify_func2)
             {
               svn_wc_notify_t *notify
-                = svn_wc_create_notify(svn_dirent_join(local_abspath, filename,
-                                                       subpool),
-                                       svn_wc_notify_skip, subpool);
+                = svn_wc_create_notify(svn_dirent_join(local_abspath, base_name,
+                                                       iterpool),
+                                       svn_wc_notify_skip, iterpool);
               notify->kind = svn_node_dir;
               notify->content_state = notify->prop_state
                 = svn_wc_notify_state_inapplicable;
               notify->lock_state = svn_wc_notify_lock_state_inapplicable;
-              (*ctx->notify_func2)(ctx->notify_baton2, notify, subpool);
+              (*ctx->notify_func2)(ctx->notify_baton2, notify, iterpool);
             }
+
+          apr_hash_set(dirents, base_name, APR_HASH_KEY_STRING, NULL);
+          continue;
+        }
+            /* If this is an excluded path, exclude it. */
+      if (apr_hash_get(excludes, local_abspath, APR_HASH_KEY_STRING))
+        {
+          apr_hash_set(dirents, base_name, APR_HASH_KEY_STRING, NULL);
           continue;
         }
 
-      /* Typically, we started importing from ".", in which case
-         edit_path is "".  So below, this_path might become "./blah",
-         and this_edit_path might become "blah", for example. */
-      this_abspath = svn_dirent_join(local_abspath, filename, subpool);
-      this_edit_path = svn_relpath_join(edit_path, filename, subpool);
-
-      /* If this is an excluded path, exclude it. */
-      if (apr_hash_get(excludes, this_abspath, APR_HASH_KEY_STRING))
-        continue;
-
-      if ((!no_ignore) && svn_wc_match_ignore_list(filename, ignores,
-                                                   subpool))
-        continue;
+      if (ignores && svn_wc_match_ignore_list(base_name, ignores, iterpool))
+        {
+          apr_hash_set(dirents, base_name, APR_HASH_KEY_STRING, NULL);
+          continue;
+        }
 
-      if (filter_callback != NULL)
+      if (filter_callback)
         {
           svn_boolean_t filter = FALSE;
 
-          SVN_ERR(filter_callback(filter_baton, &filter, this_abspath,
-                                  dirent, subpool));
+          SVN_ERR(filter_callback(filter_baton, &filter, local_abspath,
+                                  dirent, iterpool));
 
           if (filter)
-            continue;
+            {
+              apr_hash_set(dirents, base_name, APR_HASH_KEY_STRING, NULL);
+              continue;
+            }
         }
+    }
+  svn_pool_destroy(iterpool);
 
-      if (dirent->kind == svn_node_dir && depth >= svn_depth_immediates)
-        {
-          void *this_dir_baton;
+  *children = dirents;
+  return SVN_NO_ERROR;
+}
 
-          /* Add the new subdirectory, getting a descent baton from
-             the editor. */
-          SVN_ERR(editor->add_directory(this_edit_path, dir_baton,
-                                        NULL, SVN_INVALID_REVNUM, subpool,
-                                        &this_dir_baton));
+static svn_error_t *
+import_dir(const svn_delta_editor_t *editor,
+           void *dir_baton,
+           const char *local_abspath,
+           const char *edit_path,
+           svn_depth_t depth,
+           apr_hash_t *excludes,
+           svn_boolean_t no_ignore,
+           svn_boolean_t ignore_unknown_node_types,
+           svn_client_import_filter_func_t filter_callback,
+           void *filter_baton,
+           import_ctx_t *import_ctx,
+           svn_client_ctx_t *ctx,
+           apr_pool_t *pool);
 
-          /* Remember that the repository was modified */
-          import_ctx->repos_changed = TRUE;
 
-          /* By notifying before the recursive call below, we display
-             a directory add before displaying adds underneath the
-             directory.  To do it the other way around, just move this
-             after the recursive call. */
-          if (ctx->notify_func2)
-            {
-              svn_wc_notify_t *notify
-                = svn_wc_create_notify(this_abspath,
-                                       svn_wc_notify_commit_added,
-                                       subpool);
-              notify->kind = svn_node_dir;
-              notify->content_state = notify->prop_state
-                = svn_wc_notify_state_inapplicable;
-              notify->lock_state = svn_wc_notify_lock_state_inapplicable;
-              (*ctx->notify_func2)(ctx->notify_baton2, notify, subpool);
-            }
+/* Import the children of DIR_ABSPATH, with other arguments similar to
+ * import_dir(). */
+static svn_error_t *
+import_children(const char *dir_abspath,
+                const char *edit_path,
+                apr_hash_t *dirents,
+                const svn_delta_editor_t *editor,
+                void *dir_baton,
+                svn_depth_t depth,
+                apr_hash_t *excludes,
+                svn_boolean_t no_ignore,
+                svn_boolean_t ignore_unknown_node_types,
+                svn_client_import_filter_func_t filter_callback,
+                void *filter_baton,
+                import_ctx_t *import_ctx,
+                svn_client_ctx_t *ctx,
+                apr_pool_t *scratch_pool)
+{
+  apr_array_header_t *sorted_dirents;
+  int i;
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
 
-          /* Recurse. */
-          {
-            svn_depth_t depth_below_here = depth;
-            if (depth == svn_depth_immediates)
-              depth_below_here = svn_depth_empty;
-
-            SVN_ERR(import_dir(editor, this_dir_baton, this_abspath,
-                               this_edit_path, depth_below_here, excludes,
-                               no_ignore, ignore_unknown_node_types,
-                               filter_callback, filter_baton,
-                               import_ctx, ctx,
-                               subpool));
-          }
+  sorted_dirents = svn_sort__hash(dirents, svn_sort_compare_items_lexically,
+                                  scratch_pool);
+  for (i = 0; i < sorted_dirents->nelts; i++)
+    {
+      const char *this_abspath, *this_edit_path;
+      svn_sort__item_t item = APR_ARRAY_IDX(sorted_dirents, i,
+                                            svn_sort__item_t);
+      const char *filename = item.key;
+      const svn_io_dirent2_t *dirent = item.value;
+
+      svn_pool_clear(iterpool);
 
-          /* Finally, close the sub-directory. */
-          SVN_ERR(editor->close_directory(this_dir_baton, subpool));
+      if (ctx->cancel_func)
+        SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
+
+      /* Typically, we started importing from ".", in which case
+         edit_path is "".  So below, this_path might become "./blah",
+         and this_edit_path might become "blah", for example. */
+      this_abspath = svn_dirent_join(dir_abspath, filename, iterpool);
+      this_edit_path = svn_relpath_join(edit_path, filename, iterpool);
+
+      if (dirent->kind == svn_node_dir && depth >= svn_depth_immediates)
+        {
+          /* Recurse. */
+          svn_depth_t depth_below_here = depth;
+          if (depth == svn_depth_immediates)
+            depth_below_here = svn_depth_empty;
+
+          SVN_ERR(import_dir(editor, dir_baton, this_abspath,
+                             this_edit_path, depth_below_here, excludes,
+                             no_ignore, ignore_unknown_node_types,
+                             filter_callback, filter_baton,
+                             import_ctx, ctx,
+                             iterpool));
         }
       else if (dirent->kind == svn_node_file && depth >= svn_depth_files)
         {
           SVN_ERR(import_file(editor, dir_baton, this_abspath,
                               this_edit_path, dirent,
-                              import_ctx, ctx, subpool));
+                              import_ctx, ctx, iterpool));
         }
       else if (dirent->kind != svn_node_dir && dirent->kind != svn_node_file)
         {
@@ -447,23 +456,114 @@ import_dir(const svn_delta_editor_t *edi
                 {
                   svn_wc_notify_t *notify
                     = svn_wc_create_notify(this_abspath,
-                                           svn_wc_notify_skip, subpool);
+                                           svn_wc_notify_skip, iterpool);
                   notify->kind = svn_node_dir;
                   notify->content_state = notify->prop_state
                     = svn_wc_notify_state_inapplicable;
                   notify->lock_state = svn_wc_notify_lock_state_inapplicable;
-                  (*ctx->notify_func2)(ctx->notify_baton2, notify, subpool);
+                  (*ctx->notify_func2)(ctx->notify_baton2, notify, iterpool);
                 }
             }
           else
             return svn_error_createf
               (SVN_ERR_NODE_UNKNOWN_KIND, NULL,
                _("Unknown or unversionable type for '%s'"),
-               svn_dirent_local_style(this_abspath, subpool));
+               svn_dirent_local_style(this_abspath, iterpool));
         }
     }
 
-  svn_pool_destroy(subpool);
+  svn_pool_destroy(iterpool);
+  return SVN_NO_ERROR;
+}
+
+
+/* Import directory LOCAL_ABSPATH into the repository directory indicated by
+ * DIR_BATON in EDITOR.  EDIT_PATH is the path imported as the root
+ * directory, so all edits are relative to that.
+ *
+ * DEPTH is the depth at this point in the descent (it may be changed
+ * for recursive calls).
+ *
+ * Accumulate file paths and their batons in FILES, which must be
+ * non-null.  (These are used to send postfix textdeltas later).
+ *
+ * EXCLUDES is a hash whose keys are absolute paths to exclude from
+ * the import (values are unused).
+ *
+ * If NO_IGNORE is FALSE, don't import files or directories that match
+ * ignore patterns.
+ *
+ * If FILTER_CALLBACK is not NULL, call it with FILTER_BATON on each to be
+ * imported node below LOCAL_ABSPATH to allow filtering nodes.
+ *
+ * If CTX->NOTIFY_FUNC is non-null, invoke it with CTX->NOTIFY_BATON for each
+ * directory.
+ *
+ * Use POOL for any temporary allocation.  */
+static svn_error_t *
+import_dir(const svn_delta_editor_t *editor,
+           void *dir_baton,
+           const char *local_abspath,
+           const char *edit_path,
+           svn_depth_t depth,
+           apr_hash_t *excludes,
+           svn_boolean_t no_ignore,
+           svn_boolean_t ignore_unknown_node_types,
+           svn_client_import_filter_func_t filter_callback,
+           void *filter_baton,
+           import_ctx_t *import_ctx,
+           svn_client_ctx_t *ctx,
+           apr_pool_t *pool)
+{
+  apr_hash_t *dirents;
+  apr_array_header_t *ignores = NULL;
+  void *this_dir_baton;
+
+  SVN_ERR(svn_path_check_valid(local_abspath, pool));
+
+  if (!no_ignore)
+    SVN_ERR(svn_wc_get_default_ignores(&ignores, ctx->config, pool));
+
+  SVN_ERR(get_filtered_children(&dirents, local_abspath, excludes, ignores,
+                                filter_callback, filter_baton, ctx,
+                                pool, pool));
+
+  /* Import this directory, but not yet its children. */
+  {
+    /* Add the new subdirectory, getting a descent baton from the editor. */
+    SVN_ERR(editor->add_directory(edit_path, dir_baton, NULL,
+                                  SVN_INVALID_REVNUM, pool, &this_dir_baton));
+
+    /* Remember that the repository was modified */
+    import_ctx->repos_changed = TRUE;
+
+    /* By notifying before the recursive call below, we display
+       a directory add before displaying adds underneath the
+       directory.  To do it the other way around, just move this
+       after the recursive call. */
+    if (ctx->notify_func2)
+      {
+        svn_wc_notify_t *notify
+          = svn_wc_create_notify(local_abspath, svn_wc_notify_commit_added,
+                                 pool);
+        notify->kind = svn_node_dir;
+        notify->content_state = notify->prop_state
+          = svn_wc_notify_state_inapplicable;
+        notify->lock_state = svn_wc_notify_lock_state_inapplicable;
+        (*ctx->notify_func2)(ctx->notify_baton2, notify, pool);
+      }
+  }
+
+  /* Now import the children recursively. */
+  SVN_ERR(import_children(local_abspath, edit_path, dirents, editor,
+                          this_dir_baton, depth, excludes, no_ignore,
+                          ignore_unknown_node_types,
+                          filter_callback, filter_baton,
+                          import_ctx, ctx, pool));
+
+  /* Finally, close the sub-directory. */
+  SVN_ERR(editor->close_directory(this_dir_baton, pool));
+
   return SVN_NO_ERROR;
 }
 
@@ -518,7 +618,7 @@ import(const char *local_abspath,
        apr_pool_t *pool)
 {
   void *root_baton;
-  apr_array_header_t *ignores;
+  apr_array_header_t *ignores = NULL;
   apr_array_header_t *batons = NULL;
   const char *edit_path = "";
   import_ctx_t *import_ctx = apr_pcalloc(pool, sizeof(*import_ctx));
@@ -596,11 +696,20 @@ import(const char *local_abspath,
     }
   else if (dirent->kind == svn_node_dir)
     {
-      SVN_ERR(import_dir(editor, root_baton, local_abspath, edit_path,
-                         depth, excludes, no_ignore,
-                         ignore_unknown_node_types,
-                         filter_callback, filter_baton,
-                         import_ctx, ctx, pool));
+      apr_hash_t *dirents;
+
+      if (!no_ignore)
+        SVN_ERR(svn_wc_get_default_ignores(&ignores, ctx->config, pool));
+
+      SVN_ERR(get_filtered_children(&dirents, local_abspath, excludes, ignores,
+                                    filter_callback, filter_baton, ctx,
+                                    pool, pool));
+
+      SVN_ERR(import_children(local_abspath, edit_path, dirents, editor,
+                              root_baton, depth, excludes, no_ignore,
+                              ignore_unknown_node_types,
+                              filter_callback, filter_baton,
+                              import_ctx, ctx, pool));
 
     }
   else if (dirent->kind == svn_node_none
@@ -655,16 +764,13 @@ capture_commit_info(const svn_commit_inf
 
 
 static svn_error_t *
-get_ra_editor(svn_ra_session_t **ra_session,
-              const svn_delta_editor_t **editor,
+get_ra_editor(const svn_delta_editor_t **editor,
               void **edit_baton,
+              svn_ra_session_t *ra_session,
               svn_client_ctx_t *ctx,
-              const char *base_url,
-              const char *base_dir_abspath,
               const char *log_msg,
               const apr_array_header_t *commit_items,
               const apr_hash_t *revprop_table,
-              svn_boolean_t is_commit,
               apr_hash_t *lock_tokens,
               svn_boolean_t keep_locks,
               svn_commit_callback2_t commit_callback,
@@ -672,54 +778,43 @@ get_ra_editor(svn_ra_session_t **ra_sess
               apr_pool_t *pool)
 {
   apr_hash_t *commit_revprops;
-  const char *anchor_abspath;
-
-  /* Open an RA session to URL. */
-  SVN_ERR(svn_client__open_ra_session_internal(ra_session, NULL, base_url,
-                                               base_dir_abspath, commit_items,
-                                               is_commit, !is_commit,
-                                               ctx, pool));
-
-  /* If this is an import (aka, not a commit), we need to verify that
-     our repository URL exists. */
-  if (! is_commit)
-    {
-      svn_node_kind_t kind;
-
-      SVN_ERR(svn_ra_check_path(*ra_session, "", SVN_INVALID_REVNUM,
-                                &kind, pool));
-      if (kind == svn_node_none)
-        return svn_error_createf(SVN_ERR_FS_NO_SUCH_ENTRY, NULL,
-                                 _("Path '%s' does not exist"),
-                                 base_url);
-    }
+  apr_hash_t *relpath_map = NULL;
 
   SVN_ERR(svn_client__ensure_revprop_table(&commit_revprops, revprop_table,
                                            log_msg, ctx, pool));
 
 #ifdef ENABLE_EV2_SHIMS
-  /* We need this for the shims. */
-  if (base_dir_abspath)
+  if (commit_items)
     {
-      const char *relpath;
-      const char *wcroot_abspath;
+      int i;
+      apr_pool_t *iterpool = svn_pool_create(pool);
 
-      SVN_ERR(svn_wc__get_wc_root(&wcroot_abspath, ctx->wc_ctx,
-                                  base_dir_abspath, pool, pool));
+      relpath_map = apr_hash_make(pool);
+      for (i = 0; i < commit_items->nelts; i++)
+        {
+          svn_client_commit_item3_t *item = APR_ARRAY_IDX(commit_items, i,
+                                                  svn_client_commit_item3_t *);
+          const char *relpath;
+
+          if (!item->path)
+            continue;
 
-      SVN_ERR(svn_ra_get_path_relative_to_root(*ra_session, &relpath, base_url,
-                                               pool));
-      anchor_abspath = svn_dirent_join(wcroot_abspath, relpath, pool);
+          svn_pool_clear(iterpool);
+          SVN_ERR(svn_wc__node_get_origin(NULL, NULL, &relpath, NULL, NULL, NULL,
+                                          ctx->wc_ctx, item->path, FALSE, pool,
+                                          iterpool));
+          if (relpath)
+            apr_hash_set(relpath_map, relpath, APR_HASH_KEY_STRING, item->path);
+        }
+      svn_pool_destroy(iterpool);
     }
-  else
 #endif
-    anchor_abspath = NULL;
 
   /* Fetch RA commit editor. */
-  SVN_ERR(svn_ra__register_editor_shim_callbacks(*ra_session,
+  SVN_ERR(svn_ra__register_editor_shim_callbacks(ra_session,
                         svn_client__get_shim_callbacks(ctx->wc_ctx,
-                                                       anchor_abspath, pool)));
-  SVN_ERR(svn_ra_get_commit_editor3(*ra_session, editor, edit_baton,
+                                                       relpath_map, pool)));
+  SVN_ERR(svn_ra_get_commit_editor3(ra_session, editor, edit_baton,
                                     commit_revprops, commit_callback,
                                     commit_baton, lock_tokens, keep_locks,
                                     pool));
@@ -756,7 +851,8 @@ svn_client_import5(const char *path,
                                                    sizeof(const char *));
   const char *temp;
   const char *dir;
-  apr_pool_t *subpool;
+  apr_hash_t *commit_revprops;
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
 
   if (svn_path_is_url(path))
     return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
@@ -794,37 +890,34 @@ svn_client_import5(const char *path,
 
   SVN_ERR(svn_io_check_path(local_abspath, &kind, scratch_pool));
 
+  SVN_ERR(svn_client__open_ra_session_internal(&ra_session, NULL, url, NULL,
+                                               NULL, FALSE, TRUE, ctx,
+                                               scratch_pool));
+
   /* Figure out all the path components we need to create just to have
      a place to stick our imported tree. */
-  subpool = svn_pool_create(scratch_pool);
-  do
-    {
-      svn_pool_clear(subpool);
+  SVN_ERR(svn_ra_check_path(ra_session, "", SVN_INVALID_REVNUM, &kind,
+                            iterpool));
 
-      /* See if the user is interested in cancelling this operation. */
-      if (ctx->cancel_func)
-        SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
+  /* We can import into directories, but if a file already exists, that's
+     an error. */
+  if (kind == svn_node_file)
+    return svn_error_createf
+      (SVN_ERR_ENTRY_EXISTS, NULL,
+       _("Path '%s' already exists"), url);
 
-      if (err)
-        {
-          /* If get_ra_editor below failed we either tried to open
-             an invalid url, or else some other kind of error.  In case
-             the url was bad we back up a directory and try again. */
+  while (kind == svn_node_none)
+    {
+      svn_pool_clear(iterpool);
 
-          if (err->apr_err != SVN_ERR_FS_NO_SUCH_ENTRY)
-            return err;
-          else
-            svn_error_clear(err);
+      svn_uri_split(&temp, &dir, url, scratch_pool);
+      APR_ARRAY_PUSH(new_entries, const char *) = dir;
+      url = temp;
+      SVN_ERR(svn_ra_reparent(ra_session, url, iterpool));
 
-          svn_uri_split(&temp, &dir, url, scratch_pool);
-          APR_ARRAY_PUSH(new_entries, const char *) = dir;
-          url = temp;
-        }
+      SVN_ERR(svn_ra_check_path(ra_session, "", SVN_INVALID_REVNUM, &kind,
+                                iterpool));
     }
-  while ((err = get_ra_editor(&ra_session,
-                              &editor, &edit_baton, ctx, url, NULL,
-                              log_msg, NULL, revprop_table, FALSE, NULL, TRUE,
-                              commit_callback, commit_baton, subpool)));
 
   /* Reverse the order of the components we added to our NEW_ENTRIES array. */
   if (new_entries->nelts)
@@ -843,14 +936,6 @@ svn_client_import5(const char *path,
         }
     }
 
-  /* An empty NEW_ENTRIES list the first call to get_ra_editor() above
-     succeeded.  That means that URL corresponds to an already
-     existing filesystem entity. */
-  if (kind == svn_node_file && (! new_entries->nelts))
-    return svn_error_createf
-      (SVN_ERR_ENTRY_EXISTS, NULL,
-       _("Path '%s' already exists"), url);
-
   /* The repository doesn't know about the reserved administrative
      directory. */
   if (new_entries->nelts
@@ -867,6 +952,17 @@ svn_client_import5(const char *path,
        _("'%s' is a reserved name and cannot be imported"),
        svn_dirent_local_style(temp, scratch_pool));
 
+  SVN_ERR(svn_client__ensure_revprop_table(&commit_revprops, revprop_table,
+                                           log_msg, ctx, scratch_pool));
+
+  /* Fetch RA commit editor. */
+  SVN_ERR(svn_ra__register_editor_shim_callbacks(ra_session,
+                        svn_client__get_shim_callbacks(ctx->wc_ctx,
+                                                       NULL, scratch_pool)));
+  SVN_ERR(svn_ra_get_commit_editor3(ra_session, &editor, &edit_baton,
+                                    commit_revprops, commit_callback,
+                                    commit_baton, NULL, TRUE,
+                                    scratch_pool));
 
   /* If an error occurred during the commit, abort the edit and return
      the error.  We don't even care if the abort itself fails.  */
@@ -874,13 +970,13 @@ svn_client_import5(const char *path,
                     depth, excludes, no_ignore,
                     ignore_unknown_node_types,
                     filter_callback, filter_baton,
-                    ctx, subpool)))
+                    ctx, iterpool)))
     {
-      svn_error_clear(editor->abort_edit(edit_baton, subpool));
+      svn_error_clear(editor->abort_edit(edit_baton, iterpool));
       return svn_error_trace(err);
     }
 
-  svn_pool_destroy(subpool);
+  svn_pool_destroy(iterpool);
 
   return SVN_NO_ERROR;
 }
@@ -1238,7 +1334,10 @@ append_externals_as_explicit_targets(apr
 {
   int rel_targets_nelts_fixed;
   int i;
-  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+  apr_pool_t *iterpool;
+
+  if (! (include_file_externals || include_dir_externals))
+    return SVN_NO_ERROR;
 
   /* Easy part of applying DEPTH to externals. */
   if (depth == svn_depth_empty)
@@ -1266,12 +1365,11 @@ append_externals_as_explicit_targets(apr
        * ### not at all. No other effect. So not doing that for now. */
      }
 
-  if (! (include_file_externals || include_dir_externals))
-    return SVN_NO_ERROR;
-
   /* Iterate *and* grow REL_TARGETS at the same time. */
   rel_targets_nelts_fixed = rel_targets->nelts;
 
+  iterpool = svn_pool_create(scratch_pool);
+
   for (i = 0; i < rel_targets_nelts_fixed; i++)
     {
       int j;
@@ -1673,11 +1771,18 @@ svn_client_commit6(const apr_array_heade
   cb.pool = pool;
 
   cmt_err = svn_error_trace(
-                 get_ra_editor(&ra_session, &editor, &edit_baton, ctx,
-                               base_url, base_abspath, log_msg,
-                               commit_items, revprop_table, TRUE, lock_tokens,
-                               keep_locks, capture_commit_info,
-                               &cb, pool));
+              svn_client__open_ra_session_internal(&ra_session, NULL, base_url,
+                                                   base_abspath, commit_items,
+                                                   TRUE, FALSE, ctx, pool));
+
+  if (cmt_err)
+    goto cleanup;
+
+  cmt_err = svn_error_trace(
+              get_ra_editor(&editor, &edit_baton, ra_session, ctx,
+                            log_msg, commit_items, revprop_table,
+                            lock_tokens, keep_locks, capture_commit_info,
+                            &cb, pool));
 
   if (cmt_err)
     goto cleanup;
@@ -1687,9 +1792,9 @@ svn_client_commit6(const apr_array_heade
 
   /* Perform the commit. */
   cmt_err = svn_error_trace(
-            svn_client__do_commit(base_url, commit_items, editor, edit_baton,
-                                  notify_prefix, NULL,
-                                  &sha1_checksums, ctx, pool, iterpool));
+              svn_client__do_commit(base_url, commit_items, editor, edit_baton,
+                                    notify_prefix, &sha1_checksums, ctx, pool,
+                                    iterpool));
 
   /* Handle a successful commit. */
   if ((! cmt_err)



Mime
View raw message