subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From julianf...@apache.org
Subject svn commit: r1688213 [2/3] - in /subversion/branches/move-tracking-2: ./ build/ build/ac-macros/ subversion/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversion/include/ subversion/include/private/...
Date Mon, 29 Jun 2015 13:42:12 GMT
Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/pack.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/pack.c?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/pack.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/pack.c Mon Jun 29 13:42:10 2015
@@ -1931,6 +1931,34 @@ pack_shard(struct pack_baton *baton,
   return SVN_NO_ERROR;
 }
 
+/* Read the youngest rev and the first non-packed rev info for FS from disk.
+   Set *FULLY_PACKED when there is no completed unpacked shard.
+   Use SCRATCH_POOL for temporary allocations.
+ */
+static svn_error_t *
+get_pack_status(svn_boolean_t *fully_packed,
+                svn_fs_t *fs,
+                apr_pool_t *scratch_pool)
+{
+  fs_fs_data_t *ffd = fs->fsap_data;
+  apr_int64_t completed_shards;
+  svn_revnum_t youngest;
+
+  SVN_ERR(svn_fs_fs__read_min_unpacked_rev(&ffd->min_unpacked_rev, fs,
+                                           scratch_pool));
+
+  SVN_ERR(svn_fs_fs__youngest_rev(&youngest, fs, scratch_pool));
+  completed_shards = (youngest + 1) / ffd->max_files_per_dir;
+
+  /* See if we've already completed all possible shards thus far. */
+  if (ffd->min_unpacked_rev == (completed_shards * ffd->max_files_per_dir))
+    *fully_packed = TRUE;
+  else
+    *fully_packed = FALSE;
+
+  return SVN_NO_ERROR;
+}
+
 /* The work-horse for svn_fs_fs__pack, called with the FS write lock.
    This implements the svn_fs_fs__with_write_lock() 'body' callback
    type.  BATON is a 'struct pack_baton *'.
@@ -1952,30 +1980,16 @@ pack_body(void *baton,
   struct pack_baton *pb = baton;
   fs_fs_data_t *ffd = pb->fs->fsap_data;
   apr_int64_t completed_shards;
-  svn_revnum_t youngest;
   apr_pool_t *iterpool;
+  svn_boolean_t fully_packed;
 
-  /* If the repository isn't a new enough format, we don't support packing.
-     Return a friendly error to that effect. */
-  if (ffd->format < SVN_FS_FS__MIN_PACKED_FORMAT)
-    return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
-      _("FSFS format (%d) too old to pack; please upgrade the filesystem."),
-      ffd->format);
-
-  /* If we aren't using sharding, we can't do any packing, so quit. */
-  if (!ffd->max_files_per_dir)
-    return SVN_NO_ERROR;
-
-  SVN_ERR(svn_fs_fs__read_min_unpacked_rev(&ffd->min_unpacked_rev, pb->fs,
-                                           pool));
-
-  SVN_ERR(svn_fs_fs__youngest_rev(&youngest, pb->fs, pool));
-  completed_shards = (youngest + 1) / ffd->max_files_per_dir;
-
-  /* See if we've already completed all possible shards thus far. */
-  if (ffd->min_unpacked_rev == (completed_shards * ffd->max_files_per_dir))
+  /* Since another process might have already packed the repo,
+     we need to re-read the pack status. */
+  SVN_ERR(get_pack_status(&fully_packed, pb->fs, pool));
+  if (fully_packed)
     return SVN_NO_ERROR;
 
