Author: julianfoad
Date: Mon Jun 29 13:42:10 2015
New Revision: 1688213

URL: http://svn.apache.org/r1688213
Log:
On the 'move-tracking-2' branch: Catch up to trunk@1688211.

Modified:
    subversion/branches/move-tracking-2/   (props changed)
    subversion/branches/move-tracking-2/build/   (props changed)
    subversion/branches/move-tracking-2/build/ac-macros/apache.m4
    subversion/branches/move-tracking-2/subversion/   (props changed)
    
subversion/branches/move-tracking-2/subversion/bindings/javahl/native/SVNRepos.cpp
    
subversion/branches/move-tracking-2/subversion/bindings/javahl/native/SVNRepos.h
    
subversion/branches/move-tracking-2/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNRepos.cpp
    
subversion/branches/move-tracking-2/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRepos.java
    
subversion/branches/move-tracking-2/subversion/bindings/javahl/src/org/apache/subversion/javahl/ReposNotifyInformation.java
    
subversion/branches/move-tracking-2/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNRepos.java
    
subversion/branches/move-tracking-2/subversion/include/private/svn_wc_private.h
    subversion/branches/move-tracking-2/subversion/include/svn_client.h
    subversion/branches/move-tracking-2/subversion/include/svn_error_codes.h
    subversion/branches/move-tracking-2/subversion/include/svn_repos.h
    subversion/branches/move-tracking-2/subversion/libsvn_client/resolved.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.h
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.h
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/hotcopy.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/hotcopy.h
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/pack.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/transaction.c
    subversion/branches/move-tracking-2/subversion/libsvn_repos/deprecated.c
    subversion/branches/move-tracking-2/subversion/libsvn_repos/dump.c
    subversion/branches/move-tracking-2/subversion/libsvn_repos/rev_hunt.c
    subversion/branches/move-tracking-2/subversion/libsvn_subr/cache-membuffer.c
    subversion/branches/move-tracking-2/subversion/libsvn_subr/config.c
    subversion/branches/move-tracking-2/subversion/libsvn_subr/io.c
    subversion/branches/move-tracking-2/subversion/libsvn_wc/conflicts.c
    subversion/branches/move-tracking-2/subversion/mod_dav_svn/util.c
    subversion/branches/move-tracking-2/subversion/svn/cl-conflicts.c
    subversion/branches/move-tracking-2/subversion/svn/cl-conflicts.h
    subversion/branches/move-tracking-2/subversion/svn/cl.h
    subversion/branches/move-tracking-2/subversion/svn/conflict-callbacks.c
    subversion/branches/move-tracking-2/subversion/svn/info-cmd.c
    subversion/branches/move-tracking-2/subversion/svn/status.c
    subversion/branches/move-tracking-2/subversion/svn/util.c
    subversion/branches/move-tracking-2/subversion/svnadmin/svnadmin.c
    
subversion/branches/move-tracking-2/subversion/tests/cmdline/merge_tree_conflict_tests.py
    
subversion/branches/move-tracking-2/subversion/tests/cmdline/mergeinfo_tests.py
    subversion/branches/move-tracking-2/subversion/tests/cmdline/move_tests.py
    subversion/branches/move-tracking-2/subversion/tests/cmdline/prop_tests.py
    
subversion/branches/move-tracking-2/subversion/tests/cmdline/svnadmin_tests.py
    subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/main.py
    subversion/branches/move-tracking-2/subversion/tests/cmdline/update_tests.py
    
subversion/branches/move-tracking-2/subversion/tests/libsvn_client/mtcc-test.c
    
subversion/branches/move-tracking-2/subversion/tests/libsvn_fs_fs/fs-fs-fuzzy-test.c
    
subversion/branches/move-tracking-2/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c
    
subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/config-test.c
    
subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/config-test.cfg

Propchange: subversion/branches/move-tracking-2/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Jun 29 13:42:10 2015
@@ -90,4 +90,4 @@
 /subversion/branches/verify-at-commit:1462039-1462408
 /subversion/branches/verify-keep-going:1439280-1546110
 /subversion/branches/wc-collate-path:1402685-1480384
-/subversion/trunk:1606692-1686493
+/subversion/trunk:1606692-1688211

Propchange: subversion/branches/move-tracking-2/build/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Jun 29 13:42:10 2015
@@ -82,4 +82,4 @@
 /subversion/branches/verify-at-commit/build:1462039-1462408
 /subversion/branches/verify-keep-going/build:1439280-1546110
 /subversion/branches/wc-collate-path/build:1402685-1480384
-/subversion/trunk/build:1606692-1677758
+/subversion/trunk/build:1606692-1688211

Modified: subversion/branches/move-tracking-2/build/ac-macros/apache.m4
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/build/ac-macros/apache.m4?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/build/ac-macros/apache.m4 (original)
+++ subversion/branches/move-tracking-2/build/ac-macros/apache.m4 Mon Jun 29 
13:42:10 2015
@@ -166,7 +166,7 @@ if test -n "$APXS" && test "$APXS" != "n
     if ! test -e $HTTPD ; then
       HTTPD="`$APXS -q bindir`/`$APXS -q PROGNAME`"
     fi
-    HTTPD_VERSION=["`$HTTPD -v | $SED -e 's@^.*/\([0-9.]*\)\(.*$\)@\1@ ; 1q'`"]
+    HTTPD_VERSION=["`$HTTPD -v | $SED -e 's/^.*\/\([0-9.]*\).*$/\1/' -e 1q`"]
 
     case $host in
       *-*-cygwin*)

Propchange: subversion/branches/move-tracking-2/subversion/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Jun 29 13:42:10 2015
@@ -82,4 +82,4 @@
 /subversion/branches/verify-at-commit/subversion:1462039-1462408
 /subversion/branches/verify-keep-going/subversion:1439280-1546110
 /subversion/branches/wc-collate-path/subversion:1402685-1480384
-/subversion/trunk/subversion:1606692-1686493
+/subversion/trunk/subversion:1606692-1688211

Modified: 
subversion/branches/move-tracking-2/subversion/bindings/javahl/native/SVNRepos.cpp
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/bindings/javahl/native/SVNRepos.cpp?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- 
subversion/branches/move-tracking-2/subversion/bindings/javahl/native/SVNRepos.cpp
 (original)
+++ 
subversion/branches/move-tracking-2/subversion/bindings/javahl/native/SVNRepos.cpp
 Mon Jun 29 13:42:10 2015
@@ -594,7 +594,7 @@ SVNRepos::getRevnum(svn_revnum_t *revnum
 
 void
 SVNRepos::verify(File &path, Revision &revisionStart, Revision &revisionEnd,
-                 bool keepGoing, bool checkNormalization, bool metadataOnly,
+                 bool checkNormalization, bool metadataOnly,
                  ReposNotifyCallback *notifyCallback)
 {
   SVN::Pool requestPool;
@@ -639,13 +639,13 @@ SVNRepos::verify(File &path, Revision &r
        _("Start revision cannot be higher than end revision")), );
 
   SVN_JNI_ERR(svn_repos_verify_fs3(repos, lower, upper,
-                                   keepGoing,
                                    checkNormalization,
                                    metadataOnly,
                                    notifyCallback != NULL
                                     ? ReposNotifyCallback::notify
                                     : NULL,
                                    notifyCallback,
+                                   NULL, NULL, /* verify callback/baton */
                                    checkCancel, this /* cancel callback/baton 
*/,
                                    requestPool.getPool()), );
 }

Modified: 
subversion/branches/move-tracking-2/subversion/bindings/javahl/native/SVNRepos.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/bindings/javahl/native/SVNRepos.h?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- 
subversion/branches/move-tracking-2/subversion/bindings/javahl/native/SVNRepos.h
 (original)
+++ 
subversion/branches/move-tracking-2/subversion/bindings/javahl/native/SVNRepos.h
 Mon Jun 29 13:42:10 2015
