You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2013/02/13 07:37:56 UTC

svn commit: r1445479 [4/11] - in /subversion/branches/fsfs-format7: ./ build/generator/ build/generator/swig/ build/generator/templates/ notes/api-errata/1.7/ packages/ subversion/bindings/swig/include/ subversion/bindings/swig/perl/libsvn_swig_perl/ s...

Modified: subversion/branches/fsfs-format7/subversion/libsvn_client/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_client/mergeinfo.c?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_client/mergeinfo.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_client/mergeinfo.c Wed Feb 13 06:37:54 2013
@@ -217,8 +217,8 @@ svn_client__get_wc_mergeinfo(svn_mergein
   if (limit_abspath)
     SVN_ERR_ASSERT(svn_dirent_is_absolute(limit_abspath));
 
-  SVN_ERR(svn_wc__node_get_base(&base_revision, NULL, NULL, NULL, ctx->wc_ctx,
-                                local_abspath,
+  SVN_ERR(svn_wc__node_get_base(&base_revision, NULL, NULL, NULL, NULL,
+                                ctx->wc_ctx, local_abspath,
                                 scratch_pool, scratch_pool));
 
   iterpool = svn_pool_create(scratch_pool);
@@ -287,7 +287,7 @@ svn_client__get_wc_mergeinfo(svn_mergein
           local_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
 
           SVN_ERR(svn_wc__node_get_base(&parent_base_rev, NULL, NULL, NULL,
-                                        ctx->wc_ctx, local_abspath,
+                                        NULL, ctx->wc_ctx, local_abspath,
                                         scratch_pool, scratch_pool));
           SVN_ERR(svn_wc__node_get_changed_info(&parent_changed_rev,
                                                 NULL, NULL,
@@ -371,27 +371,16 @@ svn_client__get_wc_mergeinfo_catalog(svn
                                      apr_pool_t *result_pool,
                                      apr_pool_t *scratch_pool)
 {
-  const char *target_repos_rel_path;
+  const char *target_repos_relpath;
   svn_mergeinfo_t mergeinfo;
   const char *repos_root;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
   *mergeinfo_cat = NULL;
-  SVN_ERR(svn_wc__node_get_repos_info(&repos_root, NULL,
+  SVN_ERR(svn_wc__node_get_repos_info(NULL, &target_repos_relpath,
+                                      &repos_root, NULL,
                                       ctx->wc_ctx, local_abspath,
                                       scratch_pool, scratch_pool));
-  if (!repos_root)
-    {
-      if (walked_path)
-        *walked_path = "";
-      if (inherited)
-        *inherited = FALSE;
-      return SVN_NO_ERROR;
-    }
-
-  SVN_ERR(svn_wc__node_get_repos_relpath(&target_repos_rel_path,
-                                         ctx->wc_ctx, local_abspath,
-                                         scratch_pool, scratch_pool));
 
   /* Get the mergeinfo for the LOCAL_ABSPATH target and set *INHERITED and
      *WALKED_PATH. */
@@ -406,7 +395,7 @@ svn_client__get_wc_mergeinfo_catalog(svn
     {
       *mergeinfo_cat = apr_hash_make(result_pool);
       apr_hash_set(*mergeinfo_cat,
-                   apr_pstrdup(result_pool, target_repos_rel_path),
+                   apr_pstrdup(result_pool, target_repos_relpath),
                    APR_HASH_KEY_STRING, mergeinfo);
     }
 
@@ -438,9 +427,9 @@ svn_client__get_wc_mergeinfo_catalog(svn
           if (strcmp(node_abspath, local_abspath) == 0)
             continue; /* Already parsed in svn_client__get_wc_mergeinfo */
 
-          SVN_ERR(svn_wc__node_get_repos_relpath(&repos_relpath,
-                                                 ctx->wc_ctx, node_abspath,
-                                                 result_pool, scratch_pool));
+          SVN_ERR(svn_wc__node_get_repos_info(NULL, &repos_relpath, NULL, NULL,
+                                              ctx->wc_ctx, node_abspath,
+                                              result_pool, scratch_pool));
 
           SVN_ERR(svn_mergeinfo_parse(&subtree_mergeinfo, propval->data,
                                       result_pool));
@@ -1631,9 +1620,9 @@ svn_client_mergeinfo_get_merged(apr_hash
       if (! svn_path_is_url(path_or_url))
         {
           SVN_ERR(svn_dirent_get_absolute(&path_or_url, path_or_url, pool));
-          SVN_ERR(svn_wc__node_get_repos_relpath(&repos_relpath,
-                                                 ctx->wc_ctx, path_or_url,
-                                                 pool, pool));
+          SVN_ERR(svn_wc__node_get_repos_info(NULL, &repos_relpath, NULL, NULL,
+                                              ctx->wc_ctx, path_or_url,
+                                              pool, pool));
         }
       else
         {
@@ -1674,7 +1663,7 @@ svn_client_mergeinfo_log2(svn_boolean_t 
 {
   const char *log_target = NULL;
   const char *repos_root;
-  const char *target_repos_rel;
+  const char *target_repos_relpath;
   svn_mergeinfo_catalog_t target_mergeinfo_cat;
 
   /* A hash of paths, at or under TARGET_PATH_OR_URL, mapped to
@@ -1729,18 +1718,20 @@ svn_client_mergeinfo_log2(svn_boolean_t 
     {
       SVN_ERR(svn_dirent_get_absolute(&target_path_or_url,
                                       target_path_or_url, scratch_pool));
-      SVN_ERR(svn_wc__node_get_repos_relpath(&target_repos_rel,
-                                             ctx->wc_ctx, target_path_or_url,
-                                             scratch_pool, scratch_pool));
+      SVN_ERR(svn_wc__node_get_repos_info(NULL, &target_repos_relpath,
+                                          NULL, NULL,
+                                          ctx->wc_ctx, target_path_or_url,
+                                          scratch_pool, scratch_pool));
     }
   else
     {
-      target_repos_rel = svn_uri_skip_ancestor(repos_root, target_path_or_url,
-                                               scratch_pool);
+      target_repos_relpath = svn_uri_skip_ancestor(repos_root,
+                                                   target_path_or_url,
+                                                   scratch_pool);
 
       /* TARGET_REPOS_REL should be non-NULL, else get_mergeinfo
          should have failed.  */
-      SVN_ERR_ASSERT(target_repos_rel != NULL); 
+      SVN_ERR_ASSERT(target_repos_relpath != NULL); 
     }
 
   if (!target_mergeinfo_cat)
@@ -1759,7 +1750,7 @@ svn_client_mergeinfo_log2(svn_boolean_t 
         {
           target_mergeinfo_cat = apr_hash_make(scratch_pool);
           apr_hash_set(target_mergeinfo_cat,
-                       target_repos_rel,
+                       target_repos_relpath,
                        APR_HASH_KEY_STRING,
                        apr_hash_make(scratch_pool));
         }
@@ -1840,7 +1831,7 @@ svn_client_mergeinfo_log2(svn_boolean_t 
       svn_mergeinfo_t merged;
       const char *subtree_path = svn__apr_hash_index_key(hi_catalog);
       svn_boolean_t is_subtree = strcmp(subtree_path,
-                                        target_repos_rel) != 0;
+                                        target_repos_relpath) != 0;
       svn_pool_clear(iterpool);
 
       if (is_subtree)
@@ -1849,7 +1840,7 @@ svn_client_mergeinfo_log2(svn_boolean_t 
              then make a copy of SOURCE_HISTORY that is path adjusted
              for the subtree.  */
           const char *subtree_rel_path =
-            subtree_path + strlen(target_repos_rel) + 1;
+            subtree_path + strlen(target_repos_relpath) + 1;
 
           SVN_ERR(svn_mergeinfo__add_suffix_to_mergeinfo(
             &subtree_source_history, source_history,
@@ -2075,7 +2066,8 @@ svn_client_mergeinfo_log2(svn_boolean_t 
                                        finding_merged,
                                        master_inheritable_rangelist,
                                        target_mergeinfo_cat,
-                                       svn_fspath__join("/", target_repos_rel,
+                                       svn_fspath__join("/",
+                                                        target_repos_relpath,
                                                         scratch_pool),
                                        discover_changed_paths,
                                        revprops,

Modified: subversion/branches/fsfs-format7/subversion/libsvn_client/ra.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_client/ra.c?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_client/ra.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_client/ra.c Wed Feb 13 06:37:54 2013
@@ -324,7 +324,8 @@ svn_client__open_ra_session_internal(svn
 
   if (base_dir_abspath)
     {
-      svn_error_t *err = svn_wc__node_get_repos_info(NULL, &uuid, ctx->wc_ctx,
+      svn_error_t *err = svn_wc__node_get_repos_info(NULL, NULL, NULL, &uuid,
+                                                     ctx->wc_ctx,
                                                      base_dir_abspath,
                                                      pool, pool);
 

Modified: subversion/branches/fsfs-format7/subversion/libsvn_client/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_client/util.c?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_client/util.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_client/util.c Wed Feb 13 06:37:54 2013
@@ -183,6 +183,7 @@ svn_client__wc_node_get_base(svn_client_
                                 &relpath,
                                 &(*base_p)->repos_root_url,
                                 &(*base_p)->repos_uuid,
+                                NULL,
                                 wc_ctx, wc_abspath,
                                 result_pool, scratch_pool));
   if ((*base_p)->repos_root_url && relpath)
@@ -241,10 +242,23 @@ svn_client_get_repos_root(const char **r
   /* If PATH_OR_URL is a local path we can fetch the repos root locally. */
   if (!svn_path_is_url(abspath_or_url))
     {
-      SVN_ERR(svn_wc__node_get_repos_info(repos_root, repos_uuid,
-                                          ctx->wc_ctx, abspath_or_url,
-                                          result_pool, scratch_pool));
-
+      svn_error_t *err;
+      err = svn_wc__node_get_repos_info(NULL, NULL, repos_root, repos_uuid,
+                                        ctx->wc_ctx, abspath_or_url,
+                                        result_pool, scratch_pool);
+
+      if (err)
+        {
+          if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND
+              && err->apr_err != SVN_ERR_WC_NOT_WORKING_COPY)
+            return svn_error_trace(err);
+
+          svn_error_clear(err);
+          if (repos_root)
+            *repos_root = NULL;
+          if (repos_uuid)
+            *repos_uuid = NULL;
+        }
       return SVN_NO_ERROR;
     }
 

Modified: subversion/branches/fsfs-format7/subversion/libsvn_diff/diff_tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_diff/diff_tree.c?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_diff/diff_tree.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_diff/diff_tree.c Wed Feb 13 06:37:54 2013
@@ -25,6 +25,8 @@
 #include <apr_pools.h>
 #include <apr_general.h>
 
+#include <assert.h>
+
 #include "svn_dirent_uri.h"
 #include "svn_error.h"
 #include "svn_pools.h"
@@ -538,7 +540,7 @@ reverse_node_absent(const char *relpath,
 
   SVN_ERR(rb->processor->node_absent(relpath,
                                     dir_baton,
-                                    processor,
+                                    rb->processor,
                                     scratch_pool));
   return SVN_NO_ERROR;
 }
@@ -576,6 +578,691 @@ svn_diff__tree_processor_reverse_create(
   return reverse;
 }
 
+struct filter_tree_baton_t
+{
+  const svn_diff_tree_processor_t *processor;
+  const char *prefix_relpath;
+};
+
+static svn_error_t *
+filter_dir_opened(void **new_dir_baton,
+                  svn_boolean_t *skip,
+                  svn_boolean_t *skip_children,
+                  const char *relpath,
+                  const svn_diff_source_t *left_source,
+                  const svn_diff_source_t *right_source,
+                  const svn_diff_source_t *copyfrom_source,
+                  void *parent_dir_baton,
+                  const svn_diff_tree_processor_t *processor,
+                  apr_pool_t *result_pool,
+                  apr_pool_t *scratch_pool)
+{
+  struct filter_tree_baton_t *fb = processor->baton;
+
+  relpath = svn_relpath_skip_ancestor(fb->prefix_relpath, relpath);
+
+  if (! relpath)
+    {
+      /* Skip work for this, but NOT for DESCENDANTS */
+      *skip = TRUE;
+      return SVN_NO_ERROR;
+    }
+
+  SVN_ERR(fb->processor->dir_opened(new_dir_baton, skip, skip_children,
+                                    relpath,
+                                    left_source, right_source,
+                                    copyfrom_source,
+                                    parent_dir_baton,
+                                    fb->processor,
+                                    result_pool, scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+filter_dir_added(const char *relpath,
+                 const svn_diff_source_t *copyfrom_source,
+                 const svn_diff_source_t *right_source,
+                 /*const*/ apr_hash_t *copyfrom_props,
+                 /*const*/ apr_hash_t *right_props,
+                 void *dir_baton,
+                 const svn_diff_tree_processor_t *processor,
+                 apr_pool_t *scratch_pool)
+{
+  struct filter_tree_baton_t *fb = processor->baton;
+
+  relpath = svn_relpath_skip_ancestor(fb->prefix_relpath, relpath);
+  assert(relpath != NULL); /* Driver error */
+
+  SVN_ERR(fb->processor->dir_added(relpath,
+                                   copyfrom_source,
+                                   right_source,
+                                   copyfrom_props,
+                                   right_props,
+                                   dir_baton,
+                                   fb->processor,
+                                   scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+filter_dir_deleted(const char *relpath,
+                   const svn_diff_source_t *left_source,
+                   /*const*/ apr_hash_t *left_props,
+                   void *dir_baton,
+                   const svn_diff_tree_processor_t *processor,
+                   apr_pool_t *scratch_pool)
+{
+  struct filter_tree_baton_t *fb = processor->baton;
+
+  relpath = svn_relpath_skip_ancestor(fb->prefix_relpath, relpath);
+  assert(relpath != NULL); /* Driver error */
+
+  SVN_ERR(fb->processor->dir_deleted(relpath,
+                                     left_source,
+                                     left_props,
+                                     dir_baton,
+                                     fb->processor,
+                                     scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+filter_dir_changed(const char *relpath,
+                   const svn_diff_source_t *left_source,
+                   const svn_diff_source_t *right_source,
+                   /*const*/ apr_hash_t *left_props,
+                   /*const*/ apr_hash_t *right_props,
+                   const apr_array_header_t *prop_changes,
+                   void *dir_baton,
+                   const struct svn_diff_tree_processor_t *processor,
+                   apr_pool_t *scratch_pool)
+{
+  struct filter_tree_baton_t *fb = processor->baton;
+
+  relpath = svn_relpath_skip_ancestor(fb->prefix_relpath, relpath);
+  assert(relpath != NULL); /* Driver error */
+
+  SVN_ERR(fb->processor->dir_changed(relpath,
+                                     left_source,
+                                     right_source,
+                                     left_props,
+                                     right_props,
+                                     prop_changes,
+                                     dir_baton,
+                                     fb->processor,
+                                     scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+filter_dir_closed(const char *relpath,
+                  const svn_diff_source_t *left_source,
+                  const svn_diff_source_t *right_source,
+                  void *dir_baton,
+                  const svn_diff_tree_processor_t *processor,
+                  apr_pool_t *scratch_pool)
+{
+  struct filter_tree_baton_t *fb = processor->baton;
+
+  relpath = svn_relpath_skip_ancestor(fb->prefix_relpath, relpath);
+  assert(relpath != NULL); /* Driver error */
+
+  SVN_ERR(fb->processor->dir_closed(relpath,
+                                    left_source,
+                                    right_source,
+                                    dir_baton,
+                                    fb->processor,
+                                    scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+filter_file_opened(void **new_file_baton,
+                   svn_boolean_t *skip,
+                   const char *relpath,
+                   const svn_diff_source_t *left_source,
+                   const svn_diff_source_t *right_source,
+                   const svn_diff_source_t *copyfrom_source,
+                   void *dir_baton,
+                   const svn_diff_tree_processor_t *processor,
+                   apr_pool_t *result_pool,
+                   apr_pool_t *scratch_pool)
+{
+  struct filter_tree_baton_t *fb = processor->baton;
+
+  relpath = svn_relpath_skip_ancestor(fb->prefix_relpath, relpath);
+
+  if (! relpath)
+    {
+      *skip = TRUE;
+      return SVN_NO_ERROR;
+    }
+
+  SVN_ERR(fb->processor->file_opened(new_file_baton,
+                                     skip,
+                                     relpath,
+                                     left_source,
+                                     right_source,
+                                     copyfrom_source,
+                                     dir_baton,
+                                     fb->processor,
+                                     result_pool,
+                                     scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+filter_file_added(const char *relpath,
+                  const svn_diff_source_t *copyfrom_source,
+                  const svn_diff_source_t *right_source,
+                  const char *copyfrom_file,
+                  const char *right_file,
+                  /*const*/ apr_hash_t *copyfrom_props,
+                  /*const*/ apr_hash_t *right_props,
+                  void *file_baton,
+                  const svn_diff_tree_processor_t *processor,
+                  apr_pool_t *scratch_pool)
+{
+  struct filter_tree_baton_t *fb = processor->baton;
+
+  relpath = svn_relpath_skip_ancestor(fb->prefix_relpath, relpath);
+  assert(relpath != NULL); /* Driver error */
+
+  SVN_ERR(fb->processor->file_added(relpath,
+                                    copyfrom_source,
+                                    right_source,
+                                    copyfrom_file,
+                                    right_file,
+                                    copyfrom_props,
+                                    right_props,
+                                    file_baton,
+                                    fb->processor,
+                                    scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+filter_file_deleted(const char *relpath,
+                    const svn_diff_source_t *left_source,
+                    const char *left_file,
+                    /*const*/ apr_hash_t *left_props,
+                    void *file_baton,
+                    const svn_diff_tree_processor_t *processor,
+                    apr_pool_t *scratch_pool)
+{
+  struct filter_tree_baton_t *fb = processor->baton;
+
+  relpath = svn_relpath_skip_ancestor(fb->prefix_relpath, relpath);
+  assert(relpath != NULL); /* Driver error */
+
+  SVN_ERR(fb->processor->file_deleted(relpath,
+                                      left_source,
+                                      left_file,
+                                      left_props,
+                                      file_baton,
+                                      fb->processor,
+                                      scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+filter_file_changed(const char *relpath,
+                    const svn_diff_source_t *left_source,
+                    const svn_diff_source_t *right_source,
+                    const char *left_file,
+                    const char *right_file,
+                    /*const*/ apr_hash_t *left_props,
+                    /*const*/ apr_hash_t *right_props,
+                    svn_boolean_t file_modified,
+                    const apr_array_header_t *prop_changes,
+                    void *file_baton,
+                    const svn_diff_tree_processor_t *processor,
+                    apr_pool_t *scratch_pool)
+{
+  struct filter_tree_baton_t *fb = processor->baton;
+
+  relpath = svn_relpath_skip_ancestor(fb->prefix_relpath, relpath);
+  assert(relpath != NULL); /* Driver error */
+
+  SVN_ERR(fb->processor->file_changed(relpath,
+                                      left_source,
+                                      right_source,
+                                      left_file,
+                                      right_file,
+                                      left_props,
+                                      right_props,
+                                      file_modified,
+                                      prop_changes,
+                                      file_baton,
+                                      fb->processor,
+                                      scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+filter_file_closed(const char *relpath,
+                   const svn_diff_source_t *left_source,
+                   const svn_diff_source_t *right_source,
+                   void *file_baton,
+                   const svn_diff_tree_processor_t *processor,
+                   apr_pool_t *scratch_pool)
+{
+  struct filter_tree_baton_t *fb = processor->baton;
+
+  relpath = svn_relpath_skip_ancestor(fb->prefix_relpath, relpath);
+  assert(relpath != NULL); /* Driver error */
+
+  SVN_ERR(fb->processor->file_closed(relpath,
+                                     left_source,
+                                     right_source,
+                                     file_baton,
+                                     fb->processor,
+                                     scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+filter_node_absent(const char *relpath,
+                   void *dir_baton,
+                   const svn_diff_tree_processor_t *processor,
+                   apr_pool_t *scratch_pool)
+{
+  struct filter_tree_baton_t *fb = processor->baton;
+
+  relpath = svn_relpath_skip_ancestor(fb->prefix_relpath, relpath);
+  assert(relpath != NULL); /* Driver error */
+
+  SVN_ERR(fb->processor->node_absent(relpath,
+                                    dir_baton,
+                                    fb->processor,
+                                    scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+
+const svn_diff_tree_processor_t *
+svn_diff__tree_processor_filter_create(const svn_diff_tree_processor_t * processor,
+                                        const char *prefix_relpath,
+                                        apr_pool_t *result_pool)
+{
+  struct filter_tree_baton_t *fb;
+  svn_diff_tree_processor_t *filter;
+
+  fb = apr_pcalloc(result_pool, sizeof(*fb));
+  fb->processor = processor;
+  if (prefix_relpath)
+    fb->prefix_relpath = apr_pstrdup(result_pool, prefix_relpath);
+
+  filter = svn_diff__tree_processor_create(fb, result_pool);
+
+  filter->dir_opened   = filter_dir_opened;
+  filter->dir_added    = filter_dir_added;
+  filter->dir_deleted  = filter_dir_deleted;
+  filter->dir_changed  = filter_dir_changed;
+  filter->dir_closed   = filter_dir_closed;
+
+  filter->file_opened   = filter_file_opened;
+  filter->file_added    = filter_file_added;
+  filter->file_deleted  = filter_file_deleted;
+  filter->file_changed  = filter_file_changed;
+  filter->file_closed   = filter_file_closed;
+
+  filter->node_absent   = filter_node_absent;
+
+  return filter;
+}
+
+struct copy_as_changed_baton_t
+{
+  const svn_diff_tree_processor_t *processor;
+};
+
+static svn_error_t *
+copy_as_changed_dir_opened(void **new_dir_baton,
+                           svn_boolean_t *skip,
+                           svn_boolean_t *skip_children,
+                           const char *relpath,
+                           const svn_diff_source_t *left_source,
+                           const svn_diff_source_t *right_source,
+                           const svn_diff_source_t *copyfrom_source,
+                           void *parent_dir_baton,
+                           const svn_diff_tree_processor_t *processor,
+                           apr_pool_t *result_pool,
+                           apr_pool_t *scratch_pool)
+{
+  struct copy_as_changed_baton_t *cb = processor->baton;
+
+  if (!left_source && copyfrom_source)
+    {
+      assert(right_source != NULL);
+
+      left_source = copyfrom_source;
+      copyfrom_source = NULL;
+    }
+
+  SVN_ERR(cb->processor->dir_opened(new_dir_baton, skip, skip_children,
+                                    relpath,
+                                    left_source, right_source,
+                                    copyfrom_source,
+                                    parent_dir_baton,
+                                    cb->processor,
+                                    result_pool, scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+copy_as_changed_dir_added(const char *relpath,
+                          const svn_diff_source_t *copyfrom_source,
+                          const svn_diff_source_t *right_source,
+                          /*const*/ apr_hash_t *copyfrom_props,
+                          /*const*/ apr_hash_t *right_props,
+                          void *dir_baton,
+                          const svn_diff_tree_processor_t *processor,
+                          apr_pool_t *scratch_pool)
+{
+  struct copy_as_changed_baton_t *cb = processor->baton;
+
+  if (copyfrom_source)
+    {
+      apr_array_header_t *propchanges;
+      SVN_ERR(svn_prop_diffs(&propchanges, right_props, copyfrom_props,
+                             scratch_pool));
+      SVN_ERR(cb->processor->dir_changed(relpath,
+                                         copyfrom_source,
+                                         right_source,
+                                         copyfrom_props,
+                                         right_props,
+                                         propchanges,
+                                         dir_baton,
+                                         cb->processor,
+                                         scratch_pool));
+    }
+  else
+    {
+      SVN_ERR(cb->processor->dir_added(relpath,
+                                       copyfrom_source,
+                                       right_source,
+                                       copyfrom_props,
+                                       right_props,
+                                       dir_baton,
+                                       cb->processor,
+                                       scratch_pool));
+    }
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+copy_as_changed_dir_deleted(const char *relpath,
+                            const svn_diff_source_t *left_source,
+                            /*const*/ apr_hash_t *left_props,
+                            void *dir_baton,
+                            const svn_diff_tree_processor_t *processor,
+                            apr_pool_t *scratch_pool)
+{
+  struct copy_as_changed_baton_t *cb = processor->baton;
+
+  SVN_ERR(cb->processor->dir_deleted(relpath,
+                                     left_source,
+                                     left_props,
+                                     dir_baton,
+                                     cb->processor,
+                                     scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+copy_as_changed_dir_changed(const char *relpath,
+                            const svn_diff_source_t *left_source,
+                            const svn_diff_source_t *right_source,
+                            /*const*/ apr_hash_t *left_props,
+                            /*const*/ apr_hash_t *right_props,
+                            const apr_array_header_t *prop_changes,
+                            void *dir_baton,
+                            const struct svn_diff_tree_processor_t *processor,
+                            apr_pool_t *scratch_pool)
+{
+  struct copy_as_changed_baton_t *cb = processor->baton;
+
+  SVN_ERR(cb->processor->dir_changed(relpath,
+                                     left_source,
+                                     right_source,
+                                     left_props,
+                                     right_props,
+                                     prop_changes,
+                                     dir_baton,
+                                     cb->processor,
+                                     scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+copy_as_changed_dir_closed(const char *relpath,
+                           const svn_diff_source_t *left_source,
+                           const svn_diff_source_t *right_source,
+                           void *dir_baton,
+                           const svn_diff_tree_processor_t *processor,
+                           apr_pool_t *scratch_pool)
+{
+  struct copy_as_changed_baton_t *cb = processor->baton;
+
+  SVN_ERR(cb->processor->dir_closed(relpath,
+                                    left_source,
+                                    right_source,
+                                    dir_baton,
+                                    cb->processor,
+                                    scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+copy_as_changed_file_opened(void **new_file_baton,
+                            svn_boolean_t *skip,
+                            const char *relpath,
+                            const svn_diff_source_t *left_source,
+                            const svn_diff_source_t *right_source,
+                            const svn_diff_source_t *copyfrom_source,
+                            void *dir_baton,
+                            const svn_diff_tree_processor_t *processor,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool)
+{
+  struct copy_as_changed_baton_t *cb = processor->baton;
+
+  if (!left_source && copyfrom_source)
+    {
+      assert(right_source != NULL);
+
+      left_source = copyfrom_source;
+      copyfrom_source = NULL;
+    }
+
+  SVN_ERR(cb->processor->file_opened(new_file_baton,
+                                     skip,
+                                     relpath,
+                                     left_source,
+                                     right_source,
+                                     copyfrom_source,
+                                     dir_baton,
+                                     cb->processor,
+                                     result_pool,
+                                     scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+copy_as_changed_file_added(const char *relpath,
+                           const svn_diff_source_t *copyfrom_source,
+                           const svn_diff_source_t *right_source,
+                           const char *copyfrom_file,
+                           const char *right_file,
+                           /*const*/ apr_hash_t *copyfrom_props,
+                           /*const*/ apr_hash_t *right_props,
+                           void *file_baton,
+                           const svn_diff_tree_processor_t *processor,
+                           apr_pool_t *scratch_pool)
+{
+  struct copy_as_changed_baton_t *cb = processor->baton;
+
+  if (copyfrom_source)
+    {
+      apr_array_header_t *propchanges;
+      SVN_ERR(svn_prop_diffs(&propchanges, right_props, copyfrom_props,
+                             scratch_pool));
+
+      SVN_ERR(cb->processor->file_changed(relpath,
+                                          copyfrom_source,
+                                          right_source,
+                                          copyfrom_file,
+                                          right_file,
+                                          copyfrom_props,
+                                          right_props,
+                                          copyfrom_file && right_file,
+                                          propchanges,
+                                          file_baton,
+                                          cb->processor,
+                                          scratch_pool));
+    }
+  else
+    {
+      SVN_ERR(cb->processor->file_added(relpath,
+                                        copyfrom_source,
+                                        right_source,
+                                        copyfrom_file,
+                                        right_file,
+                                        copyfrom_props,
+                                        right_props,
+                                        file_baton,
+                                        cb->processor,
+                                        scratch_pool));
+    }
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+copy_as_changed_file_deleted(const char *relpath,
+                             const svn_diff_source_t *left_source,
+                             const char *left_file,
+                             /*const*/ apr_hash_t *left_props,
+                             void *file_baton,
+                             const svn_diff_tree_processor_t *processor,
+                             apr_pool_t *scratch_pool)
+{
+  struct copy_as_changed_baton_t *cb = processor->baton;
+
+  SVN_ERR(cb->processor->file_deleted(relpath,
+                                      left_source,
+                                      left_file,
+                                      left_props,
+                                      file_baton,
+                                      cb->processor,
+                                      scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+copy_as_changed_file_changed(const char *relpath,
+                             const svn_diff_source_t *left_source,
+                             const svn_diff_source_t *right_source,
+                             const char *left_file,
+                             const char *right_file,
+                             /*const*/ apr_hash_t *left_props,
+                             /*const*/ apr_hash_t *right_props,
+                             svn_boolean_t file_modified,
+                             const apr_array_header_t *prop_changes,
+                             void *file_baton,
+                             const svn_diff_tree_processor_t *processor,
+                             apr_pool_t *scratch_pool)
+{
+  struct copy_as_changed_baton_t *cb = processor->baton;
+
+  SVN_ERR(cb->processor->file_changed(relpath,
+                                      left_source,
+                                      right_source,
+                                      left_file,
+                                      right_file,
+                                      left_props,
+                                      right_props,
+                                      file_modified,
+                                      prop_changes,
+                                      file_baton,
+                                      cb->processor,
+                                      scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+copy_as_changed_file_closed(const char *relpath,
+                            const svn_diff_source_t *left_source,
+                            const svn_diff_source_t *right_source,
+                            void *file_baton,
+                            const svn_diff_tree_processor_t *processor,
+                            apr_pool_t *scratch_pool)
+{
+  struct copy_as_changed_baton_t *cb = processor->baton;
+
+  SVN_ERR(cb->processor->file_closed(relpath,
+                                     left_source,
+                                     right_source,
+                                     file_baton,
+                                     cb->processor,
+                                     scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+copy_as_changed_node_absent(const char *relpath,
+                            void *dir_baton,
+                            const svn_diff_tree_processor_t *processor,
+                            apr_pool_t *scratch_pool)
+{
+  struct copy_as_changed_baton_t *cb = processor->baton;
+
+  SVN_ERR(cb->processor->node_absent(relpath,
+                                    dir_baton,
+                                    cb->processor,
+                                    scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+
+const svn_diff_tree_processor_t *
+svn_diff__tree_processor_copy_as_changed_create(
+                        const svn_diff_tree_processor_t * processor,
+                        apr_pool_t *result_pool)
+{
+  struct copy_as_changed_baton_t *cb;
+  svn_diff_tree_processor_t *filter;
+
+  cb = apr_pcalloc(result_pool, sizeof(*cb));
+  cb->processor = processor;
+
+  filter = svn_diff__tree_processor_create(cb, result_pool);
+  filter->dir_opened   = copy_as_changed_dir_opened;
+  filter->dir_added    = copy_as_changed_dir_added;
+  filter->dir_deleted  = copy_as_changed_dir_deleted;
+  filter->dir_changed  = copy_as_changed_dir_changed;
+  filter->dir_closed   = copy_as_changed_dir_closed;
+
+  filter->file_opened   = copy_as_changed_file_opened;
+  filter->file_added    = copy_as_changed_file_added;
+  filter->file_deleted  = copy_as_changed_file_deleted;
+  filter->file_changed  = copy_as_changed_file_changed;
+  filter->file_closed   = copy_as_changed_file_closed;
+
+  filter->node_absent   = copy_as_changed_node_absent;
+
+  return filter;
+}
+
+
 /* Processor baton for the tee tree processor */
 struct tee_baton_t
 {

Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/commit.c?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/commit.c Wed Feb 13 06:37:54 2013
@@ -289,6 +289,8 @@ checkout_node(const char **working_url,
               apr_pool_t *scratch_pool)
 {
   svn_ra_serf__handler_t handler = { 0 };
+  apr_status_t status;
+  apr_uri_t uri;
 
   /* HANDLER_POOL is the scratch pool since we don't need to remember
      anything from the handler. We just want the working resource.  */
@@ -315,7 +317,17 @@ checkout_node(const char **working_url,
     return svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
                             _("No Location header received"));
 
-  *working_url = apr_pstrdup(result_pool, handler.location);
+  /* We only want the path portion of the Location header.
+     (code.google.com sometimes returns an 'http:' scheme for an
+     'https:' transaction ... we'll work around that by stripping the
+     scheme, host, and port here and re-adding the correct ones
+     later.  */
+  status = apr_uri_parse(scratch_pool, handler.location, &uri);
+  if (status)
+    return svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
+                            _("Error parsing Location header value"));
+
+  *working_url = svn_urlpath__canonicalize(uri.path, result_pool);
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/options.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/options.c?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/options.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/options.c Wed Feb 13 06:37:54 2013
@@ -28,6 +28,7 @@
 #include <serf.h>
 
 #include "svn_dirent_uri.h"
+#include "svn_hash.h"
 #include "svn_pools.h"
 #include "svn_ra.h"
 #include "svn_dav.h"
@@ -169,47 +170,40 @@ capabilities_headers_iterator_callback(v
 
       if (svn_cstring_match_list(SVN_DAV_NS_DAV_SVN_DEPTH, vals))
         {
-          apr_hash_set(session->capabilities,
-                       SVN_RA_CAPABILITY_DEPTH, APR_HASH_KEY_STRING,
-                       capability_yes);
+          svn_hash_sets(session->capabilities,
+                        SVN_RA_CAPABILITY_DEPTH, capability_yes);
         }
       if (svn_cstring_match_list(SVN_DAV_NS_DAV_SVN_MERGEINFO, vals))
         {
           /* The server doesn't know what repository we're referring
              to, so it can't just say capability_yes. */
-          apr_hash_set(session->capabilities,
-                       SVN_RA_CAPABILITY_MERGEINFO, APR_HASH_KEY_STRING,
-                       capability_server_yes);
+          svn_hash_sets(session->capabilities,
+                        SVN_RA_CAPABILITY_MERGEINFO, capability_server_yes);
         }
       if (svn_cstring_match_list(SVN_DAV_NS_DAV_SVN_LOG_REVPROPS, vals))
         {
-          apr_hash_set(session->capabilities,
-                       SVN_RA_CAPABILITY_LOG_REVPROPS, APR_HASH_KEY_STRING,
-                       capability_yes);
+          svn_hash_sets(session->capabilities,
+                        SVN_RA_CAPABILITY_LOG_REVPROPS, capability_yes);
         }
       if (svn_cstring_match_list(SVN_DAV_NS_DAV_SVN_ATOMIC_REVPROPS, vals))
         {
-          apr_hash_set(session->capabilities,
-                       SVN_RA_CAPABILITY_ATOMIC_REVPROPS, APR_HASH_KEY_STRING,
-                       capability_yes);
+          svn_hash_sets(session->capabilities,
+                        SVN_RA_CAPABILITY_ATOMIC_REVPROPS, capability_yes);
         }
       if (svn_cstring_match_list(SVN_DAV_NS_DAV_SVN_PARTIAL_REPLAY, vals))
         {
-          apr_hash_set(session->capabilities,
-                       SVN_RA_CAPABILITY_PARTIAL_REPLAY, APR_HASH_KEY_STRING,
-                       capability_yes);
+          svn_hash_sets(session->capabilities,
+                        SVN_RA_CAPABILITY_PARTIAL_REPLAY, capability_yes);
         }
       if (svn_cstring_match_list(SVN_DAV_NS_DAV_SVN_INHERITED_PROPS, vals))
         {
-          apr_hash_set(session->capabilities,
-                       SVN_RA_CAPABILITY_INHERITED_PROPS,
-                       APR_HASH_KEY_STRING, capability_yes);
+          svn_hash_sets(session->capabilities,
+                        SVN_RA_CAPABILITY_INHERITED_PROPS, capability_yes);
         }
       if (svn_cstring_match_list(SVN_DAV_NS_DAV_SVN_EPHEMERAL_TXNPROPS, vals))
         {
-          apr_hash_set(session->capabilities,
-                       SVN_RA_CAPABILITY_EPHEMERAL_TXNPROPS, APR_HASH_KEY_STRING,
-                       capability_yes);
+          svn_hash_sets(session->capabilities,
+                        SVN_RA_CAPABILITY_EPHEMERAL_TXNPROPS, capability_yes);
         }
       if (svn_cstring_match_list(SVN_DAV_NS_DAV_SVN_INLINE_PROPS, vals))
         {
@@ -303,8 +297,7 @@ capabilities_headers_iterator_callback(v
             {
               const char *post_val = APR_ARRAY_IDX(vals, i, const char *);
 
-              apr_hash_set(session->supported_posts, post_val,
-                           APR_HASH_KEY_STRING, (void *)1);
+              svn_hash_sets(session->supported_posts, post_val, (void *)1);
             }
         }
     }
@@ -331,20 +324,20 @@ options_response_handler(serf_request_t 
       serf_bucket_t *hdrs = serf_bucket_response_get_headers(response);
 
       /* Start out assuming all capabilities are unsupported. */
-      apr_hash_set(session->capabilities, SVN_RA_CAPABILITY_PARTIAL_REPLAY,
-                   APR_HASH_KEY_STRING, capability_no);
-      apr_hash_set(session->capabilities, SVN_RA_CAPABILITY_DEPTH,
-                   APR_HASH_KEY_STRING, capability_no);
-      apr_hash_set(session->capabilities, SVN_RA_CAPABILITY_MERGEINFO,
-                   APR_HASH_KEY_STRING, capability_no);
-      apr_hash_set(session->capabilities, SVN_RA_CAPABILITY_LOG_REVPROPS,
-                   APR_HASH_KEY_STRING, capability_no);
-      apr_hash_set(session->capabilities, SVN_RA_CAPABILITY_ATOMIC_REVPROPS,
-                   APR_HASH_KEY_STRING, capability_no);
-      apr_hash_set(session->capabilities, SVN_RA_CAPABILITY_INHERITED_PROPS,
-                   APR_HASH_KEY_STRING, capability_no);
-      apr_hash_set(session->capabilities, SVN_RA_CAPABILITY_EPHEMERAL_TXNPROPS,
-                   APR_HASH_KEY_STRING, capability_no);
+      svn_hash_sets(session->capabilities, SVN_RA_CAPABILITY_PARTIAL_REPLAY,
+                    capability_no);
+      svn_hash_sets(session->capabilities, SVN_RA_CAPABILITY_DEPTH,
+                    capability_no);
+      svn_hash_sets(session->capabilities, SVN_RA_CAPABILITY_MERGEINFO,
+                    capability_no);
+      svn_hash_sets(session->capabilities, SVN_RA_CAPABILITY_LOG_REVPROPS,
+                    capability_no);
+      svn_hash_sets(session->capabilities, SVN_RA_CAPABILITY_ATOMIC_REVPROPS,
+                    capability_no);
+      svn_hash_sets(session->capabilities, SVN_RA_CAPABILITY_INHERITED_PROPS,
+                    capability_no);
+      svn_hash_sets(session->capabilities, SVN_RA_CAPABILITY_EPHEMERAL_TXNPROPS,
+                    capability_no);
 
       /* Then see which ones we can discover. */
       serf_bucket_headers_do(hdrs, capabilities_headers_iterator_callback,
@@ -548,9 +541,8 @@ svn_ra_serf__has_capability(svn_ra_sessi
           else
             cap_result = capability_yes;
 
-          apr_hash_set(serf_sess->capabilities,
-                       SVN_RA_CAPABILITY_MERGEINFO, APR_HASH_KEY_STRING,
-                       cap_result);
+          svn_hash_sets(serf_sess->capabilities,
+                        SVN_RA_CAPABILITY_MERGEINFO,  cap_result);
         }
       else
         {

Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/property.c?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/property.c Wed Feb 13 06:37:54 2013
@@ -637,7 +637,7 @@ svn_ra_serf__wait_for_props(svn_ra_serf_
 
   err2 = svn_ra_serf__error_on_status(handler->sline.code,
                                       handler->path,
-                                      NULL);
+                                      handler->location);
   if (err2)
     {
       svn_error_clear(err);

Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/util.c?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/util.c Wed Feb 13 06:37:54 2013
@@ -41,6 +41,7 @@
 #include "svn_string.h"
 #include "svn_xml.h"
 #include "svn_props.h"
+#include "svn_dirent_uri.h"
 
 #include "../libsvn_ra/ra_loader.h"
 #include "private/svn_dep_compat.h"
@@ -987,27 +988,51 @@ svn_ra_serf__response_discard_handler(se
 
 
 /* Return the value of the RESPONSE's Location header if any, or NULL
-   otherwise.  All allocations will be made in POOL.  */
+   otherwise.  */
 static const char *
 response_get_location(serf_bucket_t *response,
-                      apr_pool_t *pool)
+                      const char *base_url,
+                      apr_pool_t *result_pool,
+                      apr_pool_t *scratch_pool)
 {
   serf_bucket_t *headers;
   const char *location;
-  apr_status_t status;
-  apr_uri_t uri;
 
   headers = serf_bucket_response_get_headers(response);
   location = serf_bucket_headers_get(headers, "Location");
   if (location == NULL)
     return NULL;
 
-  /* Ignore the scheme/host/port. Or just return as-is if we can't parse.  */
-  status = apr_uri_parse(pool, location, &uri);
-  if (!status)
-    location = uri.path;
+  /* The RFCs say we should have received a full url in LOCATION, but
+     older apache versions and many custom web handlers just return a
+     relative path here...
+
+     And we can't trust anything because it is network data.
+   */
+  if (*location == '/')
+    {
+      apr_uri_t uri;
+      apr_status_t status;
+
+      status = apr_uri_parse(scratch_pool, base_url, &uri);
+
+      if (status != APR_SUCCESS)
+        return NULL;
+
+      /* Replace the path path with what we got */
+      uri.path = (char*)svn_urlpath__canonicalize(location, scratch_pool);
+
+      /* And make APR produce a proper full url for us */
+      location = apr_uri_unparse(scratch_pool, &uri, 0);
+
+      /* Fall through to ensure our canonicalization rules */
+    }
+  else if (!svn_path_is_url(location))
+    {
+      return NULL; /* Any other formats we should support? */
+    }
 
-  return svn_urlpath__canonicalize(location, pool);
+  return svn_uri_canonicalize(location, result_pool);
 }
 
 
@@ -1896,7 +1921,10 @@ handle_response(serf_request_t *request,
     }
 
   /* ... and set up the header fields in HANDLER.  */
-  handler->location = response_get_location(response, handler->handler_pool);
+  handler->location = response_get_location(response,
+                                            handler->session->session_url_str,
+                                            handler->handler_pool,
+                                            scratch_pool);
 
   /* On the last request, we failed authentication. We succeeded this time,
      so let's save away these credentials.  */

Modified: subversion/branches/fsfs-format7/subversion/libsvn_repos/reporter.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_repos/reporter.c?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_repos/reporter.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_repos/reporter.c Wed Feb 13 06:37:54 2013
@@ -687,18 +687,13 @@ delta_files(report_baton_t *b, void *fil
     {
       SVN_ERR(get_source_root(b, &s_root, s_rev));
 
-      /* Is this delta calculation worth our time?  If we are ignoring
-         ancestry, then our editor implementor isn't concerned by the
-         theoretical differences between "has contents which have not
-         changed with respect to" and "has the same actual contents
-         as".  We'll do everything we can to avoid transmitting even
-         an empty text-delta in that case.  */
-      if (b->ignore_ancestry)
-        SVN_ERR(svn_repos__compare_files(&changed, b->t_root, t_path,
-                                         s_root, s_path, pool));
-      else
-        SVN_ERR(svn_fs_contents_changed(&changed, b->t_root, t_path, s_root,
-                                        s_path, pool));
+      /* We're not interested in the theoretical difference between "has
+         contents which have not changed with respect to" and "has the same
+         actual contents as" when sending text-deltas.  If we know the
+         delta is an empty one, we avoiding sending it in either case. */
+      SVN_ERR(svn_repos__compare_files(&changed, b->t_root, t_path,
+                                       s_root, s_path, pool));
+
       if (!changed)
         return SVN_NO_ERROR;
 

Modified: subversion/branches/fsfs-format7/subversion/libsvn_subr/auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_subr/auth.c?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_subr/auth.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_subr/auth.c Wed Feb 13 06:37:54 2013
@@ -35,6 +35,8 @@
 #include "svn_dso.h"
 #include "svn_version.h"
 
+#include "auth.h"
+
 /* AN OVERVIEW
    ===========
 
@@ -619,3 +621,20 @@ svn_auth_get_platform_specific_client_pr
 
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_auth_cleanup_walk(svn_auth_baton_t *baton,
+                      svn_auth_cleanup_callback cleanup,
+                      void *cleanup_baton,
+                      apr_pool_t *scratch_pool)
+{
+
+  if (apr_hash_get(baton->tables, SVN_AUTH_CRED_SIMPLE, APR_HASH_KEY_STRING))
+    {
+      SVN_ERR(svn_auth__simple_cleanup_walk(baton, cleanup, cleanup_baton,
+                                            baton->creds_cache, scratch_pool));
+    }
+  /* ### Maybe add support for other providers? */
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/fsfs-format7/subversion/libsvn_subr/config_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_subr/config_auth.c?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_subr/config_auth.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_subr/config_auth.c Wed Feb 13 06:37:54 2013
@@ -29,18 +29,20 @@
 
 #include "config_impl.h"
 
+#include "auth.h"
+
 #include "svn_private_config.h"
 
 /* Helper for svn_config_{read|write}_auth_data.  Return a path to a
    file within ~/.subversion/auth/ that holds CRED_KIND credentials
    within REALMSTRING.  If no path is available *PATH will be set to
    NULL. */
-static svn_error_t *
-auth_file_path(const char **path,
-               const char *cred_kind,
-               const char *realmstring,
-               const char *config_dir,
-               apr_pool_t *pool)
+svn_error_t *
+svn_auth__file_path(const char **path,
+                    const char *cred_kind,
+                    const char *realmstring,
+                    const char *config_dir,
+                    apr_pool_t *pool)
 {
   const char *authdir_path, *hexname;
   svn_checksum_t *checksum;
@@ -81,8 +83,8 @@ svn_config_read_auth_data(apr_hash_t **h
 
   *hash = NULL;
 
-  SVN_ERR(auth_file_path(&auth_path, cred_kind, realmstring, config_dir,
-                         pool));
+  SVN_ERR(svn_auth__file_path(&auth_path, cred_kind, realmstring, config_dir,
+                              pool));
   if (! auth_path)
     return SVN_NO_ERROR;
 
@@ -118,8 +120,8 @@ svn_config_write_auth_data(apr_hash_t *h
   svn_stream_t *stream;
   const char *auth_path;
 
-  SVN_ERR(auth_file_path(&auth_path, cred_kind, realmstring, config_dir,
-                         pool));
+  SVN_ERR(svn_auth__file_path(&auth_path, cred_kind, realmstring, config_dir,
+                              pool));
   if (! auth_path)
     return svn_error_create(SVN_ERR_NO_AUTH_FILE_PATH, NULL,
                             _("Unable to locate auth file"));

Modified: subversion/branches/fsfs-format7/subversion/libsvn_subr/prompt.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_subr/prompt.c?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_subr/prompt.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_subr/prompt.c Wed Feb 13 06:37:54 2013
@@ -137,11 +137,7 @@ terminal_close(terminal_handle_t *termin
 {
   apr_status_t status;
 
-  /* Can't use apr_pool_cleanup_kill to remove the child cleanup; so
-     instead, replace it with the no-op handler. */
-  apr_pool_child_cleanup_set(terminal->pool, terminal,
-                             terminal_plain_cleanup,
-                             apr_pool_cleanup_null);
+  /* apr_pool_cleanup_kill() removes both normal and child cleanup */
   apr_pool_cleanup_kill(terminal->pool, terminal, terminal_plain_cleanup);
 
   status = terminal_cleanup_handler(terminal, TRUE, TRUE);
@@ -150,10 +146,10 @@ terminal_close(terminal_handle_t *termin
   return SVN_NO_ERROR;
 }
 
-/* Open TERMINAL. If NOECHO is TRUE, try to turn off terminal echo.
-   Use POOL for al allocations.*/
+/* Allocate and open *TERMINAL. If NOECHO is TRUE, try to turn off
+   terminal echo.  Use POOL for all allocations.*/
 static svn_error_t *
-terminal_open(terminal_handle_t *terminal, svn_boolean_t noecho,
+terminal_open(terminal_handle_t **terminal, svn_boolean_t noecho,
               apr_pool_t *pool)
 {
   apr_status_t status;
@@ -165,11 +161,12 @@ terminal_open(terminal_handle_t *termina
                                    FILE_SHARE_READ | FILE_SHARE_WRITE,
                                    NULL, OPEN_EXISTING,
                                    FILE_ATTRIBUTE_NORMAL, NULL);
+  *terminal = apr_palloc(pool, sizeof(terminal_handle_t));
   if (conin != INVALID_HANDLE_VALUE)
     {
       /* The process has a console. */
       CloseHandle(conin);
-      terminal_handle_init(terminal, NULL, NULL, noecho, FALSE, NULL);
+      terminal_handle_init(*terminal, NULL, NULL, noecho, FALSE, NULL);
       return SVN_NO_ERROR;
     }
 #else  /* !WIN32 */
@@ -180,10 +177,11 @@ terminal_open(terminal_handle_t *termina
   status = apr_file_open(&tmpfd, "/dev/tty",
                          APR_FOPEN_READ | APR_FOPEN_WRITE,
                          APR_OS_DEFAULT, pool);
+  *terminal = apr_palloc(pool, sizeof(terminal_handle_t));
   if (!status)
     {
       /* We have a terminal handle that we can use for input and output. */
-      terminal_handle_init(terminal, tmpfd, tmpfd, FALSE, TRUE, pool);
+      terminal_handle_init(*terminal, tmpfd, tmpfd, FALSE, TRUE, pool);
     }
 #endif /* !WIN32 */
   else
@@ -198,33 +196,33 @@ terminal_open(terminal_handle_t *termina
       status = apr_file_open_stderr(&outfd, pool);
       if (status)
         return svn_error_wrap_apr(status, _("Can't open stderr"));
-      terminal_handle_init(terminal, infd, outfd, FALSE, FALSE, pool);
+      terminal_handle_init(*terminal, infd, outfd, FALSE, FALSE, pool);
     }
 
 #ifdef HAVE_TERMIOS_H
   /* Set terminal state */
-  if (0 == apr_os_file_get(&terminal->osinfd, terminal->infd))
+  if (0 == apr_os_file_get(&(*terminal)->osinfd, (*terminal)->infd))
     {
-      if (0 == tcgetattr(terminal->osinfd, &terminal->attr))
+      if (0 == tcgetattr((*terminal)->osinfd, &(*terminal)->attr))
         {
-          struct termios attr = terminal->attr;
+          struct termios attr = (*terminal)->attr;
           /* Turn off signal handling and canonical input mode */
           attr.c_lflag &= ~(ISIG | ICANON);
           attr.c_cc[VMIN] = 1;          /* Read one byte at a time */
           attr.c_cc[VTIME] = 0;         /* No timeout, wait indefinitely */
           if (noecho)
             attr.c_lflag &= ~(ECHO);    /* Turn off echo */
-          if (0 == tcsetattr(terminal->osinfd, TCSAFLUSH, &attr))
+          if (0 == tcsetattr((*terminal)->osinfd, TCSAFLUSH, &attr))
             {
-              terminal->noecho = noecho;
-              terminal->restore_state = TRUE;
+              (*terminal)->noecho = noecho;
+              (*terminal)->restore_state = TRUE;
             }
         }
     }
 #endif /* HAVE_TERMIOS_H */
 
   /* Register pool cleanup to close handles and restore echo state. */
-  apr_pool_cleanup_register(terminal->pool, terminal,
+  apr_pool_cleanup_register((*terminal)->pool, *terminal,
                             terminal_plain_cleanup,
                             terminal_child_cleanup);
   return SVN_NO_ERROR;
@@ -441,16 +439,16 @@ prompt(const char **result,
 
   svn_boolean_t saw_first_half_of_eol = FALSE;
   svn_stringbuf_t *strbuf = svn_stringbuf_create_empty(pool);
-  terminal_handle_t terminal;
+  terminal_handle_t *terminal;
   int code;
   char c;
 
   SVN_ERR(terminal_open(&terminal, hide, pool));
-  SVN_ERR(terminal_puts(prompt_msg, &terminal, pool));
+  SVN_ERR(terminal_puts(prompt_msg, terminal, pool));
 
   while (1)
     {
-      SVN_ERR(terminal_getc(&code, &terminal, (strbuf->len > 0), pool));
+      SVN_ERR(terminal_getc(&code, terminal, (strbuf->len > 0), pool));
 
       /* Check for cancellation after a character has been read, some
          input processing modes may eat ^C and we'll only notice a
@@ -481,7 +479,7 @@ prompt(const char **result,
         case TERMINAL_EOF:
           return svn_error_create(
               APR_EOF,
-              terminal_close(&terminal),
+              terminal_close(terminal),
               _("End of file while reading from terminal"));
 
         default:
@@ -516,13 +514,13 @@ prompt(const char **result,
       svn_stringbuf_appendbyte(strbuf, c);
     }
 
-  if (terminal.noecho)
+  if (terminal->noecho)
     {
       /* If terminal echo was turned off, make sure future output
          to the terminal starts on a new line, as expected. */
-      terminal_puts(APR_EOL_STR, &terminal, pool);
+      terminal_puts(APR_EOL_STR, terminal, pool);
     }
-  SVN_ERR(terminal_close(&terminal));
+  SVN_ERR(terminal_close(terminal));
 
   return svn_cmdline_cstring_to_utf8(result, strbuf->data, pool);
 }
@@ -540,13 +538,13 @@ maybe_print_realm(const char *realm, apr
 {
   if (realm)
     {
-      terminal_handle_t terminal;
+      terminal_handle_t *terminal;
       SVN_ERR(terminal_open(&terminal, FALSE, pool));
       SVN_ERR(terminal_puts(
                   apr_psprintf(pool,
                                _("Authentication realm: %s\n"), realm),
-                  &terminal, pool));
-      SVN_ERR(terminal_close(&terminal));
+                  terminal, pool));
+      SVN_ERR(terminal_close(terminal));
     }
 
   return SVN_NO_ERROR;
@@ -761,7 +759,7 @@ plaintext_prompt_helper(svn_boolean_t *m
   svn_boolean_t answered = FALSE;
   svn_cmdline_prompt_baton2_t *pb = baton;
   const char *config_path = NULL;
-  terminal_handle_t terminal;
+  terminal_handle_t *terminal;
 
   if (pb)
     SVN_ERR(svn_config_get_user_config_path(&config_path, pb->config_dir,
@@ -770,8 +768,8 @@ plaintext_prompt_helper(svn_boolean_t *m
   SVN_ERR(terminal_open(&terminal, FALSE, pool));
   SVN_ERR(terminal_puts(apr_psprintf(pool, prompt_text,
                                      realmstring, config_path),
-                        &terminal, pool));
-  SVN_ERR(terminal_close(&terminal));
+                        terminal, pool));
+  SVN_ERR(terminal_close(terminal));
 
   do
     {

Modified: subversion/branches/fsfs-format7/subversion/libsvn_subr/simple_providers.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_subr/simple_providers.c?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_subr/simple_providers.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_subr/simple_providers.c Wed Feb 13 06:37:54 2013
@@ -29,6 +29,9 @@
 
 #include <apr_pools.h>
 #include "svn_auth.h"
+#include "svn_dirent_uri.h"
+#include "svn_hash.h"
+#include "svn_pools.h"
 #include "svn_error.h"
 #include "svn_utf.h"
 #include "svn_config.h"
@@ -37,6 +40,8 @@
 #include "private/svn_auth_private.h"
 
 #include "svn_private_config.h"
+
+#include "auth.h"
 
 /*-----------------------------------------------------------------------*/
 /* File provider                                                         */
@@ -372,8 +377,9 @@ svn_auth__simple_creds_cache_set(svn_boo
           simple_provider_baton_t *b =
             (simple_provider_baton_t *)provider_baton;
 
-          if (svn_cstring_casecmp(store_plaintext_passwords,
-                                  SVN_CONFIG_ASK) == 0)
+          if (store_plaintext_passwords
+              && svn_cstring_casecmp(store_plaintext_passwords,
+                                     SVN_CONFIG_ASK) == 0)
             {
               if (non_interactive)
                 /* In non-interactive mode, the default behaviour is
@@ -438,13 +444,15 @@ svn_auth__simple_creds_cache_set(svn_boo
                   may_save_password = TRUE;
                 }
             }
-          else if (svn_cstring_casecmp(store_plaintext_passwords,
-                                       SVN_CONFIG_FALSE) == 0)
+          else if (store_plaintext_passwords
+                   && svn_cstring_casecmp(store_plaintext_passwords,
+                                          SVN_CONFIG_FALSE) == 0)
             {
               may_save_password = FALSE;
             }
-          else if (svn_cstring_casecmp(store_plaintext_passwords,
-                                       SVN_CONFIG_TRUE) == 0)
+          else if (!store_plaintext_passwords
+                   || svn_cstring_casecmp(store_plaintext_passwords,
+                                          SVN_CONFIG_TRUE) == 0)
             {
               may_save_password = TRUE;
             }
@@ -517,6 +525,133 @@ simple_save_creds(svn_boolean_t *saved,
                                           pool);
 }
 
+svn_error_t *
+svn_auth__simple_cleanup_walk(svn_auth_baton_t *baton,
+                              svn_auth_cleanup_callback cleanup,
+                              void *cleanup_baton,
+                              apr_hash_t *creds_cache,
+                              apr_pool_t *scratch_pool)
+{
+  const char *config_dir;
+  svn_boolean_t no_auth_cache;
+  int i;
+  apr_pool_t *iterpool;
+
+  const char *cred_kinds[] =
+  {
+      SVN_AUTH_CRED_SIMPLE,
+      SVN_AUTH_CRED_USERNAME,
+      SVN_AUTH_CRED_SSL_CLIENT_CERT,
+      SVN_AUTH_CRED_SSL_CLIENT_CERT_PW,
+      SVN_AUTH_CRED_SSL_SERVER_TRUST,
+      NULL
+  };
+
+  config_dir = svn_auth_get_parameter(baton, SVN_AUTH_PARAM_CONFIG_DIR);
+  no_auth_cache = (svn_auth_get_parameter(baton, SVN_AUTH_PARAM_NO_AUTH_CACHE)
+                                != NULL);
+
+  if ((! config_dir) || no_auth_cache)
+    {
+      /* Can't locate the cache to clear */
+      return SVN_NO_ERROR;
+    }
+
+  iterpool = svn_pool_create(scratch_pool);
+  for (i = 0; cred_kinds[i]; i++)
+    {
+      const char *item_path;
+      const char *dir_path;
+      apr_hash_t *nodes;
+      svn_error_t *err;
+      apr_pool_t *itempool;
+      apr_hash_index_t *hi;
+
+      svn_pool_clear(iterpool);
+
+      SVN_ERR(svn_auth__file_path(&item_path, cred_kinds[i], "!", config_dir,
+                                  iterpool));
+
+      dir_path = svn_dirent_dirname(item_path, iterpool);
+
+      err = svn_io_get_dirents3(&nodes, dir_path, TRUE, iterpool, iterpool);
+
+      if (err)
+        {
+          if (!APR_STATUS_IS_ENOENT(err->apr_err)
+              && !SVN__APR_STATUS_IS_ENOTDIR(err->apr_err))
+            return svn_error_trace(err);
+
+          svn_error_clear(err);
+          continue;
+        }
+
+      itempool = svn_pool_create(iterpool);
+      for (hi = apr_hash_first(iterpool, nodes); hi; hi = apr_hash_next(hi))
+        {
+          svn_io_dirent2_t *dirent = svn__apr_hash_index_val(hi);
+          svn_stream_t *stream;
+          apr_hash_t *file_data;
+
+          if (dirent->kind != svn_node_file)
+            continue;
+
+          svn_pool_clear(itempool);
+
+          item_path = svn_dirent_join(dir_path, svn__apr_hash_index_key(hi),
+                                      itempool);
+
+          err = svn_stream_open_readonly(&stream, item_path, itempool, itempool);
+          if (err)
+            {
+              /* Ignore this file. There are no credentials in it anyway */
+              svn_error_clear(err);
+              continue;
+            }
+
+          file_data = apr_hash_make(itempool);
+          err = svn_hash_read2(file_data, stream, SVN_HASH_TERMINATOR, itempool);
+          err = svn_error_compose_create(err, svn_stream_close(stream));
+          if (err)
+            {
+              /* Ignore this file. There are no credentials in it anyway */
+              svn_error_clear(err);
+              continue;
+            }
+
+          {
+            const svn_string_t *realm = svn_hash_gets(file_data, SVN_CONFIG_REALMSTRING_KEY);
+            svn_boolean_t delete_file = FALSE;
+
+            if (! realm)
+              continue; /* Not an auth file */
+
+            SVN_ERR(cleanup(&delete_file, cleanup_baton, cred_kinds[i], realm->data,
+                            SVN_AUTH_CRED_SIMPLE, itempool));
+
+            if (delete_file)
+              {
+                /* Delete from the credential hash */
+                const char *cache_key = apr_pstrcat(itempool,
+                                                    cred_kinds[0],
+                                                    ":",
+                                                    realm->data,
+                                                    (char *)NULL);
+
+                svn_hash_sets(creds_cache, cache_key, NULL);
+
+                /* And the file on disk */
+                SVN_ERR(svn_io_remove_file2(item_path, TRUE, itempool));
+              }
+          }
+        }
+    }
+
+  svn_pool_destroy(iterpool);
+  return SVN_NO_ERROR;
+}
+
+
 static const svn_auth_provider_t simple_provider = {
   SVN_AUTH_CRED_SIMPLE,
   simple_first_creds,
@@ -718,7 +853,6 @@ simple_prompt_next_creds(void **credenti
                                  ! no_auth_cache, pool);
 }
 
-
 static const svn_auth_provider_t simple_prompt_provider = {
   SVN_AUTH_CRED_SIMPLE,
   simple_prompt_first_creds,

Modified: subversion/branches/fsfs-format7/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_wc/conflicts.c?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_wc/conflicts.c Wed Feb 13 06:37:54 2013
@@ -537,7 +537,7 @@ svn_wc__conflict_skel_add_tree_conflict(
                                         const char *wri_abspath,
                                         svn_wc_conflict_reason_t local_change,
                                         svn_wc_conflict_action_t incoming_change,
-                                        const char *moved_away_op_root_abspath,
+                                        const char *move_src_op_root_abspath,
                                         apr_pool_t *result_pool,
                                         apr_pool_t *scratch_pool)
 {
@@ -549,22 +549,22 @@ svn_wc__conflict_skel_add_tree_conflict(
 
   SVN_ERR_ASSERT(!tree_conflict); /* ### Use proper error? */
 
-  SVN_ERR_ASSERT((local_change != svn_wc_conflict_reason_moved_away
-                  && !moved_away_op_root_abspath)
-                 || moved_away_op_root_abspath); /* ### Use proper error? */
+  SVN_ERR_ASSERT(local_change == svn_wc_conflict_reason_moved_away
+                 || !move_src_op_root_abspath); /* ### Use proper error? */
 
   tree_conflict = svn_skel__make_empty_list(result_pool);
 
-  if (local_change == svn_wc_conflict_reason_moved_away)
+  if (local_change == svn_wc_conflict_reason_moved_away
+      && move_src_op_root_abspath)
     {
-      const char *moved_away_op_root_relpath;
+      const char *move_src_op_root_relpath;
 
-      SVN_ERR(svn_wc__db_to_relpath(&moved_away_op_root_relpath,
+      SVN_ERR(svn_wc__db_to_relpath(&move_src_op_root_relpath,
                                     db, wri_abspath,
-                                    moved_away_op_root_abspath,
+                                    move_src_op_root_abspath,
                                     result_pool, scratch_pool));
 
-      svn_skel__prepend_str(moved_away_op_root_relpath, tree_conflict,
+      svn_skel__prepend_str(move_src_op_root_relpath, tree_conflict,
                             result_pool);
     }
 
@@ -933,7 +933,7 @@ svn_wc__conflict_read_prop_conflict(cons
 svn_error_t *
 svn_wc__conflict_read_tree_conflict(svn_wc_conflict_reason_t *local_change,
                                     svn_wc_conflict_action_t *incoming_change,
-                                    const char **moved_away_op_root_abspath,
+                                    const char **move_src_op_root_abspath,
                                     svn_wc__db_t *db,
                                     const char *wri_abspath,
                                     const svn_skel_t *conflict_skel,
@@ -956,16 +956,18 @@ svn_wc__conflict_read_tree_conflict(svn_
 
   c = c->next; /* Skip markers */
 
-  if (local_change)
-    {
-      int value = svn_token__from_mem(local_change_map, c->data, c->len);
+  {
+    int value = svn_token__from_mem(local_change_map, c->data, c->len);
 
-      if (value != SVN_TOKEN_UNKNOWN)
-        *local_change = value;
-      else
-        *local_change = svn_wc_conflict_reason_edited;
+    if (local_change)
+      {
+        if (value != SVN_TOKEN_UNKNOWN)
+          *local_change = value;
+        else
+          *local_change = svn_wc_conflict_reason_edited;
+      }
 
-      is_moved_away = *local_change == svn_wc_conflict_reason_moved_away;
+      is_moved_away = (value == svn_wc_conflict_reason_moved_away);
     }
   c = c->next;
 
@@ -981,15 +983,21 @@ svn_wc__conflict_read_tree_conflict(svn_
 
   c = c->next;
 
-  if (is_moved_away && moved_away_op_root_abspath)
+  if (move_src_op_root_abspath)
     {
-      const char *moved_away_op_root_relpath = apr_pstrmemdup(scratch_pool,
-                                                              c->data, c->len);
+      /* Only set for update and switch tree conflicts */
+      if (c && is_moved_away)
+        {
+          const char *move_src_op_root_relpath
+                            = apr_pstrmemdup(scratch_pool, c->data, c->len);
 
-      SVN_ERR(svn_wc__db_from_relpath(moved_away_op_root_abspath,
-                                      db, wri_abspath,
-                                      moved_away_op_root_relpath,
-                                      result_pool, scratch_pool));
+          SVN_ERR(svn_wc__db_from_relpath(move_src_op_root_abspath,
+                                          db, wri_abspath,
+                                          move_src_op_root_relpath,
+                                          result_pool, scratch_pool));
+        }
+      else
+        *move_src_op_root_abspath = NULL;
     }
 
   return SVN_NO_ERROR;
@@ -2330,7 +2338,9 @@ resolve_conflict_on_node(svn_boolean_t *
                          svn_boolean_t resolve_tree,
                          svn_wc_conflict_choice_t conflict_choice,
                          svn_skel_t *work_items,
-                         svn_cancel_func_t cancel_func_t,
+                         svn_wc_notify_func2_t notify_func,
+                         void *notify_baton,
+                         svn_cancel_func_t cancel_func,
                          void *cancel_baton,
                          apr_pool_t *scratch_pool)
 {
@@ -2599,23 +2609,75 @@ resolve_conflict_on_node(svn_boolean_t *
   if (resolve_tree)
     {
       svn_wc_conflict_reason_t reason;
+      svn_wc_conflict_action_t action;
 
-      SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL, NULL, 
+      SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action, NULL, 
                                                   db, local_abspath,
                                                   conflicts,
                                                   scratch_pool, scratch_pool));
 
-      if (reason == svn_wc_conflict_reason_deleted)
+      if (operation == svn_wc_operation_update
+          || operation == svn_wc_operation_switch)
+        {
+          if (reason == svn_wc_conflict_reason_deleted)
+            {
+              if (conflict_choice == svn_wc_conflict_choose_merged)
+                {
+                  SVN_ERR(svn_wc__db_resolve_delete_raise_moved_away(
+                            db, local_abspath, scratch_pool));
+                  *did_resolve = TRUE;
+                }
+            }
+          else if (reason == svn_wc_conflict_reason_moved_away
+                  && action == svn_wc_conflict_action_edit)
+            {
+              /* After updates, we can resolve local moved-away
+               * vs. any incoming change, either by updating the
+               * moved-away node (mine-conflict) or by breaking the
+               * move (theirs-conflict). */
+              if (conflict_choice == svn_wc_conflict_choose_mine_conflict)
+                {
+                  SVN_ERR(svn_wc__db_update_moved_away_conflict_victim(
+                            &work_items,
+                            db, local_abspath,
+                            notify_func, notify_baton,
+                            cancel_func, cancel_baton,
+                            scratch_pool, scratch_pool));
+                  *did_resolve = TRUE;
+                }
+              else if (conflict_choice == svn_wc_conflict_choose_theirs_conflict
+                       || conflict_choice == svn_wc_conflict_choose_merged)
+                {
+                  /* We must break the move even if the user accepts
+                   * the current working copy state (choose_merged)
+                   * instead of updating the move. Else the move would
+                   * be left in an invalid state. */
+
+                  /* ### This breaks the move but leaves the conflict
+                     ### involving the move until
+                     ### svn_wc__db_op_mark_resolved. */
+                  SVN_ERR(svn_wc__db_resolve_break_moved_away(db, local_abspath,
+                                                              scratch_pool));
+                  *did_resolve = TRUE;
+                }
+            }
+        }
+
+      if (*did_resolve == FALSE &&
+          conflict_choice != svn_wc_conflict_choose_merged)
         {
-          /* ### FIXME.  At the moment this is a separate transaction
-             ### but it should somehow be combined with the transaction
-             ### in svn_wc__db_op_mark_resolved.  Perhaps move this
-             ### functionality into that function?  Perhaps have this
-             ### function generate "raise conflict" workqueue items? */
-          SVN_ERR(svn_wc__db_resolve_delete_raise_moved_away(db, local_abspath,
-                                                             scratch_pool));
+          /* For other tree conflicts, there is no way to pick
+           * theirs-full or mine-full, etc. Throw an error if the
+           * user expects us to be smarter than we really are. */
+          return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE,
+                                   NULL,
+                                   _("Tree conflict can only be "
+                                     "resolved to 'working' state; "
+                                     "'%s' not resolved"),
+                                   svn_dirent_local_style(local_abspath,
+                                                          scratch_pool));
         }
-                                                  
+
       *did_resolve = TRUE;
     }
 
@@ -2627,7 +2689,7 @@ resolve_conflict_on_node(svn_boolean_t *
 
       /* Run the work queue to remove conflict marker files. */
       SVN_ERR(svn_wc__wq_run(db, local_abspath,
-                             cancel_func_t, cancel_baton,
+                             cancel_func, cancel_baton,
                              pool));
     }
 
@@ -2650,6 +2712,7 @@ svn_wc__mark_resolved_text_conflict(svn_
                            FALSE /* resolve_tree */,
                            svn_wc_conflict_choose_merged,
                            NULL,
+                           NULL, NULL, /* notify_func */
                            NULL, NULL, /* cancel_func */
                            scratch_pool));
 }
@@ -2669,6 +2732,7 @@ svn_wc__mark_resolved_prop_conflicts(svn
                            FALSE /* resolve_tree */,
                            svn_wc_conflict_choose_merged,
                            NULL /* work_items */,
+                           NULL, NULL, /* notify_func */
                            NULL, NULL, /* cancel_func */
                            scratch_pool));
 }
@@ -2749,58 +2813,6 @@ conflict_status_walker(void *baton,
           case svn_wc_conflict_kind_tree:
             if (!cswb->resolve_tree)
               break;
-
-            /* After updates, we can resolve local moved-away vs. any incoming
-             * change, either by updating the moved-away node (mine-conflict)
-             * or by breaking the move (theirs-conflict). */
-            if ((cd->operation == svn_wc_operation_update ||
-                 cd->operation == svn_wc_operation_switch) &&
-                cd->reason == svn_wc_conflict_reason_moved_away)
-              {
-                if (my_choice == svn_wc_conflict_choose_mine_conflict)
-                  SVN_ERR(svn_wc__db_update_moved_away_conflict_victim(
-                            &work_items,
-                            cswb->db, local_abspath,
-                            cswb->notify_func, cswb->notify_baton,
-                            cswb->cancel_func, cswb->cancel_baton,
-                            scratch_pool, scratch_pool));
-                 else if (my_choice == svn_wc_conflict_choose_theirs_conflict)
-                  {
-                    switch (status->node_status)
-                      {
-                        case svn_wc_status_deleted:
-                          /* Break the move by reverting the deleted half of
-                           * the move, keeping the copied-half as a copy.
-                           * Reverting a node requires write lock on parent. */
-                          SVN_ERR(svn_wc__revert_internal(cswb->db, local_abspath,
-                                                          svn_depth_infinity,
-                                                          FALSE, 
-                                                          cswb->cancel_func,
-                                                          cswb->cancel_baton,
-                                                          cswb->notify_func,
-                                                          cswb->notify_baton,
-                                                          scratch_pool));
-                          break;
-                        default:
-                          /* ### TODO other node_status cases */
-                          break;
-                      }
-                  }
-              }
-            else if (my_choice != svn_wc_conflict_choose_merged)
-              {
-                /* For other tree conflicts, there is no way to pick
-                 * theirs-full or mine-full, etc. Throw an error if the
-                 * user expects us to be smarter than we really are. */
-                return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE,
-                                         NULL,
-                                         _("Tree conflict can only be "
-                                           "resolved to 'working' state; "
-                                           "'%s' not resolved"),
-                                         svn_dirent_local_style(local_abspath,
-                                                                iterpool));
-              }
-
             SVN_ERR(resolve_conflict_on_node(&did_resolve,
                                              db,
                                              local_abspath,
@@ -2809,6 +2821,8 @@ conflict_status_walker(void *baton,
                                              TRUE /* resolve_tree */,
                                              my_choice,
                                              work_items,
+                                             cswb->notify_func,
+                                             cswb->notify_baton,
                                              cswb->cancel_func,
                                              cswb->cancel_baton,
                                              iterpool));
@@ -2828,6 +2842,8 @@ conflict_status_walker(void *baton,
                                              FALSE /* resolve_tree */,
                                              my_choice,
                                              NULL,
+                                             cswb->notify_func,
+                                             cswb->notify_baton,
                                              cswb->cancel_func,
                                              cswb->cancel_baton,
                                              iterpool));
@@ -2858,6 +2874,8 @@ conflict_status_walker(void *baton,
                                              FALSE /* resolve_tree */,
                                              my_choice,
                                              NULL,
+                                             cswb->notify_func,
+                                             cswb->notify_baton,
                                              cswb->cancel_func,
                                              cswb->cancel_baton,
                                              iterpool));

Modified: subversion/branches/fsfs-format7/subversion/libsvn_wc/conflicts.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_wc/conflicts.h?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_wc/conflicts.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_wc/conflicts.h Wed Feb 13 06:37:54 2013
@@ -201,8 +201,9 @@ svn_wc__conflict_skel_add_prop_conflict(
    It is an error to add another tree conflict to a conflict skel that
    already contains a tree conflict.
 
-   MOVED_AWAY_OP_ROOT_ABSPATH must be set when LOCAL_CHANGE is
-   svn_wc_conflict_reason_moved_away and NULL otherwise.  It should be
+   MOVE_SRC_OP_ROOT_ABSPATH must be set when LOCAL_CHANGE is
+   svn_wc_conflict_reason_moved_away and NULL otherwise and the operation
+   is svn_wc_operation_update or svn_wc_operation_switch.  It should be
    set to the op-root of the move-away unless the move is inside a
    delete in which case it should be set to the op-root of the delete
    (the delete can be a replace). So given:
@@ -210,8 +211,8 @@ svn_wc__conflict_skel_add_prop_conflict(
        A deleted and replaced
        A/B/C moved away (2)
        A/B deleted
-   MOVED_AWAY_OP_ROOT_ABSPATH should be A for a conflict associated
-   with (1), MOVED_AWAY_OP_ROOT_ABSPATH should be A/B for a conflict
+   MOVE_SRC_OP_ROOT_ABSPATH should be A for a conflict associated
+   with (1), MOVE_SRC_OP_ROOT_ABSPATH should be A/B for a conflict
    associated with (2).
 
    ### Is it an error to add a tree conflict to any existing conflict?
@@ -224,7 +225,7 @@ svn_wc__conflict_skel_add_tree_conflict(
                                         const char *wri_abspath,
                                         svn_wc_conflict_reason_t local_change,
                                         svn_wc_conflict_action_t incoming_change,
-                                        const char *moved_away_op_root_abspath,
+                                        const char *move_src_op_root_abspath,
                                         apr_pool_t *result_pool,
                                         apr_pool_t *scratch_pool);
 
@@ -355,7 +356,7 @@ svn_wc__conflict_read_prop_conflict(cons
 svn_error_t *
 svn_wc__conflict_read_tree_conflict(svn_wc_conflict_reason_t *local_change,
                                     svn_wc_conflict_action_t *incoming_change,
-                                    const char **moved_away_op_root_abspath,
+                                    const char **move_src_op_root_abspath,
                                     svn_wc__db_t *db,
                                     const char *wri_abspath,
                                     const svn_skel_t *conflict_skel,