+  completed_shards = (ffd->youngest_rev_cache + 1) / ffd->max_files_per_dir;
   pb->revs_dir = svn_dirent_join(pb->fs->path, PATH_REVS_DIR, pool);
   if (ffd->format >= SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT)
     pb->revsprops_dir = svn_dirent_join(pb->fs->path, PATH_REVPROPS_DIR,
@@ -2009,7 +2023,25 @@ svn_fs_fs__pack(svn_fs_t *fs,
   struct pack_baton pb = { 0 };
   fs_fs_data_t *ffd = fs->fsap_data;
   svn_error_t *err;
+  svn_boolean_t fully_packed;
+
+  /* If the repository isn't a new enough format, we don't support packing.
+     Return a friendly error to that effect. */
+  if (ffd->format < SVN_FS_FS__MIN_PACKED_FORMAT)
+    return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+      _("FSFS format (%d) too old to pack; please upgrade the filesystem."),
+      ffd->format);
+
+  /* If we aren't using sharding, we can't do any packing, so quit. */
+  if (!ffd->max_files_per_dir)
+    return SVN_NO_ERROR;
+
+  /* Is there we even anything to do?. */
+  SVN_ERR(get_pack_status(&fully_packed, fs, pool));
+  if (fully_packed)
+    return SVN_NO_ERROR;
 
+  /* Lock the repo and start the pack process. */
   pb.fs = fs;
   pb.notify_func = notify_func;
   pb.notify_baton = notify_baton;

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/transaction.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/transaction.c?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/transaction.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/transaction.c Mon Jun 29 13:42:10 2015
@@ -89,15 +89,6 @@ path_txn_props(svn_fs_t *fs,
 }
 
 static APR_INLINE const char *
-path_txn_props_final(svn_fs_t *fs,
-                     const svn_fs_fs__id_part_t *txn_id,
-                     apr_pool_t *pool)
-{
-  return svn_dirent_join(svn_fs_fs__path_txn_dir(fs, txn_id, pool),
-                         PATH_TXN_PROPS_FINAL, pool);
-}
-
-static APR_INLINE const char *
 path_txn_next_ids(svn_fs_t *fs,
                   const svn_fs_fs__id_part_t *txn_id,
                   apr_pool_t *pool)
@@ -1160,7 +1151,6 @@ static svn_error_t *
 set_txn_proplist(svn_fs_t *fs,
                  const svn_fs_fs__id_part_t *txn_id,
                  apr_hash_t *props,
-                 svn_boolean_t final,
                  apr_pool_t *pool)
 {
   svn_stringbuf_t *buf;
@@ -1173,9 +1163,7 @@ set_txn_proplist(svn_fs_t *fs,
   SVN_ERR(svn_stream_close(stream));
 
   /* Open the transaction properties file and write new contents to it. */
-  SVN_ERR(svn_io_write_atomic((final
-                               ? path_txn_props_final(fs, txn_id, pool)
-                               : path_txn_props(fs, txn_id, pool)),
+  SVN_ERR(svn_io_write_atomic(path_txn_props(fs, txn_id, pool),
                               buf->data, buf->len,
                               NULL /* copy_perms_path */, pool));
   return SVN_NO_ERROR;
@@ -1232,7 +1220,7 @@ svn_fs_fs__change_txn_props(svn_fs_txn_t
 
   /* Create a new version of the file and write out the new props. */
   /* Open the transaction properties file. */
-  SVN_ERR(set_txn_proplist(txn->fs, &ftd->txn_id, txn_prop, FALSE, pool));
+  SVN_ERR(set_txn_proplist(txn->fs, &ftd->txn_id, txn_prop, pool));
 
   return SVN_NO_ERROR;
 }
@@ -3337,41 +3325,31 @@ verify_locks(svn_fs_t *fs,
   return SVN_NO_ERROR;
 }
 
-/* Return in *PATH the path to a file containing the properties that
-   make up the final revision properties file.  This involves setting
-   svn:date and removing any temporary properties associated with the
-   commit flags. */
+/* Writes final revision properties to file PATH applying permissions
+   from file PERMS_REFERENCE. This involves setting svn:date and
+   removing any temporary properties associated with the commit flags. */
 static svn_error_t *
-write_final_revprop(const char **path,
+write_final_revprop(const char *path,
+                    const char *perms_reference,
                     svn_fs_txn_t *txn,
-                    const svn_fs_fs__id_part_t *txn_id,
                     apr_pool_t *pool)
 {
   apr_hash_t *txnprops;
-  svn_boolean_t final_mods = FALSE;
   svn_string_t date;
   svn_string_t *client_date;
+  apr_file_t *revprop_file;
+  svn_stream_t *stream;
 
   SVN_ERR(svn_fs_fs__txn_proplist(&txnprops, txn, pool));
 
   /* Remove any temporary txn props representing 'flags'. */
-  if (svn_hash_gets(txnprops, SVN_FS__PROP_TXN_CHECK_OOD))
-    {
-      svn_hash_sets(txnprops, SVN_FS__PROP_TXN_CHECK_OOD, NULL);
-      final_mods = TRUE;
-    }
-
-  if (svn_hash_gets(txnprops, SVN_FS__PROP_TXN_CHECK_LOCKS))
-    {
-      svn_hash_sets(txnprops, SVN_FS__PROP_TXN_CHECK_LOCKS, NULL);
-      final_mods = TRUE;
-    }
+  svn_hash_sets(txnprops, SVN_FS__PROP_TXN_CHECK_OOD, NULL);
+  svn_hash_sets(txnprops, SVN_FS__PROP_TXN_CHECK_LOCKS, NULL);
 
   client_date = svn_hash_gets(txnprops, SVN_FS__PROP_TXN_CLIENT_DATE);
   if (client_date)
     {
       svn_hash_sets(txnprops, SVN_FS__PROP_TXN_CLIENT_DATE, NULL);
-      final_mods = TRUE;
     }
 
   /* Update commit time to ensure that svn:date revprops remain ordered if
@@ -3381,18 +3359,22 @@ write_final_revprop(const char **path,
       date.data = svn_time_to_cstring(apr_time_now(), pool);
       date.len = strlen(date.data);
       svn_hash_sets(txnprops, SVN_PROP_REVISION_DATE, &date);
-      final_mods = TRUE;
     }
 
-  if (final_mods)
-    {
-      SVN_ERR(set_txn_proplist(txn->fs, txn_id, txnprops, TRUE, pool));
-      *path = path_txn_props_final(txn->fs, txn_id, pool);
-    }
-  else
-    {
-      *path = path_txn_props(txn->fs, txn_id, pool);
-    }
+  /* Create new revprops file. Tell OS to truncate existing file,
+     since  file may already exists from failed transaction. */
+  SVN_ERR(svn_io_file_open(&revprop_file, path,
+                           APR_WRITE | APR_CREATE | APR_TRUNCATE
+                           | APR_BUFFERED, APR_OS_DEFAULT, pool));
+
+  stream = svn_stream_from_aprfile2(revprop_file, TRUE, pool);
+  SVN_ERR(svn_hash_write2(txnprops, stream, SVN_HASH_TERMINATOR, pool));
+  SVN_ERR(svn_stream_close(stream));
+
+  SVN_ERR(svn_io_file_flush_to_disk(revprop_file, pool));
+  SVN_ERR(svn_io_file_close(revprop_file, pool));
+
+  SVN_ERR(svn_io_copy_perms(perms_reference, path, pool));
 
   return SVN_NO_ERROR;
 }
@@ -3457,7 +3439,7 @@ commit_body(void *baton, apr_pool_t *poo
   struct commit_baton *cb = baton;
   fs_fs_data_t *ffd = cb->fs->fsap_data;
   const char *old_rev_filename, *rev_filename, *proto_filename;
-  const char *revprop_filename, *final_revprop;
+  const char *revprop_filename;
   const svn_fs_id_t *root_id, *new_root_id;
   apr_uint64_t start_node_id;
   apr_uint64_t start_copy_id;
@@ -3610,12 +3592,11 @@ commit_body(void *baton, apr_pool_t *poo
      remove the transaction directory later. */
   SVN_ERR(unlock_proto_rev(cb->fs, txn_id, proto_file_lockcookie, pool));
 
-  /* Move the revprops file into place. */
+  /* Write final revprops file. */
   SVN_ERR_ASSERT(! svn_fs_fs__is_packed_revprop(cb->fs, new_rev));
-  SVN_ERR(write_final_revprop(&revprop_filename, cb->txn, txn_id, pool));
-  final_revprop = svn_fs_fs__path_revprops(cb->fs, new_rev, pool);
-  SVN_ERR(svn_fs_fs__move_into_place(revprop_filename, final_revprop,
-                                     old_rev_filename, pool));
+  revprop_filename = svn_fs_fs__path_revprops(cb->fs, new_rev, pool);
+  SVN_ERR(write_final_revprop(revprop_filename, old_rev_filename,
+                              cb->txn, pool));
 
   /* Update the 'current' file. */
   SVN_ERR(verify_as_revision_before_current_plus_plus(cb->fs, new_rev, pool));
@@ -3919,6 +3900,5 @@ svn_fs_fs__begin_txn(svn_fs_txn_t **txn_
                   svn_string_create("0", pool));
 
   ftd = (*txn_p)->fsap_data;
-  return svn_error_trace(set_txn_proplist(fs, &ftd->txn_id, props, FALSE,
-                                          pool));
+  return svn_error_trace(set_txn_proplist(fs, &ftd->txn_id, props, pool));
 }

Modified: subversion/branches/move-tracking-2/subversion/libsvn_repos/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_repos/deprecated.c?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_repos/deprecated.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_repos/deprecated.c Mon Jun 29 13:42:10 2015
@@ -774,9 +774,9 @@ svn_repos_verify_fs2(svn_repos_t *repos,
                                               end_rev,
                                               FALSE,
                                               FALSE,
-                                              FALSE,
                                               notify_func,
                                               notify_baton,
+                                              NULL, NULL,
                                               cancel_func,
                                               cancel_baton,
                                               pool));

Modified: subversion/branches/move-tracking-2/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_repos/dump.c?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_repos/dump.c Mon Jun 29 13:42:10 2015
@@ -2265,24 +2265,6 @@ verify_close_directory(void *dir_baton,
   return close_directory(dir_baton, pool);
 }
 
-static void
-notify_verification_error(svn_revnum_t rev,
-                          svn_error_t *err,
-                          svn_repos_notify_func_t notify_func,
-                          void *notify_baton,
-                          apr_pool_t *pool)
-{
-  svn_repos_notify_t *notify_failure;
-
-  if (notify_func == NULL)
-    return;
-
-  notify_failure = svn_repos_notify_create(svn_repos_notify_failure, pool);
-  notify_failure->err = err;
-  notify_failure->revision = rev;
-  notify_func(notify_baton, notify_failure, pool);
-}
-
 /* Verify revision REV in file system FS. */
 static svn_error_t *
 verify_one_revision(svn_fs_t *fs,
@@ -2359,15 +2341,42 @@ verify_fs_notify_func(svn_revnum_t revis
                             notify_baton->notify, pool);
 }
 
+static svn_error_t *
+report_error(svn_revnum_t revision,
+             svn_error_t *verify_err,
+             svn_repos_verify_callback_t verify_callback,
+             void *verify_baton,
+             apr_pool_t *pool)
+{
+  if (verify_callback)
+    {
+      svn_error_t *cb_err;
+
+      /* The caller provided us with a callback, so make him responsible
+         for what's going to happen with the error. */
+      cb_err = verify_callback(verify_baton, revision, verify_err, pool);
+      svn_error_clear(verify_err);
+      SVN_ERR(cb_err);
+
+      return SVN_NO_ERROR;
+    }
+  else
+    {
+      /* No callback -- no second guessing.  Just return the error. */
+      return svn_error_trace(verify_err);
+    }
+}
+
 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_func,
                      void *cancel_baton,
                      apr_pool_t *pool)
@@ -2380,8 +2389,6 @@ svn_repos_verify_fs3(svn_repos_t *repos,
   svn_fs_progress_notify_func_t verify_notify = NULL;
   struct verify_fs_notify_func_baton_t *verify_notify_baton = NULL;
   svn_error_t *err;
-  svn_boolean_t failed_metadata = FALSE;
-  svn_revnum_t failed_revisions = 0;
 
   /* Determine the current youngest revision of the filesystem. */
   SVN_ERR(svn_fs_youngest_rev(&youngest, fs, pool));
@@ -2430,20 +2437,8 @@ svn_repos_verify_fs3(svn_repos_t *repos,
     }
   else if (err)
     {
-      notify_verification_error(SVN_INVALID_REVNUM, err, notify_func,
-                                notify_baton, iterpool);
-
-      if (!keep_going)
-        {
-          /* Return the error, the caller doesn't want us to continue. */
-          return svn_error_trace(err);
-        }
-      else
-        {
-          /* Clear the error and keep going. */
-          failed_metadata = TRUE;
-          svn_error_clear(err);
-        }
+      SVN_ERR(report_error(SVN_INVALID_REVNUM, err, verify_callback,
+                           verify_baton, iterpool));
     }
 
   if (!metadata_only)
@@ -2463,20 +2458,8 @@ svn_repos_verify_fs3(svn_repos_t *repos,
           }
         else if (err)
           {
-            notify_verification_error(rev, err, notify_func, notify_baton,
-                                      iterpool);
-
-            if (!keep_going)
-              {
-                /* Return the error, the caller doesn't want us to continue. */
-                return svn_error_trace(err);
-              }
-            else
-              {
-                /* Clear the error and keep going. */
-                ++failed_revisions;
-                svn_error_clear(err);
-              }
+            SVN_ERR(report_error(rev, err, verify_callback, verify_baton,
+                                 iterpool));
           }
         else if (notify_func)
           {
@@ -2495,40 +2478,5 @@ svn_repos_verify_fs3(svn_repos_t *repos,
 
   svn_pool_destroy(iterpool);
 
-  /* Summarize the results. */
-  if (failed_metadata || 0 != failed_revisions)
-    {
-      const char *const repos_path =
-        svn_dirent_local_style(svn_repos_path(repos, pool), pool);
-
-      if (0 == failed_revisions)
-        {
-          return svn_error_createf(
-              SVN_ERR_REPOS_VERIFY_FAILED, NULL,
-              _("Metadata verification failed on repository '%s'"),
-              repos_path);
-        }
-      else
-        {
-          const char* format_string;
-
-          if (failed_metadata)
-            format_string = apr_psprintf(
-                pool, _("Verification of metadata and"
-                        " %%%s out of %%%s revisions"
-                        " failed on repository '%%s'"),
-                SVN_REVNUM_T_FMT, SVN_REVNUM_T_FMT);
-          else
-            format_string = apr_psprintf(
-                pool, _("Verification of %%%s out of %%%s revisions"
-                        " failed on repository '%%s'"),
-                SVN_REVNUM_T_FMT, SVN_REVNUM_T_FMT);
-
-          return svn_error_createf(
-              SVN_ERR_REPOS_VERIFY_FAILED, NULL, format_string,
-              failed_revisions, end_rev - start_rev + 1, repos_path);
-        }
-    }
-
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/move-tracking-2/subversion/libsvn_repos/rev_hunt.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_repos/rev_hunt.c?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_repos/rev_hunt.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_repos/rev_hunt.c Mon Jun 29 13:42:10 2015
@@ -1336,6 +1336,7 @@ struct send_baton
   apr_hash_t *last_props;
   const char *last_path;
   svn_fs_root_t *last_root;
+  svn_boolean_t include_merged_revisions;
 };
 
 /* Send PATH_REV to HANDLER and HANDLER_BATON, using information provided by
@@ -1379,10 +1380,11 @@ send_path_revision(struct path_revision
       /* Special case: In the first revision, we always provide a delta. */
       contents_changed = TRUE;
     }
-  else if (strcmp(sb->last_path, path_rev->path))
+  else if (sb->include_merged_revisions
+           && strcmp(sb->last_path, path_rev->path))
     {
-      /* This is a HACK!!!
-       * Blame, in older clients anyways, relies on getting a notification
+      /* ### This is a HACK!!!
+       * Blame -g, in older clients anyways, relies on getting a notification
        * whenever the path changes - even if there was no content change.
        *
        * TODO: A future release should take an extra parameter and depending
@@ -1466,6 +1468,7 @@ get_file_revs_backwards(svn_repos_t *rep
   last_pool = svn_pool_create(scratch_pool);
   sb.iterpool = svn_pool_create(scratch_pool);
   sb.last_pool = svn_pool_create(scratch_pool);
+  sb.include_merged_revisions = FALSE;
 
   /* We want the first txdelta to be against the empty file. */
   sb.last_root = NULL;
@@ -1621,6 +1624,9 @@ svn_repos_get_file_revs2(svn_repos_t *re
   /* Create an empty hash table for the first property diff. */
   sb.last_props = apr_hash_make(sb.last_pool);
 
+  /* Inform send_path_revision() whether workarounds / special behavior
+   * may be needed. */
+  sb.include_merged_revisions = include_merged_revisions;
 
   /* Get the revisions we are interested in. */
   duplicate_path_revs = apr_hash_make(scratch_pool);

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/cache-membuffer.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/cache-membuffer.c?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/cache-membuffer.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/cache-membuffer.c Mon Jun 29 13:42:10 2015
@@ -2233,7 +2233,7 @@ membuffer_cache_get_internal(svn_membuff
 
 /* Look for the *ITEM identified by KEY. If no item has been stored
  * for KEY, *ITEM will be NULL. Otherwise, the DESERIALIZER is called
- * re-construct the proper object from the serialized data.
+ * to re-construct the proper object from the serialized data.
  * Allocations will be done in POOL.
  */
 static svn_error_t *

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/config.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/config.c?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/config.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/config.c Mon Jun 29 13:42:10 2015
@@ -55,6 +55,27 @@ struct cfg_section_t
 };
 
 
+/* States that a config option value can assume. */
+typedef enum option_state_t
+{
+  /* Value still needs to be expanded.
+     This is the initial state for *all* values. */
+  option_state_needs_expanding,
+
+  /* Value is currently being expanded.
+     This transitional state allows for detecting cyclic dependencies. */
+  option_state_expanding,
+
+  /* Expanded value is available.
+     Values that never needed expanding directly go into that state
+     skipping option_state_expanding. */
+  option_state_expanded,
+
+  /* The value expansion is cyclic which results in "undefined" behavior.
+     This is to return a defined value ("") in that case. */
+  option_state_cyclic
+} option_state_t;
+
 /* Option table entries. */
 typedef struct cfg_option_t cfg_option_t;
 struct cfg_option_t
@@ -71,10 +92,10 @@ struct cfg_option_t
   /* The expanded option value. */
   const char *x_value;
 
-  /* Expansion flag. If this is TRUE, this value has already been expanded.
-     In this case, if x_value is NULL, no expansions were necessary,
-     and value should be used directly. */
-  svn_boolean_t expanded;
+  /* Expansion state. If this is option_state_expanded, VALUE has already
+     been expanded.  In this case, if x_value is NULL, no expansions were
+     necessary, and value should be used directly. */
+  option_state_t state;
 };
 
 
@@ -396,12 +417,13 @@ svn_config_merge(svn_config_t *cfg, cons
 static svn_boolean_t
 rmex_callback(void *baton, cfg_section_t *section, cfg_option_t *option)
 {
-  /* Only clear the `expanded' flag if the value actually contains
+  /* Only reset the expansion state if the value actually contains
      variable expansions. */
-  if (option->expanded && option->x_value != NULL)
+  if (   (option->state == option_state_expanded && option->x_value != NULL)
+      || option->state == option_state_cyclic)
     {
       option->x_value = NULL;
-      option->expanded = FALSE;
+      option->state = option_state_needs_expanding;
     }
 
   return FALSE;
@@ -482,7 +504,7 @@ find_option(svn_config_t *cfg, const cha
 
 
 /* Has a bi-directional dependency with make_string_from_option(). */
-static void
+static svn_boolean_t
 expand_option_value(svn_config_t *cfg, cfg_section_t *section,
                     const char *opt_value, const char **opt_x_valuep,
                     apr_pool_t *x_pool);
@@ -496,7 +518,20 @@ make_string_from_option(const char **val
                         apr_pool_t* x_pool)
 {
   /* Expand the option value if necessary. */
-  if (!opt->expanded)
+  if (   opt->state == option_state_expanding
+      || opt->state == option_state_cyclic)
+    {
+      /* Recursion is not supported.  Since we can't produce an error
+       * nor should we abort the process, the next best thing is to
+       * report the recursive part as an empty string. */
+      *valuep = "";
+
+      /* Go into "value undefined" state. */
+      opt->state = option_state_cyclic;
+
+      return;
+    }
+  else if (opt->state == option_state_needs_expanding)
     {
       /* before attempting to expand an option, check for the placeholder.
        * If none is there, there is no point in calling expand_option_value.
@@ -511,9 +546,16 @@ make_string_from_option(const char **val
 
           tmp_pool = (x_pool ? x_pool : svn_pool_create(cfg->x_pool));
 
-          expand_option_value(cfg, section, opt->value, &opt->x_value, tmp_pool);
-          opt->expanded = TRUE;
+          /* Expand the value. During that process, have the option marked
+           * as "expanding" to detect cycles. */
+          opt->state = option_state_expanding;
+          if (expand_option_value(cfg, section, opt->value, &opt->x_value,
+                                  tmp_pool))
+            opt->state = option_state_expanded;
+          else
+            opt->state = option_state_cyclic;
 
+          /* Ensure the expanded value is allocated in a permanent pool. */
           if (x_pool != cfg->x_pool)
             {
               /* Grab the fully expanded value from tmp_pool before its
@@ -527,7 +569,7 @@ make_string_from_option(const char **val
         }
       else
         {
-          opt->expanded = TRUE;
+          opt->state = option_state_expanded;
         }
     }
 
@@ -549,8 +591,9 @@ make_string_from_option(const char **val
 
 /* Expand OPT_VALUE (which may be NULL) in SECTION into *OPT_X_VALUEP.
    If no variable replacements are done, set *OPT_X_VALUEP to
-   NULL. Allocate from X_POOL. */
-static void
+   NULL.  Return TRUE if the expanded value is defined and FALSE
+   for recursive definitions.  Allocate from X_POOL. */
+static svn_boolean_t
 expand_option_value(svn_config_t *cfg, cfg_section_t *section,
                     const char *opt_value, const char **opt_x_valuep,
                     apr_pool_t *x_pool)
@@ -587,6 +630,18 @@ expand_option_value(svn_config_t *cfg, c
                  should terminate. */
               make_string_from_option(&cstring, cfg, section, x_opt, x_pool);
 
+              /* Values depending on cyclic values must also be marked as
+               * "undefined" because they might themselves form cycles with
+               * the one cycle we just detected.  Due to the early abort of
+               * the recursion, we won't follow and thus detect dependent
+               * cycles anymore.
+               */
+              if (x_opt->state == option_state_cyclic)
+                {
+                  *opt_x_valuep = "";
+                  return FALSE;
+                }
+
               /* Append the plain text preceding the expansion. */
               len = name_start - FMT_START_LEN - copy_from;
               if (buf == NULL)
@@ -625,6 +680,9 @@ expand_option_value(svn_config_t *cfg, c
     }
   else
     *opt_x_valuep = NULL;
+
+  /* Expansion has a well-defined answer. */
+  return TRUE;
 }
 
 static cfg_section_t *
@@ -664,7 +722,7 @@ svn_config_create_option(cfg_option_t **
 
   o->value = apr_pstrdup(pool, value);
   o->x_value = NULL;
-  o->expanded = FALSE;
+  o->state = option_state_needs_expanding;
 
   *opt = o;
 }
@@ -685,7 +743,8 @@ svn_config__is_expanded(svn_config_t *cf
     return FALSE;
 
   /* already expanded? */
-  if (opt->expanded)
+  if (   opt->state == option_state_expanded
+      || opt->state == option_state_cyclic)
     return TRUE;
 
   /* needs expansion? */
@@ -719,8 +778,14 @@ svn_config_get(svn_config_t *cfg, const
           {
             apr_pool_t *tmp_pool = svn_pool_create(cfg->pool);
             const char *x_default;
-            expand_option_value(cfg, sec, default_value, &x_default, tmp_pool);
-            if (x_default)
+            if (!expand_option_value(cfg, sec, default_value, &x_default,
+                                     tmp_pool))
+              {
+                /* Recursive definitions are not supported.
+                   Normalize the answer in that case. */
+                *valuep = "";
+              }
+            else if (x_default)
               {
                 svn_stringbuf_set(cfg->tmp_value, x_default);
                 *valuep = cfg->tmp_value->data;
@@ -758,7 +823,7 @@ svn_config_set(svn_config_t *cfg,
     {
       /* Replace the option's value. */
       opt->value = apr_pstrdup(cfg->pool, value);
-      opt->expanded = FALSE;
+      opt->state = option_state_needs_expanding;
       return;
     }
 
@@ -1171,7 +1236,7 @@ svn_config_dup(svn_config_t **cfgp,
 
       destopt->value = apr_pstrdup(pool, srcopt->value);
       destopt->x_value = apr_pstrdup(pool, srcopt->x_value);
-      destopt->expanded = srcopt->expanded;
+      destopt->state = srcopt->state;
       apr_hash_set(destsec->options,
                    apr_pstrdup(pool, (const char*)optkey),
                    optkeyLength, destopt);

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/io.c?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/io.c Mon Jun 29 13:42:10 2015
@@ -2301,6 +2301,14 @@ svn_error_t *svn_io_file_flush_to_disk(a
                                        apr_pool_t *pool)
 {
   apr_os_file_t filehand;
+  const char *fname;
+  apr_status_t apr_err;
+
+  /* We need this only in case of an error but this is cheap to get -
+   * so we do it here for clarity. */
+  apr_err = apr_file_name_get(&fname, file);
+  if (apr_err)
+    return svn_error_wrap_apr(apr_err, _("Can't get file name"));
 
   /* ### In apr 1.4+ we could delegate most of this function to
          apr_file_sync(). The only major difference is that this doesn't
@@ -2318,7 +2326,8 @@ svn_error_t *svn_io_file_flush_to_disk(a
 
     if (! FlushFileBuffers(filehand))
         return svn_error_wrap_apr(apr_get_os_error(),
-                                  _("Can't flush file to disk"));
+                                  _("Can't flush file '%s' to disk"),
+                                  try_utf8_from_internal_style(fname, pool));
 
 #else
       int rv;
@@ -2339,7 +2348,8 @@ svn_error_t *svn_io_file_flush_to_disk(a
 
       if (rv == -1)
         return svn_error_wrap_apr(apr_get_os_error(),
-                                  _("Can't flush file to disk"));
+                                  _("Can't flush file '%s' to disk"),
+                                  try_utf8_from_internal_style(fname, pool));
 
 #endif
   }
@@ -4014,6 +4024,24 @@ svn_io_stat(apr_finfo_t *finfo, const ch
   return SVN_NO_ERROR;
 }
 
+#if defined(WIN32)
+/* Platform specific implementation of apr_file_rename() to workaround
+   APR problems on Windows. */
+static apr_status_t
+win32_file_rename(const WCHAR *from_path_w,
+                  const WCHAR *to_path_w,
+                  apr_pool_t *pool)
+{
+  /* APR calls MoveFileExW() with MOVEFILE_COPY_ALLOWED, while we rely
+   * that rename is atomic operation. Call MoveFileEx directly on Windows
+   * without MOVEFILE_COPY_ALLOWED flag to workaround it.
+   */
+  if (!MoveFileExW(from_path_w, to_path_w, MOVEFILE_REPLACE_EXISTING))
+      return apr_get_os_error();
+
+  return APR_SUCCESS;
+}
+#endif
 
 svn_error_t *
 svn_io_file_rename(const char *from_path, const char *to_path,
@@ -4021,13 +4049,19 @@ svn_io_file_rename(const char *from_path
 {
   apr_status_t status = APR_SUCCESS;
   const char *from_path_apr, *to_path_apr;
+#if defined(WIN32)
+  WCHAR *from_path_w;
+  WCHAR *to_path_w;
+#endif
 
   SVN_ERR(cstring_from_utf8(&from_path_apr, from_path, pool));
   SVN_ERR(cstring_from_utf8(&to_path_apr, to_path, pool));
 
-  status = apr_file_rename(from_path_apr, to_path_apr, pool);
+#if defined(WIN32)
+  SVN_ERR(svn_io__utf8_to_unicode_longpath(&from_path_w, from_path_apr, pool));
+  SVN_ERR(svn_io__utf8_to_unicode_longpath(&to_path_w, to_path_apr, pool));
+  status = win32_file_rename(from_path_w, to_path_w, pool);
 
-#if defined(WIN32) || defined(__OS2__)
   /* If the target file is read only NTFS reports EACCESS and
      FAT/FAT32 reports EEXIST */
   if (APR_STATUS_IS_EACCES(status) || APR_STATUS_IS_EEXIST(status))
@@ -4037,9 +4071,23 @@ svn_io_file_rename(const char *from_path
          allow renaming when from_path is read only. */
       SVN_ERR(svn_io_set_file_read_write(to_path, TRUE, pool));
 
+      status = win32_file_rename(from_path_w, to_path_w, pool);
+    }
+  WIN32_RETRY_LOOP(status, win32_file_rename(from_path_w, to_path_w, pool));
+#elif defined(__OS2__)
+  /* If the target file is read only NTFS reports EACCESS and
+     FAT/FAT32 reports EEXIST */
+  if (APR_STATUS_IS_EACCES(status) || APR_STATUS_IS_EEXIST(status))
+    {
+      /* Set the destination file writable because OS/2 will not
+         allow us to rename when to_path is read-only, but will
+         allow renaming when from_path is read only. */
+      SVN_ERR(svn_io_set_file_read_write(to_path, TRUE, pool));
+
       status = apr_file_rename(from_path_apr, to_path_apr, pool);
     }
-  WIN32_RETRY_LOOP(status, apr_file_rename(from_path_apr, to_path_apr, pool));
+#else
+  status = apr_file_rename(from_path_apr, to_path_apr, pool);
 #endif /* WIN32 || __OS2__ */
 
   if (status)

Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/conflicts.c?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_wc/conflicts.c Mon Jun 29 13:42:10 2015
@@ -2323,6 +2323,17 @@ svn_wc__read_conflicts(const apr_array_h
   return SVN_NO_ERROR;
 }
 
+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)
+{
+  return svn_wc__read_conflicts(conflicts, NULL, wc_ctx->db, local_abspath, 
+                                FALSE, FALSE, result_pool, scratch_pool);
+}
+
 
 /*** Resolving a conflict automatically ***/
 

Modified: subversion/branches/move-tracking-2/subversion/mod_dav_svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/mod_dav_svn/util.c?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/mod_dav_svn/util.c (original)
+++ subversion/branches/move-tracking-2/subversion/mod_dav_svn/util.c Mon Jun 29 13:42:10 2015
@@ -746,7 +746,7 @@ request_body_to_string(svn_string_t **re
   int seen_eos;
   apr_status_t status;
   apr_off_t total_read = 0;
-  apr_off_t limit_req_body = ap_get_limit_req_body(r);
+  apr_off_t limit_req_body = ap_get_limit_xml_body(r);
   int result = HTTP_BAD_REQUEST;
   const char *content_length_str;
   char *endp;

Modified: subversion/branches/move-tracking-2/subversion/svn/cl-conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svn/cl-conflicts.c?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svn/cl-conflicts.c (original)
+++ subversion/branches/move-tracking-2/subversion/svn/cl-conflicts.c Mon Jun 29 13:42:10 2015
@@ -229,7 +229,7 @@ operation_str(svn_wc_operation_t operati
 svn_error_t *
 svn_cl__get_human_readable_prop_conflict_description(
   const char **desc,
-  const svn_wc_conflict_description2_t *conflict,
+  const svn_client_conflict_t *conflict,
   apr_pool_t *pool)
 {
   const char *reason_str, *action_str;
@@ -288,7 +288,7 @@ svn_cl__get_human_readable_prop_conflict
 svn_error_t *
 svn_cl__get_human_readable_tree_conflict_description(
   const char **desc,
-  const svn_wc_conflict_description2_t *conflict,
+  const svn_client_conflict_t *conflict,
   apr_pool_t *pool)
 {
   const char *action, *reason, *operation;
@@ -301,32 +301,26 @@ svn_cl__get_human_readable_tree_conflict
   conflict_action = svn_client_conflict_get_incoming_change(conflict);
   conflict_reason = svn_client_conflict_get_local_change(conflict);
   conflict_operation = svn_client_conflict_get_operation(conflict);
-  conflict_node_kind = svn_client_conflict_get_node_kind(conflict);
+  conflict_node_kind = svn_client_conflict_tree_get_victim_node_kind(conflict);
 
   /* Determine the node kind of the incoming change. */
   incoming_kind = svn_node_unknown;
   if (conflict_action == svn_wc_conflict_action_edit ||
       conflict_action == svn_wc_conflict_action_delete)
     {
-      const svn_wc_conflict_version_t *src_left_version;
-
       /* Change is acting on 'src_left' version of the node. */
-      src_left_version = svn_client_conflict_get_src_left_version(conflict);
-      if (src_left_version)
-        incoming_kind = src_left_version->node_kind;
+      SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
+                NULL, NULL, &incoming_kind, conflict, pool, pool));
     }
   else if (conflict_action == svn_wc_conflict_action_add ||
            conflict_action == svn_wc_conflict_action_replace)
     {
-      const svn_wc_conflict_version_t *src_right_version;
-
       /* Change is acting on 'src_right' version of the node.
        *
        * ### For 'replace', the node kind is ambiguous. However, src_left
        * ### is NULL for replace, so we must use src_right. */
-      src_right_version = svn_client_conflict_get_src_right_version(conflict);
-      if (src_right_version)
-        incoming_kind = src_right_version->node_kind;
+      SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
+                NULL, NULL, &incoming_kind, conflict, pool, pool));
     }
 
   reason = local_reason_str(conflict_node_kind, conflict_reason,
@@ -380,13 +374,16 @@ svn_cl__get_human_readable_action_descri
 
 
 /* Helper for svn_cl__append_tree_conflict_info_xml().
- * Appends the attributes of the given VERSION to ATT_HASH.
+ * Appends the repository location of a conflicted node to ATT_HASH.
  * SIDE is the content of the version tag's side="..." attribute,
  * currently one of "source-left" or "source-right".*/
 static svn_error_t *
 add_conflict_version_xml(svn_stringbuf_t **pstr,
                          const char *side,
-                         const svn_wc_conflict_version_t *version,
+                         const char *repos_root_url,
+                         const char *repos_relpath,
+                         svn_revnum_t peg_rev,
+                         svn_node_kind_t node_kind,
                          apr_pool_t *pool)
 {
   apr_hash_t *att_hash = apr_hash_make(pool);
@@ -394,18 +391,17 @@ add_conflict_version_xml(svn_stringbuf_t
 
   svn_hash_sets(att_hash, "side", side);
 
-  if (version->repos_url)
-    svn_hash_sets(att_hash, "repos-url", version->repos_url);
+  if (repos_root_url)
+    svn_hash_sets(att_hash, "repos-url", repos_root_url);
 
-  if (version->path_in_repos)
-    svn_hash_sets(att_hash, "path-in-repos", version->path_in_repos);
+  if (repos_relpath)
+    svn_hash_sets(att_hash, "path-in-repos", repos_relpath);
 
-  if (SVN_IS_VALID_REVNUM(version->peg_rev))
-    svn_hash_sets(att_hash, "revision", apr_ltoa(pool, version->peg_rev));
+  if (SVN_IS_VALID_REVNUM(peg_rev))
+    svn_hash_sets(att_hash, "revision", apr_ltoa(pool, peg_rev));
 
-  if (version->node_kind != svn_node_unknown)
-    svn_hash_sets(att_hash, "kind",
-                  svn_cl__node_kind_str_xml(version->node_kind));
+  if (node_kind != svn_node_unknown)
+    svn_hash_sets(att_hash, "kind", svn_cl__node_kind_str_xml(node_kind));
 
   svn_xml_make_open_tag_hash(pstr, pool, svn_xml_self_closing,
                              "version", att_hash);
@@ -415,13 +411,15 @@ add_conflict_version_xml(svn_stringbuf_t
 
 static svn_error_t *
 append_tree_conflict_info_xml(svn_stringbuf_t *str,
-                              const svn_wc_conflict_description2_t *conflict,
+                              const svn_client_conflict_t *conflict,
                               apr_pool_t *pool)
 {
   apr_hash_t *att_hash = apr_hash_make(pool);
   const char *tmp;
-  const svn_wc_conflict_version_t *src_left_version;
-  const svn_wc_conflict_version_t *src_right_version;
+  const char *repos_root_url;
+  const char *repos_relpath;
+  svn_revnum_t peg_rev;
+  svn_node_kind_t node_kind;
 
   svn_hash_sets(att_hash, "victim",
                 svn_dirent_basename(
@@ -429,7 +427,7 @@ append_tree_conflict_info_xml(svn_string
 
   svn_hash_sets(att_hash, "kind",
                 svn_cl__node_kind_str_xml(
-                  svn_client_conflict_get_node_kind(conflict)));
+                  svn_client_conflict_tree_get_victim_node_kind(conflict)));
 
   svn_hash_sets(att_hash, "operation",
                 svn_cl__operation_str_xml(
@@ -449,19 +447,30 @@ append_tree_conflict_info_xml(svn_string
 
   /* Add child tags for OLDER_VERSION and THEIR_VERSION. */
 
-  src_left_version = svn_client_conflict_get_src_left_version(conflict);
-  if (src_left_version)
-    SVN_ERR(add_conflict_version_xml(&str,
-                                     "source-left",
-                                     src_left_version,
-                                     pool));
-
-  src_right_version = svn_client_conflict_get_src_right_version(conflict);
-  if (src_right_version)
+  SVN_ERR(svn_client_conflict_get_repos_info(&repos_root_url, NULL, conflict,
+                                             pool, pool));
+  SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(&repos_relpath,
+                                                              &peg_rev,
+                                                              &node_kind,
+                                                              conflict,
+                                                              pool,
+                                                              pool));
+  if (repos_root_url && repos_relpath)
+    SVN_ERR(add_conflict_version_xml(&str, "source-left",
+                                     repos_root_url, repos_relpath, peg_rev,
+                                     node_kind, pool));
+
+  SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(&repos_relpath,
+                                                              &peg_rev,
+                                                              &node_kind,
+                                                              conflict,
+                                                              pool,
+                                                              pool));
+  if (repos_root_url && repos_relpath)
     SVN_ERR(add_conflict_version_xml(&str,
                                      "source-right",
-                                     src_right_version,
-                                     pool));
+                                     repos_root_url, repos_relpath, peg_rev,
+                                     node_kind, pool));
 
   svn_xml_make_close_tag(&str, pool, "tree-conflict");
 
@@ -470,15 +479,17 @@ append_tree_conflict_info_xml(svn_string
 
 svn_error_t *
 svn_cl__append_conflict_info_xml(svn_stringbuf_t *str,
-                                 const svn_wc_conflict_description2_t *conflict,
+                                 const svn_client_conflict_t *conflict,
                                  apr_pool_t *scratch_pool)
 {
   apr_hash_t *att_hash;
   const char *kind;
   svn_wc_conflict_kind_t conflict_kind;
   svn_wc_operation_t conflict_operation;
-  const svn_wc_conflict_version_t *src_left_version;
-  const svn_wc_conflict_version_t *src_right_version;
+  const char *repos_root_url;
+  const char *repos_relpath;
+  svn_revnum_t peg_rev;
+  svn_node_kind_t node_kind;
 
   conflict_kind = svn_client_conflict_get_kind(conflict);
   conflict_operation = svn_client_conflict_get_operation(conflict);
@@ -507,45 +518,66 @@ svn_cl__append_conflict_info_xml(svn_str
   svn_xml_make_open_tag_hash(&str, scratch_pool,
                              svn_xml_normal, "conflict", att_hash);
 
-  src_left_version = svn_client_conflict_get_src_left_version(conflict);
-  if (src_left_version)
-    SVN_ERR(add_conflict_version_xml(&str,
-                                     "source-left",
-                                     src_left_version,
-                                     scratch_pool));
-
-  src_right_version = svn_client_conflict_get_src_right_version(conflict);
-  if (src_right_version)
-    SVN_ERR(add_conflict_version_xml(&str,
-                                     "source-right",
-                                     src_right_version,
-                                     scratch_pool));
+  SVN_ERR(svn_client_conflict_get_repos_info(&repos_root_url, NULL, conflict,
+                                             scratch_pool, scratch_pool));
+  SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(&repos_relpath,
+                                                              &peg_rev,
+                                                              &node_kind,
+                                                              conflict,
+                                                              scratch_pool,
+                                                              scratch_pool));
+  if (repos_root_url && repos_relpath)
+    SVN_ERR(add_conflict_version_xml(&str, "source-left",
+                                     repos_root_url, repos_relpath, peg_rev,
+                                     node_kind, scratch_pool));
+
+  SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(&repos_relpath,
+                                                              &peg_rev,
+                                                              &node_kind,
+                                                              conflict,
+                                                              scratch_pool,
+                                                              scratch_pool));
+  if (repos_root_url && repos_relpath)
+    SVN_ERR(add_conflict_version_xml(&str, "source-right",
+                                     repos_root_url, repos_relpath, peg_rev,
+                                     node_kind, scratch_pool));
 
   switch (conflict_kind)
     {
+      const char *base_abspath;
+      const char *my_abspath;
+      const char *their_abspath;
+
       case svn_wc_conflict_kind_text:
+        SVN_ERR(svn_client_conflict_text_get_contents(NULL, &my_abspath,
+                                                      &base_abspath,
+                                                      &their_abspath,
+                                                      conflict, scratch_pool,
+                                                      scratch_pool));
         /* "<prev-base-file> xx </prev-base-file>" */
         svn_cl__xml_tagged_cdata(
-          &str, scratch_pool, "prev-base-file",
-          svn_client_conflict_get_base_abspath(conflict));
+          &str, scratch_pool, "prev-base-file", base_abspath);
 
         /* "<prev-wc-file> xx </prev-wc-file>" */
         svn_cl__xml_tagged_cdata(
-          &str, scratch_pool, "prev-wc-file",
-          svn_client_conflict_get_my_abspath(conflict));
+          &str, scratch_pool, "prev-wc-file", my_abspath);
 
         /* "<cur-base-file> xx </cur-base-file>" */
         svn_cl__xml_tagged_cdata(
-          &str, scratch_pool, "cur-base-file",
-          svn_client_conflict_get_their_abspath(conflict));
+          &str, scratch_pool, "cur-base-file", their_abspath);
 
         break;
 
       case svn_wc_conflict_kind_property:
-        /* "<prop-file> xx </prop-file>" */
-        svn_cl__xml_tagged_cdata(
-          &str, scratch_pool, "prop-file",
-          svn_client_conflict_get_their_abspath(conflict));
+        {
+          const char *reject_abspath;
+
+          /* "<prop-file> xx </prop-file>" */
+          reject_abspath =
+            svn_client_conflict_prop_get_reject_abspath(conflict);
+          svn_cl__xml_tagged_cdata(
+            &str, scratch_pool, "prop-file", reject_abspath);
+        }
         break;
 
       default:

Modified: subversion/branches/move-tracking-2/subversion/svn/cl-conflicts.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svn/cl-conflicts.h?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svn/cl-conflicts.h (original)
+++ subversion/branches/move-tracking-2/subversion/svn/cl-conflicts.h Mon Jun 29 13:42:10 2015
@@ -31,6 +31,7 @@
 
 #include "svn_types.h"
 #include "svn_string.h"
+#include "svn_client.h"
 #include "svn_wc.h"
 
 #ifdef __cplusplus
@@ -48,7 +49,7 @@ extern "C" {
 svn_error_t *
 svn_cl__get_human_readable_prop_conflict_description(
   const char **desc,
-  const svn_wc_conflict_description2_t *conflict,
+  const svn_client_conflict_t *conflict,
   apr_pool_t *pool);
 
 /**
@@ -60,7 +61,7 @@ svn_cl__get_human_readable_prop_conflict
 svn_error_t *
 svn_cl__get_human_readable_tree_conflict_description(
   const char **desc,
-  const svn_wc_conflict_description2_t *conflict,
+  const svn_client_conflict_t *conflict,
   apr_pool_t *pool);
 
 /* Like svn_cl__get_human_readable_tree_conflict_description but
@@ -80,7 +81,7 @@ svn_cl__get_human_readable_action_descri
 svn_error_t *
 svn_cl__append_conflict_info_xml(
   svn_stringbuf_t *str,
-  const svn_wc_conflict_description2_t *conflict,
+  const svn_client_conflict_t *conflict,
   apr_pool_t *pool);
 
 #ifdef __cplusplus

Modified: subversion/branches/move-tracking-2/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svn/cl.h?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svn/cl.h (original)
+++ subversion/branches/move-tracking-2/subversion/svn/cl.h Mon Jun 29 13:42:10 2015
@@ -777,15 +777,18 @@ svn_cl__args_to_target_array_print_reser
                                             svn_boolean_t keep_dest_origpath_on_truepath_collision,
                                             apr_pool_t *pool);
 
-/* Return a string showing NODE's kind, URL and revision, to the extent that
- * that information is available in NODE. If NODE itself is NULL, this prints
- * just a 'none' node kind.
+/* Return a string showing a conflicted node's kind, URL and revision,
+ * to the extent that that information is available. If REPOS_ROOT_URL or
+ * REPOS_RELPATH are NULL, this prints just a 'none' node kind.
  * WC_REPOS_ROOT_URL should reflect the target working copy's repository
- * root URL. If NODE is from that same URL, the printed URL is abbreviated
+ * root URL. If the node is from that same URL, the printed URL is abbreviated
  * to caret notation (^/). WC_REPOS_ROOT_URL may be NULL, in which case
  * this function tries to print the conflicted node's complete URL. */
 const char *
-svn_cl__node_description(const svn_wc_conflict_version_t *node,
+svn_cl__node_description(const char *repos_root_url,
+                         const char *repos_relpath,
+                         svn_revnum_t peg_rev,
+                         svn_node_kind_t node_kind,
                          const char *wc_repos_root_URL,
                          apr_pool_t *pool);
 

Modified: subversion/branches/move-tracking-2/subversion/svn/conflict-callbacks.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svn/conflict-callbacks.c?rev=1688213&r1=1688212&r2=1688213&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svn/conflict-callbacks.c (original)
+++ subversion/branches/move-tracking-2/subversion/svn/conflict-callbacks.c Mon Jun 29 13:42:10 2015
@@ -128,9 +128,10 @@ svn_cl__accept_from_word(const char *wor
 
 
 /* Print on stdout a diff that shows incoming conflicting changes
- * corresponding to the conflict described in DESC. */
+ * corresponding to the conflict described in CONFLICT. */
 static svn_error_t *
-show_diff(const svn_wc_conflict_description2_t *desc,
+show_diff(const svn_client_conflict_t *conflict,
+          const char *merged_abspath,
           const char *path_prefix,
           svn_cancel_func_t cancel_func,
           void *cancel_baton,
@@ -141,10 +142,13 @@ show_diff(const svn_wc_conflict_descript
   svn_diff_t *diff;
   svn_stream_t *output;
   svn_diff_file_options_t *options;
-  const char *merged_file;
+  const char *my_abspath;
+  const char *their_abspath;
 
-  merged_file = svn_client_conflict_get_merged_file(desc);
-  if (merged_file)
+  SVN_ERR(svn_client_conflict_text_get_contents(NULL, &my_abspath, NULL,
+                                                &their_abspath,
+                                                conflict, pool, pool));
+  if (merged_abspath)
     {
       /* For conflicts recorded by the 'merge' operation, show a diff between
        * 'mine' (the working version of the file as it appeared before the
@@ -158,26 +162,26 @@ show_diff(const svn_wc_conflict_descript
        *
        * This way, the diff is always minimal and clearly identifies changes
        * brought into the working copy by the update/switch/merge operation. */
-      if (svn_client_conflict_get_operation(desc) == svn_wc_operation_merge)
+      if (svn_client_conflict_get_operation(conflict) == svn_wc_operation_merge)
         {
-          path1 = svn_client_conflict_get_my_abspath(desc);
+          path1 = my_abspath;
           label1 = _("MINE");
         }
       else
         {
-          path1 = svn_client_conflict_get_their_abspath(desc);
+          path1 = their_abspath;
           label1 = _("THEIRS");
         }
-      path2 = merged_file;
+      path2 = merged_abspath;
       label2 = _("MERGED");
     }
   else
     {
       /* There's no merged file, but we can show the
          difference between mine and theirs. */
-      path1 = svn_client_conflict_get_their_abspath(desc);
+      path1 = their_abspath;
       label1 = _("THEIRS");
-      path2 = svn_client_conflict_get_my_abspath(desc);
+      path2 = my_abspath;
       label2 = _("MINE");
     }
 
@@ -206,9 +210,9 @@ show_diff(const svn_wc_conflict_descript
 
 
 /* Print on stdout just the conflict hunks of a diff among the 'base', 'their'
- * and 'my' files of DESC. */
+ * and 'my' files of CONFLICT. */
 static svn_error_t *
-show_conflicts(const svn_wc_conflict_description2_t *desc,
+show_conflicts(const svn_client_conflict_t *conflict,
                svn_cancel_func_t cancel_func,
                void *cancel_baton,
                apr_pool_t *pool)
@@ -216,22 +220,22 @@ show_conflicts(const svn_wc_conflict_des
   svn_diff_t *diff;
   svn_stream_t *output;
   svn_diff_file_options_t *options;
-
+  const char *base_abspath;
+  const char *my_abspath;
+  const char *their_abspath;
+
+  SVN_ERR(svn_client_conflict_text_get_contents(NULL, &my_abspath,
+                                                &base_abspath, &their_abspath,
+                                                conflict, pool, pool));
   options = svn_diff_file_options_create(pool);
   options->ignore_eol_style = TRUE;
   SVN_ERR(svn_stream_for_stdout(&output, pool));
-  SVN_ERR(svn_diff_file_diff3_2(&diff,
-                                svn_client_conflict_get_base_abspath(desc),
-                                svn_client_conflict_get_my_abspath(desc),
-                                svn_client_conflict_get_their_abspath(desc),
+  SVN_ERR(svn_diff_file_diff3_2(&diff, base_abspath, my_abspath, their_abspath,
                                 options, pool));
   /* ### Consider putting the markers/labels from
      ### svn_wc__merge_internal in the conflict description. */
   return svn_diff_file_output_merge3(
-           output, diff,
-           svn_client_conflict_get_base_abspath(desc),
-           svn_client_conflict_get_my_abspath(desc),
-           svn_client_conflict_get_their_abspath(desc),
+           output, diff, base_abspath, my_abspath, their_abspath,
            _("||||||| ORIGINAL"),
            _("<<<<<<< MINE (select with 'mc')"),
            _(">>>>>>> THEIRS (select with 'tc')"),
@@ -245,61 +249,49 @@ show_conflicts(const svn_wc_conflict_des
 /* Perform a 3-way merge of the conflicting values of a property,
  * and write the result to the OUTPUT stream.
  *
- * If MERGED_ABSPATH is non-NULL, use it as 'my' version instead of
- * DESC->MY_ABSPATH.
+ * If MERGED_PROPVAL is non-NULL, use it as 'my' version instead of
+ * MY_ABSPATH.
  *
  * Assume the values are printable UTF-8 text.
  */
 static svn_error_t *
 merge_prop_conflict(svn_stream_t *output,
-                    const svn_wc_conflict_description2_t *desc,
-                    const char *merged_abspath,
+                    const svn_string_t *base_propval,
+                    const svn_string_t *my_propval,
+                    const svn_string_t *their_propval,
+                    const svn_string_t *merged_propval,
                     svn_cancel_func_t cancel_func,
                     void *cancel_baton,
                     apr_pool_t *pool)
 {
-  const char *base_abspath = svn_client_conflict_get_base_abspath(desc);
-  const char *my_abspath = svn_client_conflict_get_my_abspath(desc);
-  const char *their_abspath = svn_client_conflict_get_their_abspath(desc);
   svn_diff_file_options_t *options = svn_diff_file_options_create(pool);
   svn_diff_t *diff;
 
-  /* If any of the property values is missing, use an empty file instead
+  /* If any of the property values is missing, use an empty value instead
    * for the purpose of showing a diff. */
-  if (! base_abspath || ! my_abspath || ! their_abspath)
-    {
-      const char *empty_file;
-
-      SVN_ERR(svn_io_open_unique_file3(NULL, &empty_file,
-                                       NULL, svn_io_file_del_on_pool_cleanup,
-                                       pool, pool));
-      if (! base_abspath)
-        base_abspath = empty_file;
-      if (! my_abspath)
-        my_abspath = empty_file;
-      if (! their_abspath)
-        their_abspath = empty_file;
-    }
-
+  if (base_propval == NULL)
+    base_propval = svn_string_create_empty(pool);
+  if (my_propval == NULL)
+    my_propval = svn_string_create_empty(pool);
+  if (my_propval == NULL)
+    my_propval = svn_string_create_empty(pool);
+    
   options->ignore_eol_style = TRUE;
-  SVN_ERR(svn_diff_file_diff3_2(&diff,
-                                base_abspath,
-                                merged_abspath ? merged_abspath : my_abspath,
-                                their_abspath,
-                                options, pool));
-  SVN_ERR(svn_diff_file_output_merge3(output, diff,
-                                      base_abspath,
-                                      merged_abspath ? merged_abspath
-                                                     : my_abspath,
-                                      their_abspath,
-                                      _("||||||| ORIGINAL"),
-                                      _("<<<<<<< MINE"),
-                                      _(">>>>>>> THEIRS"),
-                                      "=======",
-                                      svn_diff_conflict_display_modified_original_latest,
-                                      cancel_func,
-                                      cancel_baton,
-                                      pool));
+  SVN_ERR(svn_diff_mem_string_diff3(&diff, base_propval,
+                                    merged_propval ?
+                                      merged_propval : my_propval,
+                                    their_propval, options, pool));
+  SVN_ERR(svn_diff_mem_string_output_merge3(
+            output, diff, base_propval,
+            merged_propval ? merged_propval : my_propval, their_propval,
+            _("||||||| ORIGINAL"),
+            _("<<<<<<< MINE"),
+            _(">>>>>>> THEIRS"),
+            "=======",
+            svn_diff_conflict_display_modified_original_latest,
+            cancel_func,
+            cancel_baton,
+            pool));
 
   return SVN_NO_ERROR;
 }
@@ -312,8 +304,10 @@ merge_prop_conflict(svn_stream_t *output
  * Assume the values are printable UTF-8 text.
  */
 static svn_error_t *
-show_prop_conflict(const svn_wc_conflict_description2_t *desc,
-                   const char *merged_abspath,
+show_prop_conflict(const svn_string_t *base_propval,
+                   const svn_string_t *my_propval,
+                   const svn_string_t *their_propval,
+                   const svn_string_t *merged_propval,
                    svn_cancel_func_t cancel_func,
                    void *cancel_baton,
                    apr_pool_t *pool)
@@ -321,13 +315,13 @@ show_prop_conflict(const svn_wc_conflict
   svn_stream_t *output;
 
   SVN_ERR(svn_stream_for_stdout(&output, pool));
-  SVN_ERR(merge_prop_conflict(output, desc, merged_abspath,
-                              cancel_func, cancel_baton, pool));
+  SVN_ERR(merge_prop_conflict(output, base_propval, my_propval, their_propval,
+                              merged_propval, cancel_func, cancel_baton, pool));
 
   return SVN_NO_ERROR;
 }
 
-/* Run an external editor, passing it the MERGED_FILE, or, if the
+/* Run an external editor, passing it the MERGED_ABSPATH, or, if the
  * 'merged' file is null, return an error. The tool to use is determined by
  * B->editor_cmd, B->config and environment variables; see
  * svn_cl__edit_file_externally() for details.
@@ -338,15 +332,15 @@ show_prop_conflict(const svn_wc_conflict
  * return that error. */
 static svn_error_t *
 open_editor(svn_boolean_t *performed_edit,
-            const char *merged_file,
+            const char *merged_abspath,
             svn_cl__interactive_conflict_baton_t *b,
             apr_pool_t *pool)
 {
   svn_error_t *err;
 
-  if (merged_file)
+  if (merged_abspath)
     {
-      err = svn_cmdline__edit_file_externally(merged_file, b->editor_cmd,
+      err = svn_cmdline__edit_file_externally(merged_abspath, b->editor_cmd,
                                               b->config, pool);
       if (err && (err->apr_err == SVN_ERR_CL_NO_EXTERNAL_EDITOR ||
                   err->apr_err == SVN_ERR_EXTERNAL_PROGRAM))
@@ -371,12 +365,16 @@ open_editor(svn_boolean_t *performed_edi
   return SVN_NO_ERROR;
 }
 
-/* Run an external editor, passing it the 'merged' property in DESC.
+/* Run an external editor on the merged property value with conflict markers.
+ * Return the edited result in *MERGED_PROPVAL.
+ * If the edit is aborted, set *MERGED_ABSPATH and *MERGED_PROPVAL to NULL.
  * The tool to use is determined by B->editor_cmd, B->config and
  * environment variables; see svn_cl__edit_file_externally() for details. */
 static svn_error_t *
-edit_prop_conflict(const char **merged_file_path,
-                   const svn_wc_conflict_description2_t *desc,
+edit_prop_conflict(const svn_string_t **merged_propval,
+                   const svn_string_t *base_propval,
+                   const svn_string_t *my_propval,
+                   const svn_string_t *their_propval,
                    svn_cl__interactive_conflict_baton_t *b,
                    apr_pool_t *result_pool,
                    apr_pool_t *scratch_pool)
@@ -391,14 +389,23 @@ edit_prop_conflict(const char **merged_f
                                    result_pool, scratch_pool));
   merged_prop = svn_stream_from_aprfile2(file, TRUE /* disown */,
                                          scratch_pool);
-  SVN_ERR(merge_prop_conflict(merged_prop, desc, NULL,
+  SVN_ERR(merge_prop_conflict(merged_prop, base_propval, my_propval,
+                              their_propval, NULL,
                               b->pb->cancel_func,
                               b->pb->cancel_baton,
                               scratch_pool));
   SVN_ERR(svn_stream_close(merged_prop));
   SVN_ERR(svn_io_file_flush(file, scratch_pool));
   SVN_ERR(open_editor(&performed_edit, file_path, b, scratch_pool));
-  *merged_file_path = (performed_edit ? file_path : NULL);
+  if (performed_edit)
+    {
+      svn_stringbuf_t *buf;
+
+      SVN_ERR(svn_stringbuf_from_file2(&buf, file_path, scratch_pool));
+      *merged_propval = svn_string_create_from_buf(buf, result_pool); 
+    }
+  else
+    *merged_propval = NULL;
 
   return SVN_NO_ERROR;
 }
@@ -695,13 +702,13 @@ prompt_user(const resolver_option_t **op
   return SVN_NO_ERROR;
 }
 
-/* Ask the user what to do about the text conflict described by DESC.
+/* Ask the user what to do about the text conflict described by CONFLICT.
  * Return the answer in RESULT. B is the conflict baton for this
  * conflict resolution session.
  * SCRATCH_POOL is used for temporary allocations. */
 static svn_error_t *
 handle_text_conflict(svn_wc_conflict_result_t *result,
-                     const svn_wc_conflict_description2_t *desc,
+                     const svn_client_conflict_t *conflict,
                      svn_cl__interactive_conflict_baton_t *b,
                      apr_pool_t *scratch_pool)
 {
@@ -715,15 +722,19 @@ handle_text_conflict(svn_wc_conflict_res
      give them a rational basis for choosing (r)esolved? */
   svn_boolean_t knows_something = FALSE;
   const char *local_relpath;
-  const char *local_abspath = svn_client_conflict_get_local_abspath(desc);
-  svn_boolean_t is_binary = svn_client_conflict_get_is_binary(desc);
-  const char *base_abspath = svn_client_conflict_get_base_abspath(desc);
-  const char *my_abspath = svn_client_conflict_get_my_abspath(desc);
-  const char *their_abspath = svn_client_conflict_get_their_abspath(desc);
-  const char *merged_file = svn_client_conflict_get_merged_file(desc);
-
-  SVN_ERR_ASSERT(svn_client_conflict_get_kind(desc) ==
-                 svn_wc_conflict_kind_text);
+  const char *local_abspath = svn_client_conflict_get_local_abspath(conflict);
+  const char *mime_type = svn_client_conflict_text_get_mime_type(conflict);
+  svn_boolean_t is_binary = mime_type ? svn_mime_type_is_binary(mime_type)
+                                      : FALSE;
+  const char *base_abspath;
+  const char *my_abspath;
+  const char *their_abspath;
+  const char *merged_abspath = svn_client_conflict_get_local_abspath(conflict);
+
+  SVN_ERR(svn_client_conflict_text_get_contents(NULL, &my_abspath,
+                                                &base_abspath, &their_abspath,
+                                                conflict, scratch_pool,
+                                                scratch_pool));
 
   local_relpath = svn_cl__local_style_skip_ancestor(b->path_prefix,
                                                     local_abspath,
@@ -747,7 +758,7 @@ handle_text_conflict(svn_wc_conflict_res
      scenario), or if no base is available, we can show a diff
      between mine and theirs. */
   if (!is_binary &&
-      ((merged_file && base_abspath)
+      ((merged_abspath && base_abspath)
       || (!base_abspath && my_abspath && their_abspath)))
     diff_allowed = TRUE;
 
@@ -833,7 +844,7 @@ handle_text_conflict(svn_wc_conflict_res
                                             "files not available.\n\n")));
               continue;
             }
-          SVN_ERR(show_conflicts(desc,
+          SVN_ERR(show_conflicts(conflict,
                                  b->pb->cancel_func,
                                  b->pb->cancel_baton,
                                  iterpool));
@@ -850,14 +861,14 @@ handle_text_conflict(svn_wc_conflict_res
               continue;
             }
 
-          SVN_ERR(show_diff(desc, b->path_prefix,
+          SVN_ERR(show_diff(conflict, merged_abspath, b->path_prefix,
                             b->pb->cancel_func, b->pb->cancel_baton,
                             iterpool));
           knows_something = TRUE;
         }
       else if (strcmp(opt->code, "e") == 0 || strcmp(opt->code, ":-E") == 0)
         {
-          SVN_ERR(open_editor(&performed_edit, merged_file, b, iterpool));
+          SVN_ERR(open_editor(&performed_edit, merged_abspath, b, iterpool));
           if (performed_edit)
             knows_something = TRUE;
         }
@@ -878,7 +889,7 @@ handle_text_conflict(svn_wc_conflict_res
           err = svn_cl__merge_file_externally(base_abspath,
                                               their_abspath,
                                               my_abspath,
-                                              merged_file,
+                                              merged_abspath,
                                               local_abspath, b->config,
                                               NULL, iterpool);
           if (err)
@@ -893,7 +904,7 @@ handle_text_conflict(svn_wc_conflict_res
                                              base_abspath,
                                              their_abspath,
                                              my_abspath,
-                                             merged_file,
+                                             merged_abspath,
                                              local_abspath,
                                              b->path_prefix,
                                              b->editor_cmd,
@@ -931,9 +942,9 @@ handle_text_conflict(svn_wc_conflict_res
         {
           /* ### This check should be earlier as it's nasty to offer an option
            *     and then when the user chooses it say 'Invalid option'. */
-          /* ### 'merged_file' shouldn't be necessary *before* we launch the
+          /* ### 'merged_abspath' shouldn't be necessary *before* we launch the
            *     resolver: it should be the *result* of doing so. */
-          if (base_abspath && their_abspath && my_abspath && merged_file)
+          if (base_abspath && their_abspath && my_abspath && merged_abspath)
             {
               svn_error_t *err;
               char buf[1024];
@@ -942,7 +953,7 @@ handle_text_conflict(svn_wc_conflict_res
               err = svn_cl__merge_file_externally(base_abspath,
                                                   their_abspath,
                                                   my_abspath,
-                                                  merged_file,
+                                                  merged_abspath,
                                                   local_abspath,
                                                   b->config, NULL, iterpool);
               if (err && (err->apr_err == SVN_ERR_CL_NO_EXTERNAL_MERGE_TOOL ||
@@ -973,7 +984,7 @@ handle_text_conflict(svn_wc_conflict_res
                                      base_abspath,
                                      their_abspath,
                                      my_abspath,
-                                     merged_file,
+                                     merged_abspath,
                                      local_abspath,
                                      b->path_prefix,
                                      b->editor_cmd,
@@ -1022,41 +1033,40 @@ handle_text_conflict(svn_wc_conflict_res
   return SVN_NO_ERROR;
 }
 
-/* Ask the user what to do about the property conflict described by DESC.
+/* Ask the user what to do about the property conflict described by CONFLICT.
  * Return the answer in RESULT. B is the conflict baton for this
  * conflict resolution session.
  * SCRATCH_POOL is used for temporary allocations. */
 static svn_error_t *
 handle_prop_conflict(svn_wc_conflict_result_t *result,
-                     const svn_wc_conflict_description2_t *desc,
+                     const svn_client_conflict_t *conflict,
                      svn_cl__interactive_conflict_baton_t *b,
                      apr_pool_t *result_pool,
                      apr_pool_t *scratch_pool)
 {
   apr_pool_t *iterpool;
   const char *message;
-  const char *merged_file_path = NULL;
+  const svn_string_t *merged_propval = NULL;
   svn_boolean_t resolved_allowed = FALSE;
-
-  /* ### Work around a historical bug in the provider: the path to the
-   *     conflict description file was put in the 'theirs' field, and
-   *     'theirs' was put in the 'merged' field. */
-  ((svn_wc_conflict_description2_t *)desc)->their_abspath = desc->merged_file;
-  ((svn_wc_conflict_description2_t *)desc)->merged_file = NULL;
-
-  SVN_ERR_ASSERT(svn_client_conflict_get_kind(desc) ==
-                 svn_wc_conflict_kind_property);
+  const svn_string_t *base_propval;
+  const svn_string_t *my_propval;
+  const svn_string_t *their_propval;
+
+  SVN_ERR(svn_client_conflict_prop_get_propvals(NULL, &my_propval,
+                                                &base_propval, &their_propval,
+                                                conflict, scratch_pool));
 
   SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
                               _("Conflict for property '%s' discovered"
                                 " on '%s'.\n"),
-                              svn_client_conflict_get_property_name(desc),
+                              svn_client_conflict_prop_get_propname(conflict),
                               svn_cl__local_style_skip_ancestor(
                                 b->path_prefix,
-                                svn_client_conflict_get_local_abspath(desc),
+                                svn_client_conflict_get_local_abspath(conflict),
                                 scratch_pool)));
 
-  SVN_ERR(svn_cl__get_human_readable_prop_conflict_description(&message, desc,
+  SVN_ERR(svn_cl__get_human_readable_prop_conflict_description(&message,
+                                                               conflict,
                                                                scratch_pool));
   SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s\n", message));
 
@@ -1094,15 +1104,17 @@ handle_prop_conflict(svn_wc_conflict_res
         }
       else if (strcmp(opt->code, "dc") == 0)
         {
-          SVN_ERR(show_prop_conflict(desc, merged_file_path,
+          SVN_ERR(show_prop_conflict(base_propval, my_propval, their_propval,
+                                     merged_propval,
                                      b->pb->cancel_func, b->pb->cancel_baton,
                                      scratch_pool));
         }
       else if (strcmp(opt->code, "e") == 0)
         {
-          SVN_ERR(edit_prop_conflict(&merged_file_path, desc, b,
-                                     result_pool, scratch_pool));
-          resolved_allowed = (merged_file_path != NULL);
+          SVN_ERR(edit_prop_conflict(&merged_propval,
+                                     base_propval, my_propval, their_propval,
+                                     b, result_pool, scratch_pool));
+          resolved_allowed = (merged_propval != NULL);
         }
       else if (strcmp(opt->code, "r") == 0)
         {
@@ -1114,7 +1126,7 @@ handle_prop_conflict(svn_wc_conflict_res
               continue;
             }
 
-          result->merged_file = merged_file_path;
+          result->merged_value = merged_propval;
           result->choice = svn_wc_conflict_choose_merged;
           break;
         }
@@ -1129,43 +1141,58 @@ handle_prop_conflict(svn_wc_conflict_res
   return SVN_NO_ERROR;
 }
 
-/* Ask the user what to do about the tree conflict described by DESC.
+/* Ask the user what to do about the tree conflict described by CONFLICT.
  * Return the answer in RESULT. B is the conflict baton for this
  * conflict resolution session.
  * SCRATCH_POOL is used for temporary allocations. */
 static svn_error_t *
 handle_tree_conflict(svn_wc_conflict_result_t *result,
-                     const svn_wc_conflict_description2_t *desc,
+                     const svn_client_conflict_t *conflict,
                      svn_cl__interactive_conflict_baton_t *b,
                      apr_pool_t *scratch_pool)
 {
   const char *readable_desc;
   const char *src_left_version;
   const char *src_right_version;
+  const char *repos_root_url;
+  const char *repos_relpath;
+  svn_revnum_t peg_rev;
+  svn_node_kind_t node_kind;
   apr_pool_t *iterpool;
-
+  
   SVN_ERR(svn_cl__get_human_readable_tree_conflict_description(
-           &readable_desc, desc, scratch_pool));
+           &readable_desc, conflict, scratch_pool));
   SVN_ERR(svn_cmdline_fprintf(
                stderr, scratch_pool,
                _("Tree conflict on '%s'\n   > %s\n"),
                svn_cl__local_style_skip_ancestor(b->path_prefix,
-                 svn_client_conflict_get_local_abspath(desc), scratch_pool),
+                 svn_client_conflict_get_local_abspath(conflict), scratch_pool),
                readable_desc));
 
+  SVN_ERR(svn_client_conflict_get_repos_info(&repos_root_url, NULL, conflict,
+                                             scratch_pool, scratch_pool));
+  SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(&repos_relpath,
+                                                              &peg_rev,
+                                                              &node_kind,
+                                                              conflict,
+                                                              scratch_pool,
+                                                              scratch_pool));
   src_left_version =
-              svn_cl__node_description(
-                svn_client_conflict_get_src_left_version(desc),
-                svn_client_conflict_get_src_left_version(desc)->repos_url,
-                scratch_pool);
+              svn_cl__node_description(repos_root_url, repos_relpath, peg_rev,
+                                       node_kind, repos_root_url, scratch_pool);
   if (src_left_version)
     SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s: %s\n",
                                 _("Source  left"), src_left_version));
+
+  SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(&repos_relpath,
+                                                              &peg_rev,
+                                                              &node_kind,
+                                                              conflict,
+                                                              scratch_pool,
+                                                              scratch_pool));
   src_right_version =
-              svn_cl__node_description(
-                svn_client_conflict_get_src_right_version(desc),
-                svn_client_conflict_get_src_right_version(desc)->repos_url,
-                scratch_pool);
+              svn_cl__node_description(repos_root_url, repos_relpath, peg_rev,
+                                       node_kind, repos_root_url, scratch_pool);
   if (src_right_version)
     SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s: %s\n",
                                 _("Source right"), src_right_version));
@@ -1180,12 +1207,14 @@ handle_tree_conflict(svn_wc_conflict_res
 
       tc_opts = tree_conflict_options;
 
-      if (svn_client_conflict_get_operation(desc) == svn_wc_operation_update ||
-          svn_client_conflict_get_operation(desc) == svn_wc_operation_switch)
+      if (svn_client_conflict_get_operation(conflict) ==
+          svn_wc_operation_update ||
+          svn_client_conflict_get_operation(conflict) ==
+          svn_wc_operation_switch)
         {
           svn_wc_conflict_reason_t reason;
 
-          reason = svn_client_conflict_get_local_change(desc);
+          reason = svn_client_conflict_get_local_change(conflict);
           if (reason == svn_wc_conflict_reason_moved_away)
             {
               tc_opts = tree_conflict_options_update_moved_away;
@@ -1193,9 +1222,10 @@ handle_tree_conflict(svn_wc_conflict_res
           else if (reason == svn_wc_conflict_reason_deleted ||
                    reason == svn_wc_conflict_reason_replaced)
             {
-              if (svn_client_conflict_get_incoming_change(desc) ==
+              if (svn_client_conflict_get_incoming_change(conflict) ==
                   svn_wc_conflict_action_edit &&
-                  svn_client_conflict_get_node_kind(desc) == svn_node_dir)
+                  svn_client_conflict_tree_get_victim_node_kind(conflict) ==
+                  svn_node_dir)
                 tc_opts = tree_conflict_options_update_edit_deleted_dir;
             }
         }
@@ -1225,17 +1255,24 @@ handle_tree_conflict(svn_wc_conflict_res
 /* The body of svn_cl__conflict_func_interactive(). */
 static svn_error_t *
 conflict_func_interactive(svn_wc_conflict_result_t **result,
-                          const svn_wc_conflict_description2_t *desc,
+                          const svn_client_conflict_t *conflict,
                           void *baton,
                           apr_pool_t *result_pool,
                           apr_pool_t *scratch_pool)
 {
   svn_cl__interactive_conflict_baton_t *b = baton;
   svn_error_t *err;
-  const char *base_abspath = svn_client_conflict_get_base_abspath(desc);
-  const char *my_abspath = svn_client_conflict_get_my_abspath(desc);
-  const char *their_abspath = svn_client_conflict_get_their_abspath(desc);
-  const char *merged_file = svn_client_conflict_get_merged_file(desc);
+  const char *base_abspath = NULL;
+  const char *my_abspath = NULL;
+  const char *their_abspath = NULL;
+  const char *merged_abspath = svn_client_conflict_get_local_abspath(conflict);
+
+  if (svn_client_conflict_get_kind(conflict) == svn_wc_conflict_kind_text)
+    SVN_ERR(svn_client_conflict_text_get_contents(NULL, &my_abspath,
+                                                  &base_abspath,
+                                                  &their_abspath,
+                                                  conflict, scratch_pool,
+                                                  scratch_pool));
 
   /* Start out assuming we're going to postpone the conflict. */
   *result = svn_wc_create_conflict_result(svn_wc_conflict_choose_postpone,
@@ -1254,10 +1291,6 @@ conflict_func_interactive(svn_wc_conflic
       (*result)->choice = svn_wc_conflict_choose_base;
       return SVN_NO_ERROR;
     case svn_cl__accept_working:
-      /* If the caller didn't merge the property values, then I guess
-       * 'choose working' means 'choose mine'... */
-      if (! merged_file)
-        (*result)->merged_file = my_abspath;
       (*result)->choice = svn_wc_conflict_choose_merged;
       return SVN_NO_ERROR;
     case svn_cl__accept_mine_conflict:
@@ -1273,7 +1306,7 @@ conflict_func_interactive(svn_wc_conflic
       (*result)->choice = svn_wc_conflict_choose_theirs_full;
       return SVN_NO_ERROR;
     case svn_cl__accept_edit:
-      if (merged_file)
+      if (merged_abspath)
         {
           if (b->external_failed)
             {
@@ -1281,7 +1314,7 @@ conflict_func_interactive(svn_wc_conflic
               return SVN_NO_ERROR;
             }
 
-          err = svn_cmdline__edit_file_externally(merged_file,
+          err = svn_cmdline__edit_file_externally(merged_abspath,
                                                   b->editor_cmd, b->config,
                                                   scratch_pool);
           if (err && (err->apr_err == SVN_ERR_CL_NO_EXTERNAL_EDITOR ||
@@ -1304,7 +1337,7 @@ conflict_func_interactive(svn_wc_conflic
       /* else, fall through to prompting. */
       break;
     case svn_cl__accept_launch:
-      if (base_abspath && their_abspath && my_abspath && merged_file)
+      if (base_abspath && their_abspath && my_abspath && merged_abspath)
         {
           svn_boolean_t remains_in_conflict;
           const char *local_abspath;
@@ -1315,11 +1348,11 @@ conflict_func_interactive(svn_wc_conflic
               return SVN_NO_ERROR;
             }
 
-          local_abspath = svn_client_conflict_get_local_abspath(desc);
+          local_abspath = svn_client_conflict_get_local_abspath(conflict);
           err = svn_cl__merge_file_externally(base_abspath,
                                               their_abspath,
                                               my_abspath,
-                                              merged_file,
+                                              merged_abspath,
                                               local_abspath,
                                               b->config,
                                               &remains_in_conflict,
@@ -1364,16 +1397,18 @@ conflict_func_interactive(svn_wc_conflic
      Conflicting edits on a file's text, or
      Conflicting edits on a property.
   */
-  if (((svn_client_conflict_get_kind(desc) == svn_wc_conflict_kind_text)
-       && (svn_client_conflict_get_incoming_change(desc) ==
+  if (((svn_client_conflict_get_kind(conflict) == svn_wc_conflict_kind_text)
+       && (svn_client_conflict_get_incoming_change(conflict) ==
            svn_wc_conflict_action_edit)
-       && (svn_client_conflict_get_local_change(desc) ==
+       && (svn_client_conflict_get_local_change(conflict) ==
            svn_wc_conflict_reason_edited)))
-    SVN_ERR(handle_text_conflict(*result, desc, b, scratch_pool));
-  else if (svn_client_conflict_get_kind(desc) == svn_wc_conflict_kind_property)
-    SVN_ERR(handle_prop_conflict(*result, desc, b, result_pool, scratch_pool));
-  else if (svn_client_conflict_get_kind(desc) == svn_wc_conflict_kind_tree)
-    SVN_ERR(handle_tree_conflict(*result, desc, b, scratch_pool));
+    SVN_ERR(handle_text_conflict(*result, conflict, b, scratch_pool));
+  else if (svn_client_conflict_get_kind(conflict) ==
+           svn_wc_conflict_kind_property)
+    SVN_ERR(handle_prop_conflict(*result, conflict, b, result_pool,
+                                 scratch_pool));
+  else if (svn_client_conflict_get_kind(conflict) == svn_wc_conflict_kind_tree)
+    SVN_ERR(handle_tree_conflict(*result, conflict, b, scratch_pool));
 
   else /* other types of conflicts -- do nothing about them. */
     {
@@ -1391,8 +1426,12 @@ svn_cl__conflict_func_interactive(svn_wc
                                   apr_pool_t *scratch_pool)
 {
   svn_cl__interactive_conflict_baton_t *b = baton;
+  svn_client_conflict_t *conflict;
 
-  SVN_ERR(conflict_func_interactive(result, desc, baton,
+  SVN_ERR(svn_client_conflict_from_wc_description2_t(&conflict, desc,
+                                                     scratch_pool,
+                                                     scratch_pool));
+  SVN_ERR(conflict_func_interactive(result, conflict, baton,
                                     result_pool, scratch_pool));
 
   /* If we are resolving a conflict, adjust the summary of conflicts. */
@@ -1400,11 +1439,11 @@ svn_cl__conflict_func_interactive(svn_wc
     {
       const char *local_path
         = svn_cl__local_style_skip_ancestor(
-            b->path_prefix, svn_client_conflict_get_local_abspath(desc),
+            b->path_prefix, svn_client_conflict_get_local_abspath(conflict),
             scratch_pool);
 
       svn_cl__conflict_stats_resolved(b->conflict_stats, local_path,
-                                      svn_client_conflict_get_kind(desc));
+                                      svn_client_conflict_get_kind(conflict));
     }
   return SVN_NO_ERROR;
 }



Mime
View raw message