@@ -45,7 +45,7 @@ class SVNRepos : public SVNBase
   void rmlocks(File &path, StringArray &locks);
   jobject lslocks(File &path, svn_depth_t depth);
   void verify(File &path, Revision &revisionStart, Revision &revisionEnd,
-              bool keepGoing, bool checkNormalization, bool metadataOnly,
+              bool checkNormalization, bool metadataOnly,
               ReposNotifyCallback *notifyCallback);
   void setRevProp(File &path, Revision &revision,
                   const char *propName, const char *propValue,

Modified: 
subversion/branches/move-tracking-2/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNRepos.cpp
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNRepos.cpp?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- 
subversion/branches/move-tracking-2/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNRepos.cpp
 (original)
+++ 
subversion/branches/move-tracking-2/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNRepos.cpp
 Mon Jun 29 13:42:10 2015
@@ -419,7 +419,7 @@ JNIEXPORT void JNICALL
 Java_org_apache_subversion_javahl_SVNRepos_verify(
     JNIEnv *env, jobject jthis, jobject jpath,
     jobject jrevisionStart, jobject jrevisionEnd,
-    jboolean jkeepGoing, jboolean jcheckNormalization, jboolean jmetadataOnly,
+    jboolean jcheckNormalization, jboolean jmetadataOnly,
     jobject jcallback)
 {
   JNIEntry(SVNRepos, verify);
@@ -447,7 +447,7 @@ Java_org_apache_subversion_javahl_SVNRep
     return;
 
   cl->verify(path, revisionStart, revisionEnd,
-             jkeepGoing, jcheckNormalization, jmetadataOnly,
+             jcheckNormalization, jmetadataOnly,
              jcallback != NULL ? &callback : NULL);
 }
 

Modified: 
subversion/branches/move-tracking-2/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRepos.java
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRepos.java?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- 
subversion/branches/move-tracking-2/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRepos.java
 (original)
+++ 
subversion/branches/move-tracking-2/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRepos.java
 Mon Jun 29 13:42:10 2015
@@ -299,7 +299,6 @@ public interface ISVNRepos {
      * @param path              the path to the repository
      * @param start             the first revision
      * @param end               the last revision
-         * @param keepGoing         continue verification even if a revision 
is bad
          * @param checkNormalization report directory entry and mergeinfo name 
collisions
          *                           caused by denormalized Unicode 
representations
          * @param metadataOnly      check only metadata, not file contents
@@ -308,8 +307,7 @@ public interface ISVNRepos {
          * @since 1.9
      */
     public abstract void verify(File path, Revision start, Revision end,
-                boolean keepGoing, boolean checkNormalization,
-                boolean metadataOnly,
+                boolean checkNormalization, boolean metadataOnly,
                 ReposNotifyCallback callback)
             throws ClientException;
 

Modified: 
subversion/branches/move-tracking-2/subversion/bindings/javahl/src/org/apache/subversion/javahl/ReposNotifyInformation.java
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/bindings/javahl/src/org/apache/subversion/javahl/ReposNotifyInformation.java?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- 
subversion/branches/move-tracking-2/subversion/bindings/javahl/src/org/apache/subversion/javahl/ReposNotifyInformation.java
 (original)
+++ 
subversion/branches/move-tracking-2/subversion/bindings/javahl/src/org/apache/subversion/javahl/ReposNotifyInformation.java
 Mon Jun 29 13:42:10 2015
@@ -199,12 +199,6 @@ public class ReposNotifyInformation exte
         verify_rev_structure,
 
         /**
-         * A revision is found with corruption/errors.
-         * @since 1.9
-         */
-        failure,
-
-        /**
          * A revprop shard got packed. @
          * @since 1.9
          */

Modified: 
subversion/branches/move-tracking-2/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNRepos.java
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNRepos.java?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- 
subversion/branches/move-tracking-2/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNRepos.java
 (original)
+++ 
subversion/branches/move-tracking-2/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNRepos.java
 Mon Jun 29 13:42:10 2015
@@ -238,12 +238,11 @@ public class SVNRepos implements ISVNRep
                        ReposNotifyCallback callback)
             throws ClientException
     {
-        verify(path, start, end, false, false, false, callback);
+        verify(path, start, end, false, false, callback);
     }
 
     public native void verify(File path, Revision start, Revision end,
-                              boolean keepGoing, boolean checkNormalization,
-                              boolean metadataOnly,
+                              boolean checkNormalization, boolean metadataOnly,
                               ReposNotifyCallback callback)
             throws ClientException;
 

Modified: 
subversion/branches/move-tracking-2/subversion/include/private/svn_wc_private.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/private/svn_wc_private.h?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- 
subversion/branches/move-tracking-2/subversion/include/private/svn_wc_private.h 
(original)
+++ 
subversion/branches/move-tracking-2/subversion/include/private/svn_wc_private.h 
Mon Jun 29 13:42:10 2015
@@ -1905,6 +1905,17 @@ svn_wc__diff7(const char **root_relpath,
               apr_pool_t *result_pool,
               apr_pool_t *scratch_pool);
 
+/**
+ * Read all conflicts at LOCAL_ABSPATH into an array containing pointers to
+ * svn_wc_conflict_description2_t data structures alloated in RESULT_POOL.
+ */
+svn_error_t *
+svn_wc__read_conflict_descriptions2_t(const apr_array_header_t **conflicts,
+                                      svn_wc_context_t *wc_ctx,
+                                      const char *local_abspath,
+                                      apr_pool_t *result_pool,
+                                      apr_pool_t *scratch_pool);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/branches/move-tracking-2/subversion/include/svn_client.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/svn_client.h?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/svn_client.h 
(original)
+++ subversion/branches/move-tracking-2/subversion/include/svn_client.h Mon Jun 
29 13:42:10 2015
@@ -4361,6 +4361,188 @@ svn_client_revert(const apr_array_header
  * @{
  */
 
+typedef struct svn_client_conflict_t svn_client_conflict_t;
+
+typedef struct svn_client_conflict_option_t svn_client_conflict_option_t;
+
+/**
+ * A public enumuneration of conflict option IDs.
+ *
+ * @since New in 1.10, unless noted otherwise.
+ */
+typedef enum svn_client_conflict_option_id_t {
+
+  /* These values intentionally mirror svn_wc_conflict_choice_t. */
+  svn_client_conflict_option_undefined = -1, /* for private use only */
+  svn_client_conflict_option_postpone = 0,
+  svn_client_conflict_option_base_text,
+  svn_client_conflict_option_incoming_new_text,
+  svn_client_conflict_option_working_text,
+  svn_client_conflict_option_incoming_new_text_for_conflicted_hunks_only,
+  svn_client_conflict_option_working_text_for_conflicted_hunks_only,
+  svn_client_conflict_option_merged_text, /* unsupported */
+  svn_client_conflict_option_unspecified
+  /* Values derived from svn_wc_conflict_choice_t end here. */
+
+} svn_client_conflict_option_id_t;
+
+/**
+ * Return a conflict for the conflicted path @a local_abspath.
+ * 
+ * @since New in 1.10.
+ */
+svn_error_t *
+svn_client_conflict_get(svn_client_conflict_t **conflict,
+                        const char *local_abspath,
+                        svn_client_ctx_t *ctx,
+                        apr_pool_t *result_pool,
+                        apr_pool_t *scratch_pool);
+
+/**
+ * Return a conflict corresponding to legacy conflict description @a desc.
+ * 
+ * @since New in 1.10.
+ */
+svn_error_t *
+svn_client_conflict_from_wc_description2_t(
+  svn_client_conflict_t **conflict,
+  const svn_wc_conflict_description2_t *desc,
+  apr_pool_t *result_pool,
+  apr_pool_t *scratch_pool);
+
+/**
+ * Callback for svn_client_conflict_walk_conflicts();
+ * 
+ * @since New in 1.10.
+ */
+typedef svn_error_t *(svn_client_conflict_walk_func_t)(
+  void *baton,
+  svn_client_conflict_t *conflict,
+  apr_pool_t *scratch_pool);
+
+/**
+ * Walk all conflicts within the specified @a depth of @a local_abspath.
+ * Pass each conflict found during the walk to the @conflict_walk_func
+ * callback, along with @a conflict_walk_func_baton.
+ * Use cancellation and notification support provided by client context @a ctx.
+ * 
+ * This callback may choose to resolve the conflict. If the act of resolving
+ * a conflict creates new conflicts within the walked working copy (as might
+ * be the case for some tree conflicts), the callback will be invoked for each
+ * such new conflict as well.
+ * 
+ * @since New in 1.10.
+ */
+svn_error_t *
+svn_client_conflict_walk(const char *local_abspath,
+                         svn_depth_t depth,
+                         svn_client_conflict_walk_func_t conflict_walk_func,
+                         void *conflict_walk_func_baton,
+                         svn_client_ctx_t *ctx,
+                         apr_pool_t *scratch_pool);
+
+/**
+* Indicate the types of conflicts present on the working copy node
+* described by @a conflict. Any output argument may be @c NULL if
+* the caller is not interested in the status of a particular type.
+*
+* The returned @a *props_conflicted array is allocated in @a result_pool.
+* It contains the names of conflicted properties. If no property conflit
+* exists, the array will contain no elements.
+*
+* @since New in 1.10. 
+*/
+svn_error_t *
+svn_client_conflict_get_conflicted(svn_boolean_t *text_conflicted,
+                                   apr_array_header_t **props_conflicted,
+                                   svn_boolean_t *tree_conflicted,
+                                   svn_client_conflict_t *conflict,
+                                   apr_pool_t *result_pool,
+                                   apr_pool_t *scratch_pool);
+
+/**
+ * Set @a *options to an array of pointers to svn_client_conflict_option_t
+ * objects applicable to text conflicts described by @a conflict.
+ *
+ * @since New in 1.10.
+ */
+svn_error_t *
+svn_client_conflict_text_get_resolution_options(apr_array_header_t **options,
+                                                svn_client_conflict_t 
*conflict,
+                                                apr_pool_t *result_pool,
+                                                apr_pool_t *scratch_pool);
+
+/**
+ * Set @a *options to an array of pointers to svn_client_conflict_option_t
+ * objects applicable to property conflicts described by @a conflict.
+ *
+ * @since New in 1.10.
+ */
+svn_error_t *
+svn_client_conflict_prop_get_resolution_options(apr_array_header_t **options,
+                                                svn_client_conflict_t 
*conflict,
+                                                apr_pool_t *result_pool,
+                                                apr_pool_t *scratch_pool);
+
+/**
+ * Set @a *options to an array of pointers to svn_client_conflict_option_t
+ * objects applicable to the tree conflict described by @a conflict.
+ *
+ * @since New in 1.10.
+ */
+svn_error_t *
+svn_client_conflict_tree_get_resolution_options(apr_array_header_t **options,
+                                                svn_client_conflict_t 
*conflict,
+                                                apr_pool_t *result_pool,
+                                                apr_pool_t *scratch_pool);
+
+/**
+ * Return an ID for @a option. This ID can be used by callers to associate
+ * arbitrary data with a particular conflict resolution option.
+ *
+ * The ID of a particular resolution option will never change in future
+ * revisions of this API.
+ *
+ * @since New in 1.10.
+ */
+svn_client_conflict_option_id_t
+svn_client_conflict_option_get_id(svn_client_conflict_option_t *option);
+
+/**
+ * Return a textual human-readable description of @a option, allocated in
+ * @a result_pool. The description is encoded in UTF-8 and may contain
+ * multiple lines separated by @c APR_EOL_STR.
+ *
+ * Additionally, the description may be localized to the language used
+ * by the current locale.
+ *
+ * @since New in 1.10.
+ */
+svn_error_t *
+svn_client_conflict_option_describe(const char **description,
+                                    svn_client_conflict_option_t *option,
+                                    apr_pool_t *result_pool,
+                                    apr_pool_t *scratch_pool);
+
+/**
+ * Resolve @a conflict using resolution option @a option.
+ *
+ * @since New in 1.10.
+ */
+svn_error_t *
+svn_client_conflict_resolve(svn_client_conflict_t *conflict,
+                            svn_client_conflict_option_t *option,
+                            apr_pool_t *scratch_pool);
+
+/**
+ * Return the kind of conflict (text conflict, property conflict,
+ * or tree conflict) represented by @a conflict.
+ *
+ * New in 1.10.
+ */
+svn_wc_conflict_kind_t
+svn_client_conflict_get_kind(const svn_client_conflict_t *conflict);
+
 /**
  * Return the absolute path to the conflicted working copy node described
  * by @a conflict.
@@ -4368,8 +4550,7 @@ svn_client_revert(const apr_array_header
  * @since New in 1.10. 
  */
 const char *
-svn_client_conflict_get_local_abspath(
-  const svn_wc_conflict_description2_t *conflict);
+svn_client_conflict_get_local_abspath(const svn_client_conflict_t *conflict);
 
 /**
  * Return the operation during which the conflict described by @a
@@ -4378,8 +4559,7 @@ svn_client_conflict_get_local_abspath(
  * @since New in 1.10. 
  */
 svn_wc_operation_t
-svn_client_conflict_get_operation(
-  const svn_wc_conflict_description2_t *conflict);
+svn_client_conflict_get_operation(const svn_client_conflict_t *conflict);
 
 /**
  * Return the action an update, switch, or merge operation attempted to
@@ -4388,8 +4568,7 @@ svn_client_conflict_get_operation(
  * @since New in 1.10. 
  */
 svn_wc_conflict_action_t
-svn_client_conflict_get_incoming_change(
-  const svn_wc_conflict_description2_t *conflict);
+svn_client_conflict_get_incoming_change(const svn_client_conflict_t *conflict);
 
 /**
  * Return the reason why the attempted action performed by an update, switch,
@@ -4403,61 +4582,152 @@ svn_client_conflict_get_incoming_change(
  * @since New in 1.10. 
  */
 svn_wc_conflict_reason_t
-svn_client_conflict_get_local_change(
-  const svn_wc_conflict_description2_t *conflict);
+svn_client_conflict_get_local_change(const svn_client_conflict_t *conflict);
 
 /**
- * Accessor functions for svn_wc_conflict_description2_t. This is a temporary
- * API for eventually replacing svn_wc_conflict_description2_t with an opaque
- * type and providing improved APIs for conflict resolution.
- * 
- * @since New in 1.10. 
+ * Return information about the repository associated with @a conflict. 
+ * In case of a foreign-repository merge this will differ from the
+ * repository information associated with the merge target working copy.
+ *
+ * @since New in 1.10.
  */
+svn_error_t *
+svn_client_conflict_get_repos_info(const char **repos_root_url,
+                                   const char **repos_uuid,
+                                   const svn_client_conflict_t *conflict,
+                                   apr_pool_t *result_pool,
+                                   apr_pool_t *scratch_pool);
 
-#define svn_client_conflict_get_node_kind(conflict) \
-  ((conflict)->node_kind)
-
-#define svn_client_conflict_get_kind(conflict) \
-  ((conflict)->kind)
-
-#define svn_client_conflict_get_property_name(conflict) \
-  ((conflict)->property_name)
-
-#define svn_client_conflict_get_is_binary(conflict) \
-  ((conflict)->is_binary)
-
-#define svn_client_conflict_get_mime_type(conflict) \
-  ((conflict)->mime_type)
-
-#define svn_client_conflict_get_base_abspath(conflict) \
-  ((conflict)->base_abspath)
-
-#define svn_client_conflict_get_their_abspath(conflict) \
-  ((conflict)->their_abspath)
-
-#define svn_client_conflict_get_my_abspath(conflict) \
-  ((conflict)->my_abspath)
+/**
+ * Return the repository-relative location and the node kind of the incoming
+ * old version of the conflicted node described by @a conflict.
+ *
+ * If the repository-relative path is not available, the @a
+ * *incoming_old_repos_relpath will be set to @c NULL, 
+ *
+ * If the peg revision is not available, @a *incoming_old_regrev will be
+ * set to SVN_INVALID_REVNUM.
+ * 
+ * If the node kind is not available or if the node does not exist at the
+ * specified path and revision, @a *incoming_old_node_kind will be set to
+ * svn_node_none.
+ * ### Should return svn_node_unkown if not available?
+ *
+ * Any output parameter may be set to @c NULL by the caller to indicate that
+ * a particular piece of information should not be returned.
+ *
+ * In case of tree conflicts, this path@revision does not necessarily exist
+ * in the repository, and it does not necessarily represent the incoming
+ * change which is responsible for the occurance of the tree conflict.
+ * The responsible incoming change is generally located somewhere between
+ * the old and new incoming versions.
+ *
+ * @since New in 1.10.
+ */
+svn_error_t *
+svn_client_conflict_get_incoming_old_repos_location(
+  const char **incoming_old_repos_relpath,
+  svn_revnum_t *incoming_old_regrev,
+  svn_node_kind_t *incoming_old_node_kind,
+  const svn_client_conflict_t *conflict,
+  apr_pool_t *result_pool,
+  apr_pool_t *scratch_pool);
 
-#define svn_client_conflict_get_merged_file(conflict) \
-  ((conflict)->merged_file)
+/**
+ * Like svn_client_conflict_get_incoming_old_repos_location(), expect this
+ * function returns the same data for the incoming new version.
+ *
+ * The same note about tree conflicts applies.
+ *
+ * @since New in 1.10.
+ */
+svn_error_t *
+svn_client_conflict_get_incoming_new_repos_location(
+  const char **incoming_new_repos_relpath,
+  svn_revnum_t *incoming_new_regrev,
+  svn_node_kind_t *incoming_new_node_kind,
+  const svn_client_conflict_t *conflict,
+  apr_pool_t *result_pool,
+  apr_pool_t *scratch_pool);
 
-#define svn_client_conflict_get_src_left_version(conflict) \
-  ((conflict)->src_left_version)
+/**
+ * Return the node kind of the tree conflict victim described by @a conflict.
+ * The victim is the local node in the working copy which was affected by the
+ * tree conflict at the time the conflict was raised.
+ *
+ * @since New in 1.10.
+ */
+svn_node_kind_t
+svn_client_conflict_tree_get_victim_node_kind(
+  const svn_client_conflict_t *conflict);
 
-#define svn_client_conflict_get_src_right_version(conflict) \
-  ((conflict)->src_right_version)
+/**
+ * Return the name of the conflicted property represented by @a conflict.
+ *
+ * @since New in 1.10.
+ */
+const char *
+svn_client_conflict_prop_get_propname(const svn_client_conflict_t *conflict);
 
-#define svn_client_conflict_get_prop_reject_abspath(conflict) \
-  ((conflict)->prop_reject_abspath)
+/**
+ * Return the path to the legacy property conflicts reject file
+ * for the property conflicts represented by @a conflict.
+ *
+ * This function exists for backwards compatibility only and should not be
+ * used in new code.
+ *
+ * @since New in 1.10.
+ */
+const char *
+svn_client_conflict_prop_get_reject_abspath(
+  const svn_client_conflict_t *conflict);
 
-#define svn_client_conflict_get_prop_value_working(conflict) \
-  ((conflict)->prop_value_working)
+/**
+ * Return the set of property values involved in the property conflict
+ * described by @a conflict. If a property value is unavailable the
+ * corresponding output argument is set to @c NULL.
+ *  
+ * A 3-way diff of these property values can be generated with
+ * svn_diff_mem_string_diff3(). A merged version with conflict
+ * markers can be generated with svn_diff_mem_string_output_merge3().
+ *
+ * @since New in 1.10.
+ */
+svn_error_t *
+svn_client_conflict_prop_get_propvals(const svn_string_t **base_propval,
+                                      const svn_string_t **working_propval,
+                                      const svn_string_t 
**incoming_old_propval,
+                                      const svn_string_t 
**incoming_new_propval,
+                                      const svn_client_conflict_t *conflict,
+                                      apr_pool_t *result_pool);
 
-#define svn_client_conflict_get_prop_value_incoming_old(conflict) \
-  ((conflict)->prop_value_incoming_old)
+/**
+ * Return the MIME-type of the working version of the text-conflicted file
+ * described by @a conflict.
+ *
+ * ### Really needed? What about base/incoming_old/incoming_new values?
+ * @since: New in 1.10.
+ */
+const char *
+svn_client_conflict_text_get_mime_type(const svn_client_conflict_t *conflict);
 
-#define svn_client_conflict_get_prop_value_incoming_new(conflict) \
-  ((conflict)->prop_value_incoming_new)
+/**
+ * Return absolute paths to the versions of the text-conflicted file 
+ * described by @a conflict.
+ *
+ * If a particular content is not available, it is set to @c NULL.
+ * 
+ * ### Should this be returning svn_stream_t instead of paths?
+ * @since: New in 1.10.
+ */
+svn_error_t *
+svn_client_conflict_text_get_contents(const char **base_abspath,
+                                      const char **working_abspath,
+                                      const char **incoming_old_abspath,
+                                      const char **incoming_new_abspath,
+                                      const svn_client_conflict_t *conflict,
+                                      apr_pool_t *result_pool,
+                                      apr_pool_t *scratch_pool);
 
 /** @} */
 

Modified: 
subversion/branches/move-tracking-2/subversion/include/svn_error_codes.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/svn_error_codes.h?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/svn_error_codes.h 
(original)
+++ subversion/branches/move-tracking-2/subversion/include/svn_error_codes.h 
Mon Jun 29 13:42:10 2015
@@ -922,11 +922,6 @@ SVN_ERROR_START
              SVN_ERR_REPOS_CATEGORY_START + 10,
              "Repository upgrade is not supported")
 
-  /** @since New in 1.9. */
-  SVN_ERRDEF(SVN_ERR_REPOS_VERIFY_FAILED,
-             SVN_ERR_REPOS_CATEGORY_START + 11,
-             "Repository verification failed")
-
   /* generic RA errors */
 
   SVN_ERRDEF(SVN_ERR_RA_ILLEGAL_URL,
@@ -1497,6 +1492,11 @@ SVN_ERROR_START
              SVN_ERR_CL_CATEGORY_START + 11,
              "Failed processing one or more externals definitions")
 
+  /** @since New in 1.9. */
+  SVN_ERRDEF(SVN_ERR_CL_REPOS_VERIFY_FAILED,
+             SVN_ERR_CL_CATEGORY_START + 12,
+             "Repository verification failed")
+
   /* ra_svn errors */
 
   SVN_ERRDEF(SVN_ERR_RA_SVN_CMD_ERR,

Modified: subversion/branches/move-tracking-2/subversion/include/svn_repos.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/svn_repos.h?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/svn_repos.h 
(original)
+++ subversion/branches/move-tracking-2/subversion/include/svn_repos.h Mon Jun 
29 13:42:10 2015
@@ -234,9 +234,6 @@ typedef enum svn_repos_notify_action_t
   /** The structure of a revision is being verified.  @since New in 1.8. */
   svn_repos_notify_verify_rev_structure,
 
-  /** A revision is found with corruption/errors. @since New in 1.9. */
-  svn_repos_notify_failure,
-
   /** A revprop shard got packed. @since New in 1.9. */
   svn_repos_notify_pack_revprops,
 
@@ -348,11 +345,6 @@ typedef struct svn_repos_notify_t
   /** For #svn_repos_notify_load_node_start, the path of the node. */
   const char *path;
 
-  /** For #svn_repos_notify_failure, this error chain indicates what
-      went wrong during verification.
-      @since New in 1.9. */
-  svn_error_t *err;
-
   /** For #svn_repos_notify_hotcopy_rev_range, the start of the copied
       revision range.
       @since New in 1.9. */
@@ -2825,6 +2817,28 @@ enum svn_repos_load_uuid
   svn_repos_load_uuid_force
 };
 
+/** Callback type for use with svn_repos_verify_fs3().  @a revision
+ * and @a verify_err are the details of a single verification failure
+ * that occurred during the svn_repos_verify_fs3() call.  @a baton is
+ * the same baton given to svn_repos_verify_fs3().  @a scratch_pool is
+ * provided for the convenience of the implementor, who should not
+ * expect it to live longer than a single callback call.
+ *
+ * @a verify_err will be cleared and becomes invalid after the callback
+ * returns, use svn_error_dup() to preserve the error.  If a callback uses
+ * @a verify_err as the return value or as a part of the return value, it
+ * should also call svn_error_dup() for @a verify_err.  Implementors of this
+ * callback are forbidden to call svn_error_clear() for @a verify_err.
+ *
+ * @see svn_repos_verify_fs3
+ *
+ * @since New in 1.9.
+ */
+typedef svn_error_t *(*svn_repos_verify_callback_t)(void *baton,
+                                                    svn_revnum_t revision,
+                                                    svn_error_t *verify_err,
+                                                    apr_pool_t *scratch_pool);
+
 /**
  * Verify the contents of the file system in @a repos.
  *
@@ -2835,9 +2849,6 @@ enum svn_repos_load_uuid
  * range, then also verify "global invariants" of the repository, as
  * described in svn_fs_verify().
  *
- * When a failure is found, if @a keep_going is @c TRUE then continue
- * verification from the next revision, otherwise stop.
- *
  * If @a check_normalization is @c TRUE, report any name collisions
  * within the same directory or svn:mergeinfo property where the names
  * differ only in character representation, but are otherwise
@@ -2848,25 +2859,31 @@ enum svn_repos_load_uuid
  * file context reconstruction and verification.  For FSFS format 7+ and
  * FSX, this allows for a very fast check against external corruption.
  *
+ * If @a verify_callback is not @c NULL, call it with @a verify_baton upon
+ * receiving an FS-specific structure failure or a revision verification
+ * failure.  Set @c revision callback argument to #SVN_INVALID_REVNUM or
+ * to the revision number respectively.  Set @c verify_err to svn_error_t
+ * describing the reason of the failure.  @c verify_err will be cleared
+ * after the callback returns, use svn_error_dup() to preserve the error.
+ * If @a verify_callback returns an error different from #SVN_NO_ERROR,
+ * stop verifying the repository and immediately return the error from
+ * @a verify_callback.
+ *
+ * If @a verify_callback is @c NULL, this function returns the first
+ * encountered verification error or #SVN_NO_ERROR if there were no failures
+ * during the verification.  Errors that prevent the verification process
+ * from continuing, such as #SVN_ERR_CANCELLED, are returned immediately
+ * and do not trigger an invocation of @a verify_callback.
+ *
  * If @a notify_func is not null, then call it with @a notify_baton and
  * with a notification structure in which the fields are set as follows.
- * (For a warning or error notification that does not apply to a specific
- * revision, the revision number is #SVN_INVALID_REVNUM.)
+ * (For a warning that does not apply to a specific revision, the revision
+ * number is #SVN_INVALID_REVNUM.)
  *
  *   For each FS-specific structure warning:
  *      @c action = svn_repos_notify_verify_rev_structure
  *      @c revision = the revision or #SVN_INVALID_REVNUM
  *
- *   For a FS-specific structure failure:
- *      @c action = #svn_repos_notify_failure
- *      @c revision = #SVN_INVALID_REVNUM
- *      @c err = the corresponding error chain
- *
- *   For each revision verification failure:
- *      @c action = #svn_repos_notify_failure
- *      @c revision = the revision
- *      @c err = the corresponding error chain
- *
  *   For each revision verification warning:
  *      @c action = #svn_repos_notify_warning
  *      @c warning and @c warning_str fields set accordingly
@@ -2888,10 +2905,7 @@ enum svn_repos_load_uuid
  *
  * Use @a scratch_pool for temporary allocation.
  *
- * Return an error if there were any failures during verification, or
- * #SVN_NO_ERROR if there were no failures.  A failure means an event that,
- * if a notification callback were provided, would send a notification
- * with @c action = #svn_repos_notify_failure.
+ * @see svn_repos_verify_callback_t
  *
  * @since New in 1.9.
  */
@@ -2899,18 +2913,20 @@ svn_error_t *
 svn_repos_verify_fs3(svn_repos_t *repos,
                      svn_revnum_t start_rev,
                      svn_revnum_t end_rev,
-                     svn_boolean_t keep_going,
                      svn_boolean_t check_normalization,
                      svn_boolean_t metadata_only,
                      svn_repos_notify_func_t notify_func,
                      void *notify_baton,
+                     svn_repos_verify_callback_t verify_callback,
+                     void *verify_baton,
                      svn_cancel_func_t cancel,
                      void *cancel_baton,
                      apr_pool_t *scratch_pool);
 
 /**
- * Like svn_repos_verify_fs3(), but with @a keep_going,
- * @a check_normalization and @a metadata_only set to @c FALSE.
+ * Like svn_repos_verify_fs3(), but with @a verify_callback and
+ * @a verify_baton set to @c NULL and with @a check_normalization
+ * and @a metadata_only set to @c FALSE.
  *
  * @since New in 1.7.
  * @deprecated Provided for backward compatibility with the 1.8 API.

Modified: 
subversion/branches/move-tracking-2/subversion/libsvn_client/resolved.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_client/resolved.c?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_client/resolved.c 
(original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_client/resolved.c Mon 
Jun 29 13:42:10 2015
@@ -41,6 +41,9 @@
 #include "private/svn_wc_private.h"
 
 #include "svn_private_config.h"
+
+#define ARRAY_LEN(ary) ((sizeof (ary)) / (sizeof ((ary)[0])))
+
 
 /*** Code. ***/
 
@@ -148,30 +151,823 @@ svn_client_resolve(const char *path,
 
 /*** Dealing with conflicts. ***/
 
+struct svn_client_conflict_t
+{
+  const char *local_abspath;
+  svn_client_ctx_t *ctx;
+  apr_hash_t *prop_conflicts;
+
+  /* For backwards compat. */
+  const svn_wc_conflict_description2_t *legacy_text_conflict;
+  const svn_wc_conflict_description2_t *legacy_prop_conflict;
+  const svn_wc_conflict_description2_t *legacy_tree_conflict;
+};
+
+static void
+add_legacy_desc_to_conflict(const svn_wc_conflict_description2_t *desc,
+                            svn_client_conflict_t *conflict,
+                            apr_pool_t *result_pool)
+{
+  switch (desc->kind)
+    {
+      case svn_wc_conflict_kind_text:
+        conflict->legacy_text_conflict = desc;
+        break;
+
+      case svn_wc_conflict_kind_property:
+        conflict->legacy_prop_conflict = desc;
+        break;
+
+      case svn_wc_conflict_kind_tree:
+        conflict->legacy_tree_conflict = desc;
+        break;
+
+      default:
+        SVN_ERR_ASSERT_NO_RETURN(FALSE); /* unknown kind of conflict */
+    }
+}
+
+/* Set up a conflict object. If legacy conflict descriptor DESC is not NULL,
+ * set up the conflict object for backwards compatibility. */
+static svn_error_t *
+conflict_get_internal(svn_client_conflict_t **conflict,
+                      const char *local_abspath,
+                      const svn_wc_conflict_description2_t *desc,
+                      svn_client_ctx_t *ctx,
+                      apr_pool_t *result_pool,
+                      apr_pool_t *scratch_pool)
+{
+  const apr_array_header_t *descs;
+  int i;
+
+  *conflict = apr_pcalloc(result_pool, sizeof(**conflict));
+
+  if (desc)
+    {
+      /* Add a single legacy conflict descriptor. */
+      (*conflict)->local_abspath = desc->local_abspath;
+      add_legacy_desc_to_conflict(desc, *conflict, result_pool);
+
+      return SVN_NO_ERROR;
+    }
+
+  (*conflict)->local_abspath = apr_pstrdup(result_pool, local_abspath);
+  (*conflict)->ctx = ctx;
+
+  /* Add all legacy conflict descriptors we can find. Eventually, this code
+   * path should stop relying on svn_wc_conflict_description2_t entirely. */
+  SVN_ERR(svn_wc__read_conflict_descriptions2_t(&descs, ctx->wc_ctx,
+                                                local_abspath,
+                                                result_pool, scratch_pool));
+  for (i = 0; i < descs->nelts; i++)
+    {
+      desc = APR_ARRAY_IDX(descs, i, const svn_wc_conflict_description2_t *);
+      if (desc->kind == svn_wc_conflict_kind_property)
+        {
+          if ((*conflict)->prop_conflicts == NULL)
+            (*conflict)->prop_conflicts = apr_hash_make(result_pool);
+          svn_hash_sets((*conflict)->prop_conflicts, desc->property_name, 
desc);
+        }
+      else
+        add_legacy_desc_to_conflict(desc, *conflict, result_pool);
+    }
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_conflict_get(svn_client_conflict_t **conflict,
+                        const char *local_abspath,
+                        svn_client_ctx_t *ctx,
+                        apr_pool_t *result_pool,
+                        apr_pool_t *scratch_pool)
+{
+  return svn_error_trace(conflict_get_internal(conflict, local_abspath, NULL,
+                                               ctx, result_pool, 
scratch_pool));
+}
+
+svn_error_t *
+svn_client_conflict_from_wc_description2_t(
+  svn_client_conflict_t **conflict,
+  const svn_wc_conflict_description2_t *desc,
+  apr_pool_t *result_pool,
+  apr_pool_t *scratch_pool)
+{
+  return svn_error_trace(conflict_get_internal(conflict, NULL, desc, NULL,
+                                               result_pool, scratch_pool));
+}
+
+/* Baton type for conflict_walk_status_func(). */
+typedef struct conflict_walk_status_baton_t {
+
+  svn_client_conflict_walk_func_t *conflict_walk_func;
+  void *conflict_walk_func_baton;
+
+  svn_client_ctx_t *ctx;
+  int conflicts_found;
+  
+} conflict_walk_status_baton_t;
+
+/* Implements svn_wc_status_func4_t. */
+static svn_error_t *
+conflict_walk_status_func(void *baton,
+                          const char *local_abspath,
+                          const svn_wc_status3_t *status,
+                          apr_pool_t *scratch_pool)
+{
+  conflict_walk_status_baton_t *b = baton;
+  svn_client_conflict_t *conflict;
+
+  if (!status->conflicted)
+    return SVN_NO_ERROR;
+
+  b->conflicts_found++;
+
+  SVN_ERR(svn_client_conflict_get(&conflict, local_abspath, b->ctx,
+                                  scratch_pool, scratch_pool));
+  SVN_ERR(b->conflict_walk_func(b->conflict_walk_func_baton,
+                                conflict, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_conflict_walk(const char *local_abspath,
+                         svn_depth_t depth,
+                         svn_client_conflict_walk_func_t conflict_walk_func,
+                         void *conflict_walk_func_baton,
+                         svn_client_ctx_t *ctx,
+                         apr_pool_t *scratch_pool)
+{
+  conflict_walk_status_baton_t b;
+
+  b.conflict_walk_func = conflict_walk_func;
+  b.conflict_walk_func_baton = conflict_walk_func_baton;
+  b.ctx = ctx;
+
+  /* ### Re-run the status walk until a walk finds no conflicts at all.
+   * ### This is a crude implementation but provides the guarantees we offer
+   * ### to the caller. To optimize we should check for notifications of new
+   * ### conflicts created during the first status walk and then keep invoking
+   * ### the callback directly on any new conflicts.
+   */
+  do
+    {
+      b.conflicts_found = 0;
+      SVN_ERR(svn_wc_walk_status(ctx->wc_ctx, local_abspath, depth,
+                                 FALSE, /* get_all */
+                                 FALSE, /* no_ignore, */
+                                 TRUE,  /* ignore_externals */
+                                 NULL, /* ignore_patterns */
+                                 conflict_walk_status_func, &b,
+                                 ctx->cancel_func, ctx->cancel_baton,
+                                 scratch_pool));
+    }
+  while (b.conflicts_found > 0);
+
+  return SVN_NO_ERROR;
+}
+
+typedef svn_error_t *(*conflict_option_resolve_func_t)(
+  svn_client_conflict_option_t *option,
+  svn_client_conflict_t *conflict,
+  apr_pool_t *scratch_pool);
+
+struct svn_client_conflict_option_t
+{
+  svn_client_conflict_option_id_t id;
+  const char *description;
+
+  svn_client_conflict_t *conflict;
+  conflict_option_resolve_func_t do_resolve_func;
+};
+
+static svn_error_t *
+resolve_postpone(svn_client_conflict_option_t *option,
+                 svn_client_conflict_t *conflict,
+                 apr_pool_t *scratch_pool)
+{
+  /* Nothing to do. */
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+resolve_text_conflict(svn_client_conflict_option_t *option,
+                      svn_client_conflict_t *conflict,
+                      apr_pool_t *scratch_pool)
+{
+  svn_client_conflict_option_id_t id;
+  const char *local_abspath;
+
+  id = svn_client_conflict_option_get_id(option);
+  local_abspath = svn_client_conflict_get_local_abspath(conflict);
+
+  SVN_ERR(svn_wc_resolved_conflict5(conflict->ctx->wc_ctx, local_abspath,
+                                    svn_depth_empty, TRUE, NULL, FALSE,
+                                    id, /* option id is backwards compatible */
+                                    conflict->ctx->cancel_func,
+                                    conflict->ctx->cancel_baton,
+                                    conflict->ctx->notify_func2,
+                                    conflict->ctx->notify_baton2,
+                                    scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+resolve_prop_conflict(svn_client_conflict_option_t *option,
+                      svn_client_conflict_t *conflict,
+                      apr_pool_t *scratch_pool)
+{
+  svn_client_conflict_option_id_t id;
+  const char *local_abspath;
+
+  id = svn_client_conflict_option_get_id(option);
+  local_abspath = svn_client_conflict_get_local_abspath(conflict);
+
+  SVN_ERR(svn_wc_resolved_conflict5(conflict->ctx->wc_ctx, local_abspath,
+                                    svn_depth_empty, TRUE, "", FALSE,
+                                    id, /* option id is backwards compatible */
+                                    conflict->ctx->cancel_func,
+                                    conflict->ctx->cancel_baton,
+                                    conflict->ctx->notify_func2,
+                                    conflict->ctx->notify_baton2,
+                                    scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+resolve_tree_conflict(svn_client_conflict_option_t *option,
+                      svn_client_conflict_t *conflict,
+                      apr_pool_t *scratch_pool)
+{
+  svn_client_conflict_option_id_t id;
+  const char *local_abspath;
+
+  id = svn_client_conflict_option_get_id(option);
+  local_abspath = svn_client_conflict_get_local_abspath(conflict);
+
+  SVN_ERR(svn_wc_resolved_conflict5(conflict->ctx->wc_ctx, local_abspath,
+                                    svn_depth_empty, FALSE, NULL, TRUE,
+                                    id, /* option id is backwards compatible */
+                                    conflict->ctx->cancel_func,
+                                    conflict->ctx->cancel_baton,
+                                    conflict->ctx->notify_func2,
+                                    conflict->ctx->notify_baton2,
+                                    scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+/* Resolver options for a text conflict */
+static const svn_client_conflict_option_t text_conflict_options[] =
+{
+  {
+    svn_client_conflict_option_postpone,
+    N_("mark the conflict to be resolved later"),
+    NULL,
+    resolve_postpone
+  },
+
+  {
+    svn_client_conflict_option_incoming_new_text,
+    N_("accept incoming version of entire file"),
+    NULL,
+    resolve_text_conflict
+  },
+
+  {
+    svn_client_conflict_option_working_text,
+    N_("accept working copy version of entire file"),
+    NULL,
+    resolve_text_conflict
+  },
+
+  {
+    svn_client_conflict_option_incoming_new_text_for_conflicted_hunks_only,
+    N_("accept incoming version of all text conflicts in file"),
+    NULL,
+    resolve_text_conflict
+  },
+
+  {
+    svn_client_conflict_option_working_text_for_conflicted_hunks_only,
+    N_("accept working copy version of all text conflicts in file"),
+    NULL,
+    resolve_text_conflict
+  },
+
+};
+
+/* Resolver options for a binary file conflict */
+static const svn_client_conflict_option_t binary_conflict_options[] =
+{
+  {
+    svn_client_conflict_option_postpone,
+    N_("mark the conflict to be resolved later"),
+    NULL,
+    resolve_postpone
+  },
+
+  {
+    svn_client_conflict_option_incoming_new_text,
+    N_("accept incoming version of binary file"),
+    NULL,
+    resolve_text_conflict
+  },
+
+  {
+    svn_client_conflict_option_working_text,
+    N_("accept working copy version of binary file"),
+    NULL,
+    resolve_text_conflict
+  },
+
+};
+
+/* Resolver options for a property conflict */
+static const svn_client_conflict_option_t prop_conflict_options[] =
+{
+  {
+    svn_client_conflict_option_postpone,
+    N_("mark the conflict to be resolved later"),
+    NULL,
+    resolve_postpone
+  },
+
+  {
+    svn_client_conflict_option_incoming_new_text,
+    N_("accept incoming version of entire property value"),
+    NULL,
+    resolve_prop_conflict
+  },
+
+  {
+    svn_client_conflict_option_working_text,
+    N_("accept working copy version of entire property value"),
+    NULL,
+    resolve_prop_conflict
+  },
+
+};
+
+/* Resolver options for a tree conflict */
+static const svn_client_conflict_option_t tree_conflict_options[] =
+{
+  {
+    svn_client_conflict_option_postpone,
+    N_("mark the conflict to be resolved later"),
+    NULL,
+    resolve_postpone
+  },
+
+  {
+    /* ### Use 'working text' for now since libsvn_wc does not know another
+     * ### choice to resolve to working yet. */
+    svn_client_conflict_option_working_text,
+    N_("accept current working copy state"),
+    NULL,
+    resolve_tree_conflict
+  },
+
+};
+
+static svn_error_t *
+assert_text_conflict(svn_client_conflict_t *conflict, apr_pool_t *scratch_pool)
+{
+  svn_boolean_t text_conflicted;
+
+  SVN_ERR(svn_client_conflict_get_conflicted(&text_conflicted, NULL, NULL,
+                                             conflict, scratch_pool,
+                                             scratch_pool));
+
+  SVN_ERR_ASSERT(text_conflicted); /* ### return proper error? */
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+assert_prop_conflict(svn_client_conflict_t *conflict, apr_pool_t *scratch_pool)
+{
+  apr_array_header_t *props_conflicted;
+
+  SVN_ERR(svn_client_conflict_get_conflicted(NULL, &props_conflicted, NULL,
+                                             conflict, scratch_pool,
+                                             scratch_pool));
+
+  /* ### return proper error? */
+  SVN_ERR_ASSERT(props_conflicted && props_conflicted->nelts > 0);
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+assert_tree_conflict(svn_client_conflict_t *conflict, apr_pool_t *scratch_pool)
+{
+  svn_boolean_t tree_conflicted;
+
+  SVN_ERR(svn_client_conflict_get_conflicted(NULL, NULL, &tree_conflicted,
+                                             conflict, scratch_pool,
+                                             scratch_pool));
+
+  SVN_ERR_ASSERT(tree_conflicted); /* ### return proper error? */
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_conflict_text_get_resolution_options(apr_array_header_t **options,
+                                                svn_client_conflict_t 
*conflict,
+                                                apr_pool_t *result_pool,
+                                                apr_pool_t *scratch_pool)
+{
+  const char *mime_type;
+  int i;
+
+  SVN_ERR(assert_text_conflict(conflict, scratch_pool));
+
+  *options = apr_array_make(result_pool, ARRAY_LEN(text_conflict_options),
+                            sizeof(svn_client_conflict_option_t *));
+
+  mime_type = svn_client_conflict_text_get_mime_type(conflict);
+  if (mime_type && svn_mime_type_is_binary(mime_type))
+    {
+      for (i = 0; i < ARRAY_LEN(binary_conflict_options); i++)
+        {
+          APR_ARRAY_PUSH((*options), const svn_client_conflict_option_t *) =
+            &binary_conflict_options[i];
+        }
+    }
+  else
+    {
+      for (i = 0; i < ARRAY_LEN(text_conflict_options); i++)
+        {
+          APR_ARRAY_PUSH((*options), const svn_client_conflict_option_t *) =
+            &text_conflict_options[i];
+        }
+    }
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_conflict_prop_get_resolution_options(apr_array_header_t **options,
+                                                svn_client_conflict_t 
*conflict,
+                                                apr_pool_t *result_pool,
+                                                apr_pool_t *scratch_pool)
+{
+  int i;
+
+  SVN_ERR(assert_prop_conflict(conflict, scratch_pool));
+
+  *options = apr_array_make(result_pool, ARRAY_LEN(prop_conflict_options),
+                            sizeof(svn_client_conflict_option_t *));
+  for (i = 0; i < ARRAY_LEN(prop_conflict_options); i++)
+    {
+      APR_ARRAY_PUSH((*options), const svn_client_conflict_option_t *) =
+        &prop_conflict_options[i];
+    }
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_conflict_tree_get_resolution_options(apr_array_header_t **options,
+                                                svn_client_conflict_t 
*conflict,
+                                                apr_pool_t *result_pool,
+                                                apr_pool_t *scratch_pool)
+{
+  int i;
+
+  SVN_ERR(assert_tree_conflict(conflict, scratch_pool));
+
+  *options = apr_array_make(result_pool, ARRAY_LEN(tree_conflict_options),
+                            sizeof(svn_client_conflict_option_t *));
+  for (i = 0; i < ARRAY_LEN(tree_conflict_options); i++)
+    {
+      APR_ARRAY_PUSH((*options), const svn_client_conflict_option_t *) =
+        &tree_conflict_options[i];
+    }
+
+  return SVN_NO_ERROR;
+}
+
+svn_client_conflict_option_id_t
+svn_client_conflict_option_get_id(svn_client_conflict_option_t *option)
+{
+  return option->id;
+}
+
+svn_error_t *
+svn_client_conflict_option_describe(const char **description,
+                                    svn_client_conflict_option_t *option,
+                                    apr_pool_t *result_pool,
+                                    apr_pool_t *scratch_pool)
+{
+  *description = apr_pstrdup(result_pool, option->description);
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_conflict_resolve(svn_client_conflict_t *conflict,
+                            svn_client_conflict_option_t *option,
+                            apr_pool_t *scratch_pool)
+{
+  SVN_ERR(option->do_resolve_func(option, conflict, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+/* Return the legacy conflict descriptor which is wrapped by CONFLICT. */
+static const svn_wc_conflict_description2_t *
+get_conflict_desc2_t(const svn_client_conflict_t *conflict)
+{
+  if (conflict->legacy_text_conflict)
+    return conflict->legacy_text_conflict;
+
+  if (conflict->legacy_tree_conflict)
+    return conflict->legacy_tree_conflict;
+
+  if (conflict->legacy_prop_conflict)
+    return conflict->legacy_prop_conflict;
+
+  return NULL;
+}
+
+svn_wc_conflict_kind_t
+svn_client_conflict_get_kind(const svn_client_conflict_t *conflict)
+{
+  return get_conflict_desc2_t(conflict)->kind;
+}
+
+svn_error_t *
+svn_client_conflict_get_conflicted(svn_boolean_t *text_conflicted,
+                                   apr_array_header_t **props_conflicted,
+                                   svn_boolean_t *tree_conflicted,
+                                   svn_client_conflict_t *conflict,
+                                   apr_pool_t *result_pool,
+                                   apr_pool_t *scratch_pool)
+{
+  if (text_conflicted)
+    *text_conflicted = (conflict->legacy_text_conflict != NULL);
+
+  if (props_conflicted)
+    {
+      if (conflict->legacy_prop_conflict)
+        {
+          *props_conflicted = apr_array_make(result_pool, 1,
+                                             sizeof(const char*));
+          APR_ARRAY_PUSH((*props_conflicted), const char *) =
+            conflict->legacy_prop_conflict->property_name;
+        }
+      else
+        SVN_ERR(svn_hash_keys(props_conflicted, conflict->prop_conflicts,
+                              result_pool));
+    }
+
+  if (tree_conflicted)
+    *tree_conflicted = (conflict->legacy_tree_conflict != NULL);
+
+  return SVN_NO_ERROR;
+}
+
 const char *
-svn_client_conflict_get_local_abspath(
-  const svn_wc_conflict_description2_t *conflict)
+svn_client_conflict_get_local_abspath(const svn_client_conflict_t *conflict)
 {
   return conflict->local_abspath;
 }
 
 svn_wc_operation_t
-svn_client_conflict_get_operation(
-  const svn_wc_conflict_description2_t *conflict)
+svn_client_conflict_get_operation(const svn_client_conflict_t *conflict)
 {
-  return conflict->operation;
+  return get_conflict_desc2_t(conflict)->operation;
 }
 
 svn_wc_conflict_action_t
-svn_client_conflict_get_incoming_change(
-  const svn_wc_conflict_description2_t *conflict)
+svn_client_conflict_get_incoming_change(const svn_client_conflict_t *conflict)
 {
-  return conflict->action;
+  return get_conflict_desc2_t(conflict)->action;
 }
 
 svn_wc_conflict_reason_t
-svn_client_conflict_get_local_change(
-  const svn_wc_conflict_description2_t *conflict)
+svn_client_conflict_get_local_change(const svn_client_conflict_t *conflict)
+{
+  return get_conflict_desc2_t(conflict)->reason;
+}
+
+svn_error_t *
+svn_client_conflict_get_repos_info(const char **repos_root_url,
+                                   const char **repos_uuid,
+                                   const svn_client_conflict_t *conflict,
+                                   apr_pool_t *result_pool,
+                                   apr_pool_t *scratch_pool)
+{
+  if (repos_root_url)
+    {
+      if (get_conflict_desc2_t(conflict)->src_left_version)
+        *repos_root_url =
+          get_conflict_desc2_t(conflict)->src_left_version->repos_url;
+      else if (get_conflict_desc2_t(conflict)->src_right_version)
+        *repos_root_url =
+          get_conflict_desc2_t(conflict)->src_right_version->repos_url;
+      else
+        *repos_root_url = NULL;
+    }
+
+  if (repos_uuid)
+    {
+      if (get_conflict_desc2_t(conflict)->src_left_version)
+        *repos_uuid =
+          get_conflict_desc2_t(conflict)->src_left_version->repos_uuid;
+      else if (get_conflict_desc2_t(conflict)->src_right_version)
+        *repos_uuid =
+          get_conflict_desc2_t(conflict)->src_right_version->repos_uuid;
+      else
+        *repos_uuid = NULL;
+    }
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_conflict_get_incoming_old_repos_location(
+  const char **incoming_old_repos_relpath,
+  svn_revnum_t *incoming_old_pegrev,
+  svn_node_kind_t *incoming_old_node_kind,
+  const svn_client_conflict_t *conflict,
+  apr_pool_t *result_pool,
+  apr_pool_t *scratch_pool)
+{
+  if (incoming_old_repos_relpath)
+    {
+      if (get_conflict_desc2_t(conflict)->src_left_version)
+        *incoming_old_repos_relpath =
+          get_conflict_desc2_t(conflict)->src_left_version->path_in_repos;
+      else
+        *incoming_old_repos_relpath = NULL;
+    }
+
+  if (incoming_old_pegrev)
+    {
+      if (get_conflict_desc2_t(conflict)->src_left_version)
+        *incoming_old_pegrev =
+          get_conflict_desc2_t(conflict)->src_left_version->peg_rev;
+      else
+        *incoming_old_pegrev = SVN_INVALID_REVNUM;
+    }
+
+  if (incoming_old_node_kind)
+    {
+      if (get_conflict_desc2_t(conflict)->src_left_version)
+        *incoming_old_node_kind =
+          get_conflict_desc2_t(conflict)->src_left_version->node_kind;
+      else
+        *incoming_old_node_kind = svn_node_none;
+    }
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_conflict_get_incoming_new_repos_location(
+  const char **incoming_new_repos_relpath,
+  svn_revnum_t *incoming_new_pegrev,
+  svn_node_kind_t *incoming_new_node_kind,
+  const svn_client_conflict_t *conflict,
+  apr_pool_t *result_pool,
+  apr_pool_t *scratch_pool)
 {
-  return conflict->reason;
+  if (incoming_new_repos_relpath)
+    {
+      if (get_conflict_desc2_t(conflict)->src_right_version)
+        *incoming_new_repos_relpath =
+          get_conflict_desc2_t(conflict)->src_right_version->path_in_repos;
+      else
+        *incoming_new_repos_relpath = NULL;
+    }
+
+  if (incoming_new_pegrev)
+    {
+      if (get_conflict_desc2_t(conflict)->src_right_version)
+        *incoming_new_pegrev =
+          get_conflict_desc2_t(conflict)->src_right_version->peg_rev;
+      else
+        *incoming_new_pegrev = SVN_INVALID_REVNUM;
+    }
+
+  if (incoming_new_node_kind)
+    {
+      if (get_conflict_desc2_t(conflict)->src_right_version)
+        *incoming_new_node_kind =
+          get_conflict_desc2_t(conflict)->src_right_version->node_kind;
+      else
+        *incoming_new_node_kind = svn_node_none;
+    }
+
+  return SVN_NO_ERROR;
+}
+
+svn_node_kind_t
+svn_client_conflict_tree_get_victim_node_kind(
+  const svn_client_conflict_t *conflict)
+{
+  SVN_ERR_ASSERT_NO_RETURN(svn_client_conflict_get_kind(conflict)
+      == svn_wc_conflict_kind_tree);
+
+  return get_conflict_desc2_t(conflict)->node_kind;
+}
+
+const char *
+svn_client_conflict_prop_get_propname(const svn_client_conflict_t *conflict)
+{
+  SVN_ERR_ASSERT_NO_RETURN(svn_client_conflict_get_kind(conflict)
+      == svn_wc_conflict_kind_property);
+
+  return get_conflict_desc2_t(conflict)->property_name;
+}
+
+svn_error_t *
+svn_client_conflict_prop_get_propvals(const svn_string_t **base_propval,
+                                      const svn_string_t **working_propval,
+                                      const svn_string_t 
**incoming_old_propval,
+                                      const svn_string_t 
**incoming_new_propval,
+                                      const svn_client_conflict_t *conflict,
+  apr_pool_t *result_pool)
+{
+  SVN_ERR_ASSERT(svn_client_conflict_get_kind(conflict) ==
+                 svn_wc_conflict_kind_property);
+
+  if (base_propval)
+    *base_propval =
+      svn_string_dup(get_conflict_desc2_t(conflict)->prop_value_base,
+                     result_pool);
+
+  if (working_propval)
+    *working_propval =
+      svn_string_dup(get_conflict_desc2_t(conflict)->prop_value_working,
+                     result_pool);
+
+  if (incoming_old_propval)
+    *incoming_old_propval =
+      svn_string_dup(get_conflict_desc2_t(conflict)->prop_value_incoming_old,
+                     result_pool);
+
+  if (incoming_new_propval)
+    *incoming_new_propval =
+      svn_string_dup(get_conflict_desc2_t(conflict)->prop_value_incoming_new,
+                     result_pool);
+
+  return SVN_NO_ERROR;
+}
+
+const char *
+svn_client_conflict_prop_get_reject_abspath(
+  const svn_client_conflict_t *conflict)
+{
+  SVN_ERR_ASSERT_NO_RETURN(svn_client_conflict_get_kind(conflict)
+      == svn_wc_conflict_kind_property);
+
+  /* svn_wc_conflict_description2_t stores this path in 'their_abspath' */
+  return get_conflict_desc2_t(conflict)->their_abspath;
+}
+
+const char *
+svn_client_conflict_text_get_mime_type(const svn_client_conflict_t *conflict)
+{
+  SVN_ERR_ASSERT_NO_RETURN(svn_client_conflict_get_kind(conflict)
+      == svn_wc_conflict_kind_text);
+
+  return get_conflict_desc2_t(conflict)->mime_type;
+}
+
+svn_error_t *
+svn_client_conflict_text_get_contents(const char **base_abspath,
+                                      const char **working_abspath,
+                                      const char **incoming_old_abspath,
+                                      const char **incoming_new_abspath,
+                                      const svn_client_conflict_t *conflict,
+                                      apr_pool_t *result_pool,
+                                      apr_pool_t *scratch_pool)
+{
+  SVN_ERR_ASSERT(svn_client_conflict_get_kind(conflict)
+      == svn_wc_conflict_kind_text);
+
+  if (base_abspath)
+    {
+      if (svn_client_conflict_get_operation(conflict) ==
+          svn_wc_operation_merge)
+        *base_abspath = NULL; /* ### WC base contents not available yet */
+      else /* update/switch */
+        *base_abspath = get_conflict_desc2_t(conflict)->base_abspath;
+    }
+
+  if (working_abspath)
+    *working_abspath = get_conflict_desc2_t(conflict)->my_abspath;
+
+  if (incoming_old_abspath)
+    *incoming_old_abspath = get_conflict_desc2_t(conflict)->base_abspath;
+
+  if (incoming_new_abspath)
+    *incoming_new_abspath = get_conflict_desc2_t(conflict)->their_abspath;
+
+  return SVN_NO_ERROR;
 }

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.c?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.c Mon Jun 29 
13:42:10 2015
@@ -134,6 +134,18 @@ fs_serialized_init(svn_fs_t *fs, apr_poo
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_fs_fs__initialize_shared_data(svn_fs_t *fs,
+                                  svn_mutex__t *common_pool_lock,
+                                  apr_pool_t *pool,
+                                  apr_pool_t *common_pool)
+{
+  SVN_MUTEX__WITH_LOCK(common_pool_lock,
+                       fs_serialized_init(fs, common_pool, pool));
+
+  return SVN_NO_ERROR;
+}
+
 
 
 /* This function is provided for Subversion 1.0.x compatibility.  It
@@ -480,28 +492,19 @@ fs_hotcopy(svn_fs_t *src_fs,
            apr_pool_t *pool,
            apr_pool_t *common_pool)
 {
-  /* Open the source repo as usual. */
   SVN_ERR(fs_open(src_fs, src_path, common_pool_lock, pool, common_pool));
-  if (cancel_func)
-    SVN_ERR(cancel_func(cancel_baton));
 
-  /* Test target repo when in INCREMENTAL mode, initialize it when not.
-   * For this, we need our FS internal data structures to be temporarily
-   * available. */
+  SVN_ERR(svn_fs__check_fs(dst_fs, FALSE));
   SVN_ERR(initialize_fs_struct(dst_fs));
-  SVN_ERR(svn_fs_fs__hotcopy_prepare_target(src_fs, dst_fs, dst_path,
-                                            incremental, pool));
-  uninitialize_fs_struct(dst_fs);
-
-  /* Now, the destination repo should open just fine. */
-  SVN_ERR(fs_open(dst_fs, dst_path, common_pool_lock, pool, common_pool));
-  if (cancel_func)
-    SVN_ERR(cancel_func(cancel_baton));
-
-  /* Now, we may copy data as needed ... */
-  return svn_fs_fs__hotcopy(src_fs, dst_fs, incremental,
-                            notify_func, notify_baton,
-                            cancel_func, cancel_baton, pool);
+
+  /* In INCREMENTAL mode, svn_fs_fs__hotcopy() will open DST_FS.
+     Otherwise, it's not an FS yet --- possibly just an empty dir --- so
+     can't be opened.
+   */
+  return svn_fs_fs__hotcopy(src_fs, dst_fs, src_path, dst_path,
+                            incremental, notify_func, notify_baton,
+                            cancel_func, cancel_baton, common_pool_lock,
+                            pool, common_pool);
 }
 
 

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.h?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.h Mon Jun 29 
13:42:10 2015
@@ -82,8 +82,6 @@ extern "C" {
 /* Names of special files and file extensions for transactions */
 #define PATH_CHANGES       "changes"       /* Records changes made so far */
 #define PATH_TXN_PROPS     "props"         /* Transaction properties */
-#define PATH_TXN_PROPS_FINAL "props-final" /* Final transaction properties
-                                              before moving to revprops */
 #define PATH_NEXT_IDS      "next-ids"      /* Next temporary ID assignments */
 #define PATH_PREFIX_NODE   "node."         /* Prefix for node filename */
 #define PATH_EXT_TXN       ".txn"          /* Extension of txn dir */

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.c?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.c 
(original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.c Mon Jun 
29 13:42:10 2015
@@ -415,75 +415,6 @@ svn_fs_fs__with_all_locks(svn_fs_t *fs,
   return svn_error_trace(with_lock(lock_baton, pool));
 }
 
-/* Set *READ_ONLY to TRUE, if the (lock) file at PATH is read-only.
-   Should that file not exist, try to create an empty one at PATH.
-   If that fails due to insufficient access rights, set *READ_ONLY
-   to TRUE as well.  Use SCRATCH_POOL for temporary allocations.
- */
-static svn_error_t *
-is_read_only(svn_boolean_t *read_only,
-             const char *path,
-             apr_pool_t *scratch_pool)
-{
-  apr_finfo_t finfo;
-
-  svn_error_t *err
-    = svn_io_stat(&finfo, path, SVN__APR_FINFO_READONLY, scratch_pool);
-  if (err && APR_STATUS_IS_ENOENT(err->apr_err))
-    {
-      /* No lock file?  Try to create one.
-         If that is not allowed, the repo can't be written to.
-         Report it as r/o in that case. */
-      svn_error_clear(err);
-
-      /* This file creation is racy (see further below). */
-      err = svn_io_file_create_empty(path, scratch_pool);
-      if (err && APR_STATUS_IS_EACCES(err->apr_err))
-        {
-          /* File creation is not allowed. */
-          svn_error_clear(err);
-          *read_only = TRUE;
-          return SVN_NO_ERROR;
-        }
-
-      /* Don't leak ... */
-      svn_error_clear(err);
-
-      /* At this point, there should either be a file or something pretty
-         bad happened.  In the latter case, this will fail with some error. */
-      SVN_ERR(svn_io_stat(&finfo, path, SVN__APR_FINFO_READONLY,
-                          scratch_pool));
-    }
-
-  SVN_ERR(svn_io__is_finfo_read_only(read_only, &finfo, scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_fs_fs__is_read_only(svn_boolean_t *read_only,
-                        svn_fs_t *fs,
-                        apr_pool_t *scratch_pool)
-{
-  fs_fs_data_t *ffd = fs->fsap_data;
-
-  *read_only = FALSE;
-  SVN_ERR(is_read_only(read_only,
-                       svn_fs_fs__path_lock(fs, scratch_pool),
-                       scratch_pool));
-
-  if (ffd->format >= SVN_FS_FS__MIN_TXN_CURRENT_FORMAT && !*read_only)
-    SVN_ERR(is_read_only(read_only,
-                         svn_fs_fs__path_txn_current_lock(fs, scratch_pool),
-                         scratch_pool));
-
-  if (ffd->format >= SVN_FS_FS__MIN_PACK_LOCK_FORMAT && !*read_only)
-    SVN_ERR(is_read_only(read_only,
-                         svn_fs_fs__path_pack_lock(fs, scratch_pool),
-                         scratch_pool));
-
-  return SVN_NO_ERROR;
-}
 
 
 

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.h?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.h 
(original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.h Mon Jun 
29 13:42:10 2015
@@ -39,6 +39,15 @@ svn_error_t *svn_fs_fs__open(svn_fs_t *f
                              const char *path,
                              apr_pool_t *pool);
 
+/* Initialize parts of the FS data that are being shared across multiple
+   filesystem objects.  Use COMMON_POOL for process-wide and POOL for
+   temporary allocations.  Use COMMON_POOL_LOCK to ensure that the
+   initialization is serialized. */
+svn_error_t *svn_fs_fs__initialize_shared_data(svn_fs_t *fs,
+                                               svn_mutex__t *common_pool_lock,
+                                               apr_pool_t *pool,
+                                               apr_pool_t *common_pool);
+
 /* Upgrade the fsfs filesystem FS.  Indicate progress via the optional
  * NOTIFY_FUNC callback using NOTIFY_BATON.  The optional CANCEL_FUNC
  * will periodically be called with CANCEL_BATON to allow for preemption.
@@ -215,21 +224,6 @@ svn_fs_fs__with_all_locks(svn_fs_t *fs,
                           void *baton,
                           apr_pool_t *pool);
 
-/* Set *READ_ONLY to TRUE, if we can't write to FS (create txns, commit or
-   pack).  If *READ_ONLY is FALSE, we expect that the on-disk permissions
-   allow for any write operation.
-
-   Note that we check the access rights for the current user and that a
-   read-only repository may still be writable for other users.
-
-   Furthermore, we expect OS access rights to be set consistently on all
-   files and folders.  Therefore, *READ_ONLY==FALSE is no guarantee that
-   a write will actually succeed. */
-svn_error_t *
-svn_fs_fs__is_read_only(svn_boolean_t *read_only,
-                        svn_fs_t *fs,
-                        apr_pool_t *scratch_pool);
-
 /* Find the value of the property named PROPNAME in transaction TXN.
    Return the contents in *VALUE_P.  The contents will be allocated
    from POOL. */

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/hotcopy.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/hotcopy.c?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/hotcopy.c 
(original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/hotcopy.c Mon 
Jun 29 13:42:10 2015
@@ -982,6 +982,10 @@ hotcopy_body(void *baton, apr_pool_t *po
       if (kind == svn_node_file)
         {
           SVN_ERR(svn_sqlite__hotcopy(src_subdir, dst_subdir, pool));
+
+          /* The source might have r/o flags set on it - which would be
+             carried over to the copy. */
+          SVN_ERR(svn_io_set_file_read_write(dst_subdir, FALSE, pool));
           SVN_ERR(svn_fs_fs__del_rep_reference(dst_fs, src_youngest, pool));
         }
     }
@@ -991,76 +995,33 @@ hotcopy_body(void *baton, apr_pool_t *po
     SVN_ERR(svn_io_dir_file_copy(src_fs->path, dst_fs->path,
                                  PATH_TXN_CURRENT, pool));
 
-  return SVN_NO_ERROR;
-}
-
-/* Wrapper around hotcopy_body taking out all necessary source repository
- * locks.
- */
-static svn_error_t *
-hotcopy_locking_src_body(void *baton, apr_pool_t *pool)
-{
-  struct hotcopy_body_baton *hbb = baton;
-  fs_fs_data_t *src_ffd = hbb->src_fs->fsap_data;
-
-  /* Hotcopying while packing is racy and can lead to hotcopy failure.
-     Therefore, we try to block packing while we are copying data. */
-  if (src_ffd->format >= SVN_FS_FS__MIN_PACK_LOCK_FORMAT)
-    {
-      svn_boolean_t read_only;
-      SVN_ERR(svn_fs_fs__is_read_only(&read_only, hbb->src_fs, pool));
-      if (!read_only)
-        return svn_error_trace(svn_fs_fs__with_pack_lock(hbb->src_fs,
-                                                         hotcopy_body,
-                                                         baton, pool));
-    }
+  /* Hotcopied FS is complete. Stamp it with a format file. */
+  SVN_ERR(svn_fs_fs__write_format(dst_fs, TRUE, pool));
 
-  /* Fall-back code: Just copy. This may fail with ENOENT if the source
-     repo is being packed at the same time. */
-  return svn_error_trace(hotcopy_body(baton, pool));
+  return SVN_NO_ERROR;
 }
 
-/* Create an empty filesystem at DST_FS at DST_PATH with the same
- * configuration as SRC_FS (uuid, format, and other parameters).
- * After creation DST_FS has no revisions, not even revision zero. */
-static svn_error_t *
-hotcopy_create_empty_dest(svn_fs_t *src_fs,
-                          svn_fs_t *dst_fs,
-                          const char *dst_path,
-                          apr_pool_t *pool)
+svn_error_t *
+svn_fs_fs__hotcopy(svn_fs_t *src_fs,
+                   svn_fs_t *dst_fs,
+                   const char *src_path,
+                   const char *dst_path,
+                   svn_boolean_t incremental,
+                   svn_fs_hotcopy_notify_t notify_func,
+                   void *notify_baton,
+                   svn_cancel_func_t cancel_func,
+                   void *cancel_baton,
+                   svn_mutex__t *common_pool_lock,
+                   apr_pool_t *pool,
+                   apr_pool_t *common_pool)
 {
-  fs_fs_data_t *src_ffd = src_fs->fsap_data;
+  struct hotcopy_body_baton hbb;
 
-  /* Create the DST_FS repository with the same layout as SRC_FS. */
-  SVN_ERR(svn_fs_fs__create_file_tree(dst_fs, dst_path, src_ffd->format,
-                                      src_ffd->max_files_per_dir,
-                                      src_ffd->use_log_addressing,
-                                      pool));
-
-  /* Copy the UUID.  Hotcopy destination receives a new instance ID, but
-   * has the same filesystem UUID as the source. */
-  SVN_ERR(svn_fs_fs__set_uuid(dst_fs, src_fs->uuid, NULL, pool));
-
-  /* Remove revision 0 contents.  Otherwise, it may not get overwritten
-   * due to having a newer timestamp. */
-  SVN_ERR(hotcopy_remove_file(svn_fs_fs__path_rev(dst_fs, 0, pool), pool));
-  SVN_ERR(hotcopy_remove_file(svn_fs_fs__path_revprops(dst_fs, 0, pool),
-                              pool));
-
-  /* This filesystem is ready.  Stamp it with a format number.  Fail if
-   * the 'format' file should already exist. */
-  SVN_ERR(svn_fs_fs__write_format(dst_fs, FALSE, pool));
+  if (cancel_func)
+    SVN_ERR(cancel_func(cancel_baton));
 
-  return SVN_NO_ERROR;
-}
+  SVN_ERR(svn_fs_fs__open(src_fs, src_path, pool));
 
-svn_error_t *
-svn_fs_fs__hotcopy_prepare_target(svn_fs_t *src_fs,
-                                  svn_fs_t *dst_fs,
-                                  const char *dst_path,
-                                  svn_boolean_t incremental,
-                                  apr_pool_t *pool)
-{
   if (incremental)
     {
       const char *dst_format_abspath;
@@ -1072,39 +1033,51 @@ svn_fs_fs__hotcopy_prepare_target(svn_fs
       SVN_ERR(svn_io_check_path(dst_format_abspath, &dst_format_kind, pool));
       if (dst_format_kind == svn_node_none)
         {
-          /* Destination doesn't exist yet. Perform a normal hotcopy to a
-           * empty destination using the same configuration as the source. */
-          SVN_ERR(hotcopy_create_empty_dest(src_fs, dst_fs, dst_path, pool));
-        }
-      else
-        {
-          /* Check the existing repository. */
-          SVN_ERR(svn_fs_fs__open(dst_fs, dst_path, pool));
-          SVN_ERR(hotcopy_incremental_check_preconditions(src_fs, dst_fs,
-                                                          pool));
+          /* No destination?  Fallback to a non-incremental hotcopy. */
+          incremental = FALSE;
         }
     }
+
+  if (incremental)
+    {
+      /* Check the existing repository. */
+      SVN_ERR(svn_fs_fs__open(dst_fs, dst_path, pool));
+      SVN_ERR(hotcopy_incremental_check_preconditions(src_fs, dst_fs, pool));
+
+      SVN_ERR(svn_fs_fs__initialize_shared_data(dst_fs, common_pool_lock,
+                                                pool, common_pool));
+      SVN_ERR(svn_fs_fs__initialize_caches(dst_fs, pool));
+    }
   else
     {
       /* Start out with an empty destination using the same configuration
        * as the source. */
-      SVN_ERR(hotcopy_create_empty_dest(src_fs, dst_fs, dst_path, pool));
-    }
+      fs_fs_data_t *src_ffd = src_fs->fsap_data;
 
-  return SVN_NO_ERROR;
-}
+      /* Create the DST_FS repository with the same layout as SRC_FS. */
+      SVN_ERR(svn_fs_fs__create_file_tree(dst_fs, dst_path, src_ffd->format,
+                                          src_ffd->max_files_per_dir,
+                                          src_ffd->use_log_addressing,
+                                          pool));
+
+      /* Copy the UUID.  Hotcopy destination receives a new instance ID, but
+       * has the same filesystem UUID as the source. */
+      SVN_ERR(svn_fs_fs__set_uuid(dst_fs, src_fs->uuid, NULL, pool));
+
+      /* Remove revision 0 contents.  Otherwise, it may not get overwritten
+       * due to having a newer timestamp. */
+      SVN_ERR(hotcopy_remove_file(svn_fs_fs__path_rev(dst_fs, 0, pool),
+                                  pool));
+      SVN_ERR(hotcopy_remove_file(svn_fs_fs__path_revprops(dst_fs, 0, pool),
+                                  pool));
+
+      SVN_ERR(svn_fs_fs__initialize_shared_data(dst_fs, common_pool_lock,
+                                                pool, common_pool));
+      SVN_ERR(svn_fs_fs__initialize_caches(dst_fs, pool));
+    }
 
-svn_error_t *
-svn_fs_fs__hotcopy(svn_fs_t *src_fs,
-                   svn_fs_t *dst_fs,
-                   svn_boolean_t incremental,
-                   svn_fs_hotcopy_notify_t notify_func,
-                   void *notify_baton,
-                   svn_cancel_func_t cancel_func,
-                   void *cancel_baton,
-                   apr_pool_t *pool)
-{
-  struct hotcopy_body_baton hbb;
+  if (cancel_func)
+    SVN_ERR(cancel_func(cancel_baton));
 
   hbb.src_fs = src_fs;
   hbb.dst_fs = dst_fs;
@@ -1113,8 +1086,15 @@ svn_fs_fs__hotcopy(svn_fs_t *src_fs,
   hbb.notify_baton = notify_baton;
   hbb.cancel_func = cancel_func;
   hbb.cancel_baton = cancel_baton;
-  SVN_ERR(svn_fs_fs__with_all_locks(dst_fs, hotcopy_locking_src_body, &hbb,
-                                    pool));
+
+  /* Lock the destination in the incremental mode.  For a non-incremental
+   * hotcopy, don't take any locks.  In that case the destination cannot be
+   * opened until the hotcopy finishes, and we don't have to worry about
+   * concurrency. */
+  if (incremental)
+    SVN_ERR(svn_fs_fs__with_all_locks(dst_fs, hotcopy_body, &hbb, pool));
+  else
+    SVN_ERR(hotcopy_body(&hbb, pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/hotcopy.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/hotcopy.h?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/hotcopy.h 
(original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/hotcopy.h Mon 
Jun 29 13:42:10 2015
@@ -25,27 +25,23 @@
 
 #include "fs.h"
 
-/* Create an empty copy of the fsfs filesystem SRC_FS into a new DST_FS at
- * DST_PATH.  If INCREMENTAL is TRUE, perform a few pre-checks only if
- * a repo already exists at DST_PATH. Use POOL for temporary allocations. */
-svn_error_t *
-svn_fs_fs__hotcopy_prepare_target(svn_fs_t *src_fs,
-                                  svn_fs_t *dst_fs,
-                                  const char *dst_path,
-                                  svn_boolean_t incremental,
-                                  apr_pool_t *pool);
-
-/* Copy the fsfs filesystem SRC_FS into DST_FS. If INCREMENTAL is TRUE, do
- * not re-copy data which already exists in DST_FS.  Indicate progress via
- * the optional NOTIFY_FUNC callback using NOTIFY_BATON.  Use POOL for
- * temporary allocations. */
+/* Copy the fsfs filesystem SRC_FS at SRC_PATH into a new copy DST_FS at
+ * DST_PATH.  If INCREMENTAL is TRUE, do not re-copy data which already
+ * exists in DST_FS.  Indicate progress via the optional NOTIFY_FUNC
+ * callback using NOTIFY_BATON.  Use COMMON_POOL for process-wide and
+ * POOL for temporary allocations.  Use COMMON_POOL_LOCK to ensure
+ * that the initialization of the shared data is serialized. */
 svn_error_t * svn_fs_fs__hotcopy(svn_fs_t *src_fs,
                                  svn_fs_t *dst_fs,
+                                 const char *src_path,
+                                 const char *dst_path,
                                  svn_boolean_t incremental,
                                  svn_fs_hotcopy_notify_t notify_func,
                                  void *notify_baton,
                                  svn_cancel_func_t cancel_func,
                                  void *cancel_baton,
-                                 apr_pool_t *pool);
+                                 svn_mutex__t *common_pool_lock,
+                                 apr_pool_t *pool,
+                                 apr_pool_t *common_pool);
 
 #endif


Reply via email to