Modified: subversion/branches/addremove/subversion/libsvn_delta/branch_compat.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_delta/branch_compat.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_delta/branch_compat.c 
(original)
+++ subversion/branches/addremove/subversion/libsvn_delta/branch_compat.c Sat 
May 23 14:16:56 2020
@@ -875,6 +875,8 @@ drive_ev1_props(const char *repos_relpat
  */
 static svn_error_t *
 apply_change(void **dir_baton,
+             const svn_delta_editor_t *editor,
+             void *edit_baton,
              void *parent_baton,
              void *callback_baton,
              const char *ev1_relpath,
@@ -905,7 +907,7 @@ apply_change(void **dir_baton,
       /* Only property edits are allowed on the root.  */
       SVN_ERR_ASSERT(change->action == RESTRUCTURE_NONE);
       SVN_ERR(drive_ev1_props(ev1_relpath, change, base_props,
-                              eb->deditor, *dir_baton, scratch_pool));
+                              editor, *dir_baton, scratch_pool));
 
       /* No further action possible for the root.  */
       return SVN_NO_ERROR;
@@ -913,10 +915,10 @@ apply_change(void **dir_baton,
 
   if (change->action == RESTRUCTURE_DELETE)
     {
-      SVN_ERR(eb->deditor->delete_entry(ev1_relpath, change->deleting_rev,
-                                        parent_baton, scratch_pool));
+      SVN_ERR(editor->delete_entry(ev1_relpath, change->deleting_rev,
+                                   parent_baton, scratch_pool));
 
-      /* No futher action possible for this node.  */
+      /* No further action possible for this node.  */
       return SVN_NO_ERROR;
     }
 
@@ -927,11 +929,11 @@ apply_change(void **dir_baton,
   if (change->action == RESTRUCTURE_ADD_ABSENT)
     {
       if (change->kind == svn_node_dir)
-        SVN_ERR(eb->deditor->absent_directory(ev1_relpath, parent_baton,
-                                              scratch_pool));
-      else if (change->kind == svn_node_file)
-        SVN_ERR(eb->deditor->absent_file(ev1_relpath, parent_baton,
+        SVN_ERR(editor->absent_directory(ev1_relpath, parent_baton,
                                          scratch_pool));
+      else if (change->kind == svn_node_file)
+        SVN_ERR(editor->absent_file(ev1_relpath, parent_baton,
+                                    scratch_pool));
       else
         SVN_ERR_MALFUNCTION();
 
@@ -948,8 +950,8 @@ apply_change(void **dir_baton,
 
       /* Do we have an old node to delete first? If so, delete it. */
       if (change->deleting)
-        SVN_ERR(eb->deditor->delete_entry(ev1_relpath, change->deleting_rev,
-                                          parent_baton, scratch_pool));
+        SVN_ERR(editor->delete_entry(ev1_relpath, change->deleting_rev,
+                                     parent_baton, scratch_pool));
 
       /* If it's a copy, determine the copy source location. */
       if (change->copyfrom_path)
@@ -974,13 +976,13 @@ apply_change(void **dir_baton,
         }
 
       if (change->kind == svn_node_dir)
-        SVN_ERR(eb->deditor->add_directory(ev1_relpath, parent_baton,
-                                           copyfrom_url, copyfrom_rev,
-                                           result_pool, dir_baton));
-      else if (change->kind == svn_node_file)
-        SVN_ERR(eb->deditor->add_file(ev1_relpath, parent_baton,
+        SVN_ERR(editor->add_directory(ev1_relpath, parent_baton,
                                       copyfrom_url, copyfrom_rev,
-                                      result_pool, &file_baton));
+                                      result_pool, dir_baton));
+      else if (change->kind == svn_node_file)
+        SVN_ERR(editor->add_file(ev1_relpath, parent_baton,
+                                 copyfrom_url, copyfrom_rev,
+                                 result_pool, &file_baton));
       else
         SVN_ERR_MALFUNCTION();
     }
@@ -993,13 +995,13 @@ apply_change(void **dir_baton,
          when we fetch the base properties.) */
 
       if (change->kind == svn_node_dir)
-        SVN_ERR(eb->deditor->open_directory(ev1_relpath, parent_baton,
-                                            change->changing_rev,
-                                            result_pool, dir_baton));
-      else if (change->kind == svn_node_file)
-        SVN_ERR(eb->deditor->open_file(ev1_relpath, parent_baton,
+        SVN_ERR(editor->open_directory(ev1_relpath, parent_baton,
                                        change->changing_rev,
-                                       result_pool, &file_baton));
+                                       result_pool, dir_baton));
+      else if (change->kind == svn_node_file)
+        SVN_ERR(editor->open_file(ev1_relpath, parent_baton,
+                                  change->changing_rev,
+                                  result_pool, &file_baton));
       else
         SVN_ERR_MALFUNCTION();
     }
@@ -1007,10 +1009,10 @@ apply_change(void **dir_baton,
   /* Apply any properties in CHANGE to the node.  */
   if (change->kind == svn_node_dir)
     SVN_ERR(drive_ev1_props(ev1_relpath, change, base_props,
-                            eb->deditor, *dir_baton, scratch_pool));
+                            editor, *dir_baton, scratch_pool));
   else
     SVN_ERR(drive_ev1_props(ev1_relpath, change, base_props,
-                            eb->deditor, file_baton, scratch_pool));
+                            editor, file_baton, scratch_pool));
 
   /* Send the text content delta, if new text content is provided. */
   if (change->contents_text)
@@ -1023,7 +1025,7 @@ apply_change(void **dir_baton,
                                               scratch_pool);
       /* ### would be nice to have a BASE_CHECKSUM, but hey: this is the
          ### shim code...  */
-      SVN_ERR(eb->deditor->apply_textdelta(file_baton, NULL, scratch_pool,
+      SVN_ERR(editor->apply_textdelta(file_baton, NULL, scratch_pool,
                                            &handler, &handler_baton));
       /* ### it would be nice to send a true txdelta here, but whatever.  */
       SVN_ERR(svn_txdelta_send_stream(read_stream, handler, handler_baton,
@@ -1033,7 +1035,7 @@ apply_change(void **dir_baton,
 
   if (file_baton)
     {
-      SVN_ERR(eb->deditor->close_file(file_baton, NULL, scratch_pool));
+      SVN_ERR(editor->close_file(file_baton, NULL, scratch_pool));
     }
 
   return SVN_NO_ERROR;
@@ -1740,7 +1742,7 @@ drive_changes(svn_branch__txn_priv_t *eb
 
   /* Apply the appropriate Ev1 change to each Ev1-relative path. */
   paths = get_unsorted_paths(eb->changes, scratch_pool);
-  SVN_ERR(svn_delta_path_driver2(eb->deditor, eb->dedit_baton,
+  SVN_ERR(svn_delta_path_driver3(eb->deditor, eb->dedit_baton,
                                  paths, TRUE /*sort*/,
                                  apply_change, (void *)eb,
                                  scratch_pool));

Modified: subversion/branches/addremove/subversion/libsvn_delta/compat.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_delta/compat.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_delta/compat.c (original)
+++ subversion/branches/addremove/subversion/libsvn_delta/compat.c Sat May 23 
14:16:56 2020
@@ -108,7 +108,7 @@ svn_compat_wrap_file_rev_handler(svn_fil
  * deletion has side effects (unlike deleting a non-existent regular property
  * would).  To solve this, we introduce *another* function into the API, not
  * a part of the Ev2 callbacks, but a companion which is used to register
- * the unlock of a path.  See ev2_change_file_prop() for implemenation
+ * the unlock of a path.  See ev2_change_file_prop() for implementation
  * details.
  */
 
@@ -467,7 +467,7 @@ run_ev2_actions(struct ev2_edit_baton *e
 
   iterpool = svn_pool_create(scratch_pool);
 
-  /* Possibly pick up where we left off. Ocassionally, we do some of these
+  /* Possibly pick up where we left off. Occasionally, we do some of these
      as part of close_edit() and then some more as part of abort_edit()  */
   for (; eb->paths_processed < eb->path_order->nelts; ++eb->paths_processed)
     {
@@ -877,7 +877,7 @@ ev2_change_file_prop(void *file_baton,
 
   if (!strcmp(name, SVN_PROP_ENTRY_LOCK_TOKEN) && value == NULL)
     {
-      /* We special case the lock token propery deletion, which is the
+      /* We special case the lock token property deletion, which is the
          server's way of telling the client to unlock the path. */
 
       /* ### this duplicates much of apply_propedit(). fix in future.  */
@@ -1577,6 +1577,8 @@ drive_ev1_props(const struct editor_bato
 /* Conforms to svn_delta_path_driver_cb_func_t  */
 static svn_error_t *
 apply_change(void **dir_baton,
+             const svn_delta_editor_t *deditor,
+             void *dedit_baton,
              void *parent_baton,
              void *callback_baton,
              const char *ev1_relpath,
@@ -1614,10 +1616,10 @@ apply_change(void **dir_baton,
 
   if (change->action == RESTRUCTURE_DELETE)
     {
-      SVN_ERR(eb->deditor->delete_entry(ev1_relpath, change->deleting,
-                                        parent_baton, scratch_pool));
+      SVN_ERR(deditor->delete_entry(ev1_relpath, change->deleting,
+                                    parent_baton, scratch_pool));
 
-      /* No futher action possible for this node.  */
+      /* No further action possible for this node.  */
       return SVN_NO_ERROR;
     }
 
@@ -1627,11 +1629,11 @@ apply_change(void **dir_baton,
   if (change->action == RESTRUCTURE_ADD_ABSENT)
     {
       if (change->kind == svn_node_dir)
-        SVN_ERR(eb->deditor->absent_directory(ev1_relpath, parent_baton,
-                                              scratch_pool));
+        SVN_ERR(deditor->absent_directory(ev1_relpath, parent_baton,
+                                          scratch_pool));
       else
-        SVN_ERR(eb->deditor->absent_file(ev1_relpath, parent_baton,
-                                         scratch_pool));
+        SVN_ERR(deditor->absent_file(ev1_relpath, parent_baton,
+                                     scratch_pool));
 
       /* No further action possible for this node.  */
       return SVN_NO_ERROR;
@@ -1645,8 +1647,8 @@ apply_change(void **dir_baton,
 
       /* Do we have an old node to delete first?  */
       if (SVN_IS_VALID_REVNUM(change->deleting))
-        SVN_ERR(eb->deditor->delete_entry(ev1_relpath, change->deleting,
-                                          parent_baton, scratch_pool));
+        SVN_ERR(deditor->delete_entry(ev1_relpath, change->deleting,
+                                      parent_baton, scratch_pool));
 
       /* Are we copying the node from somewhere?  */
       if (change->copyfrom_path)
@@ -1669,24 +1671,24 @@ apply_change(void **dir_baton,
         }
 
       if (change->kind == svn_node_dir)
-        SVN_ERR(eb->deditor->add_directory(ev1_relpath, parent_baton,
-                                           copyfrom_url, copyfrom_rev,
-                                           result_pool, dir_baton));
+        SVN_ERR(deditor->add_directory(ev1_relpath, parent_baton,
+                                       copyfrom_url, copyfrom_rev,
+                                       result_pool, dir_baton));
       else
-        SVN_ERR(eb->deditor->add_file(ev1_relpath, parent_baton,
-                                      copyfrom_url, copyfrom_rev,
-                                      result_pool, &file_baton));
+        SVN_ERR(deditor->add_file(ev1_relpath, parent_baton,
+                                  copyfrom_url, copyfrom_rev,
+                                  result_pool, &file_baton));
     }
   else
     {
       if (change->kind == svn_node_dir)
-        SVN_ERR(eb->deditor->open_directory(ev1_relpath, parent_baton,
-                                            change->changing,
-                                            result_pool, dir_baton));
+        SVN_ERR(deditor->open_directory(ev1_relpath, parent_baton,
+                                        change->changing,
+                                        result_pool, dir_baton));
       else
-        SVN_ERR(eb->deditor->open_file(ev1_relpath, parent_baton,
-                                       change->changing,
-                                       result_pool, &file_baton));
+        SVN_ERR(deditor->open_file(ev1_relpath, parent_baton,
+                                   change->changing,
+                                   result_pool, &file_baton));
     }
 
   /* Apply any properties in CHANGE to the node.  */
@@ -1703,8 +1705,8 @@ apply_change(void **dir_baton,
 
       /* ### would be nice to have a BASE_CHECKSUM, but hey: this is the
          ### shim code...  */
-      SVN_ERR(eb->deditor->apply_textdelta(file_baton, NULL, scratch_pool,
-                                           &handler, &handler_baton));
+      SVN_ERR(deditor->apply_textdelta(file_baton, NULL, scratch_pool,
+                                       &handler, &handler_baton));
       SVN_ERR(svn_stream_open_readonly(&contents, change->contents_abspath,
                                        scratch_pool, scratch_pool));
       /* ### it would be nice to send a true txdelta here, but whatever.  */
@@ -1718,7 +1720,7 @@ apply_change(void **dir_baton,
       const char *digest = svn_checksum_to_cstring(change->checksum,
                                                    scratch_pool);
 
-      SVN_ERR(eb->deditor->close_file(file_baton, digest, scratch_pool));
+      SVN_ERR(deditor->close_file(file_baton, digest, scratch_pool));
     }
 
   return SVN_NO_ERROR;
@@ -1747,7 +1749,7 @@ drive_changes(const struct editor_baton
 
   /* Get a sorted list of Ev1-relative paths.  */
   paths = get_sorted_paths(eb->changes, eb->base_relpath, scratch_pool);
-  SVN_ERR(svn_delta_path_driver2(eb->deditor, eb->dedit_baton, paths,
+  SVN_ERR(svn_delta_path_driver3(eb->deditor, eb->dedit_baton, paths,
                                  FALSE, apply_change, (void *)eb,
                                  scratch_pool));
 

Modified: subversion/branches/addremove/subversion/libsvn_delta/compose_delta.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_delta/compose_delta.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_delta/compose_delta.c 
(original)
+++ subversion/branches/addremove/subversion/libsvn_delta/compose_delta.c Sat 
May 23 14:16:56 2020
@@ -128,7 +128,7 @@ free_block(void *ptr, alloc_block_t **fr
 
 
 /* ==================================================================== */
-/* Mapping offsets in the target streem to txdelta ops. */
+/* Mapping offsets in the target stream to txdelta ops. */
 
 typedef struct offset_index_t
 {

Modified: subversion/branches/addremove/subversion/libsvn_delta/debug_editor.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_delta/debug_editor.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_delta/debug_editor.c 
(original)
+++ subversion/branches/addremove/subversion/libsvn_delta/debug_editor.c Sat 
May 23 14:16:56 2020
@@ -71,9 +71,11 @@ set_target_revision(void *edit_baton,
   SVN_ERR(svn_stream_printf(eb->out, pool, "set_target_revision : %ld\n",
                             target_revision));
 
-  return eb->wrapped_editor->set_target_revision(eb->wrapped_edit_baton,
-                                                 target_revision,
-                                                 pool);
+  if (eb->wrapped_editor)
+    SVN_ERR(eb->wrapped_editor->set_target_revision(eb->wrapped_edit_baton,
+                                                    target_revision,
+                                                    pool));
+  return SVN_NO_ERROR;
 }
 
 static svn_error_t *
@@ -90,10 +92,11 @@ open_root(void *edit_baton,
                             base_revision));
   eb->indent_level++;
 
-  SVN_ERR(eb->wrapped_editor->open_root(eb->wrapped_edit_baton,
-                                        base_revision,
-                                        pool,
-                                        &dir_baton->wrapped_dir_baton));
+  if (eb->wrapped_editor)
+    SVN_ERR(eb->wrapped_editor->open_root(eb->wrapped_edit_baton,
+                                          base_revision,
+                                          pool,
+                                          &dir_baton->wrapped_dir_baton));
 
   dir_baton->edit_baton = edit_baton;
 
@@ -115,10 +118,12 @@ delete_entry(const char *path,
   SVN_ERR(svn_stream_printf(eb->out, pool, "delete_entry : %s:%ld\n",
                             path, base_revision));
 
-  return eb->wrapped_editor->delete_entry(path,
-                                          base_revision,
-                                          pb->wrapped_dir_baton,
-                                          pool);
+  if (eb->wrapped_editor)
+    SVN_ERR(eb->wrapped_editor->delete_entry(path,
+                                             base_revision,
+                                             pb->wrapped_dir_baton,
+                                             pool));
+  return SVN_NO_ERROR;
 }
 
 static svn_error_t *
@@ -139,12 +144,13 @@ add_directory(const char *path,
                             path, copyfrom_path, copyfrom_revision));
   eb->indent_level++;
 
-  SVN_ERR(eb->wrapped_editor->add_directory(path,
-                                            pb->wrapped_dir_baton,
-                                            copyfrom_path,
-                                            copyfrom_revision,
-                                            pool,
-                                            &b->wrapped_dir_baton));
+  if (eb->wrapped_editor)
+    SVN_ERR(eb->wrapped_editor->add_directory(path,
+                                              pb->wrapped_dir_baton,
+                                              copyfrom_path,
+                                              copyfrom_revision,
+                                              pool,
+                                              &b->wrapped_dir_baton));
 
   b->edit_baton = eb;
   *child_baton = b;
@@ -168,11 +174,12 @@ open_directory(const char *path,
                             path, base_revision));
   eb->indent_level++;
 
-  SVN_ERR(eb->wrapped_editor->open_directory(path,
-                                             pb->wrapped_dir_baton,
-                                             base_revision,
-                                             pool,
-                                             &db->wrapped_dir_baton));
+  if (eb->wrapped_editor)
+    SVN_ERR(eb->wrapped_editor->open_directory(path,
+                                               pb->wrapped_dir_baton,
+                                               base_revision,
+                                               pool,
+                                               &db->wrapped_dir_baton));
 
   db->edit_baton = eb;
   *child_baton = db;
@@ -199,12 +206,13 @@ add_file(const char *path,
 
   eb->indent_level++;
 
-  SVN_ERR(eb->wrapped_editor->add_file(path,
-                                       pb->wrapped_dir_baton,
-                                       copyfrom_path,
-                                       copyfrom_revision,
-                                       pool,
-                                       &fb->wrapped_file_baton));
+  if (eb->wrapped_editor)
+    SVN_ERR(eb->wrapped_editor->add_file(path,
+                                         pb->wrapped_dir_baton,
+                                         copyfrom_path,
+                                         copyfrom_revision,
+                                         pool,
+                                         &fb->wrapped_file_baton));
 
   fb->edit_baton = eb;
   *file_baton = fb;
@@ -229,11 +237,12 @@ open_file(const char *path,
 
   eb->indent_level++;
 
-  SVN_ERR(eb->wrapped_editor->open_file(path,
-                                        pb->wrapped_dir_baton,
-                                        base_revision,
-                                        pool,
-                                        &fb->wrapped_file_baton));
+  if (eb->wrapped_editor)
+    SVN_ERR(eb->wrapped_editor->open_file(path,
+                                          pb->wrapped_dir_baton,
+                                          base_revision,
+                                          pool,
+                                          &fb->wrapped_file_baton));
 
   fb->edit_baton = eb;
   *file_baton = fb;
@@ -255,11 +264,38 @@ apply_textdelta(void *file_baton,
   SVN_ERR(svn_stream_printf(eb->out, pool, "apply_textdelta : %s\n",
                             base_checksum));
 
-  SVN_ERR(eb->wrapped_editor->apply_textdelta(fb->wrapped_file_baton,
-                                              base_checksum,
-                                              pool,
-                                              handler,
-                                              handler_baton));
+  if (eb->wrapped_editor)
+    SVN_ERR(eb->wrapped_editor->apply_textdelta(fb->wrapped_file_baton,
+                                                base_checksum,
+                                                pool,
+                                                handler,
+                                                handler_baton));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+apply_textdelta_stream(const struct svn_delta_editor_t *editor,
+                       void *file_baton,
+                       const char *base_checksum,
+                       svn_txdelta_stream_open_func_t open_func,
+                       void *open_baton,
+                       apr_pool_t *scratch_pool)
+{
+  struct file_baton *fb = file_baton;
+  struct edit_baton *eb = fb->edit_baton;
+
+  SVN_ERR(write_indent(eb, scratch_pool));
+  SVN_ERR(svn_stream_printf(eb->out, scratch_pool,
+                            "apply_textdelta_stream : %s\n",
+                            base_checksum));
+
+  if (eb->wrapped_editor)
+    SVN_ERR(eb->wrapped_editor->apply_textdelta_stream(eb->wrapped_editor,
+                                                       fb->wrapped_file_baton,
+                                                       base_checksum,
+                                                       open_func, open_baton,
+                                                       scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -278,8 +314,9 @@ close_file(void *file_baton,
   SVN_ERR(svn_stream_printf(eb->out, pool, "close_file : %s\n",
                             text_checksum));
 
-  SVN_ERR(eb->wrapped_editor->close_file(fb->wrapped_file_baton,
-                                         text_checksum, pool));
+  if (eb->wrapped_editor)
+    SVN_ERR(eb->wrapped_editor->close_file(fb->wrapped_file_baton,
+                                           text_checksum, pool));
 
   return SVN_NO_ERROR;
 }
@@ -295,8 +332,9 @@ absent_file(const char *path,
   SVN_ERR(write_indent(eb, pool));
   SVN_ERR(svn_stream_printf(eb->out, pool, "absent_file : %s\n", path));
 
-  SVN_ERR(eb->wrapped_editor->absent_file(path, fb->wrapped_file_baton,
-                                          pool));
+  if (eb->wrapped_editor)
+    SVN_ERR(eb->wrapped_editor->absent_file(path, fb->wrapped_file_baton,
+                                            pool));
 
   return SVN_NO_ERROR;
 }
@@ -312,8 +350,9 @@ close_directory(void *dir_baton,
   SVN_ERR(write_indent(eb, pool));
   SVN_ERR(svn_stream_printf(eb->out, pool, "close_directory\n"));
 
-  SVN_ERR(eb->wrapped_editor->close_directory(db->wrapped_dir_baton,
-                                              pool));
+  if (eb->wrapped_editor)
+    SVN_ERR(eb->wrapped_editor->close_directory(db->wrapped_dir_baton,
+                                                pool));
 
   return SVN_NO_ERROR;
 }
@@ -330,8 +369,9 @@ absent_directory(const char *path,
   SVN_ERR(svn_stream_printf(eb->out, pool, "absent_directory : %s\n",
                             path));
 
-  SVN_ERR(eb->wrapped_editor->absent_directory(path, db->wrapped_dir_baton,
-                                               pool));
+  if (eb->wrapped_editor)
+    SVN_ERR(eb->wrapped_editor->absent_directory(path, db->wrapped_dir_baton,
+                                                 pool));
 
   return SVN_NO_ERROR;
 }
@@ -349,10 +389,11 @@ change_file_prop(void *file_baton,
   SVN_ERR(svn_stream_printf(eb->out, pool, "change_file_prop : %s -> %s\n",
                             name, value ? value->data : "<deleted>"));
 
-  SVN_ERR(eb->wrapped_editor->change_file_prop(fb->wrapped_file_baton,
-                                               name,
-                                               value,
-                                               pool));
+  if (eb->wrapped_editor)
+    SVN_ERR(eb->wrapped_editor->change_file_prop(fb->wrapped_file_baton,
+                                                 name,
+                                                 value,
+                                                 pool));
 
   return SVN_NO_ERROR;
 }
@@ -370,10 +411,11 @@ change_dir_prop(void *dir_baton,
   SVN_ERR(svn_stream_printf(eb->out, pool, "change_dir_prop : %s -> %s\n",
                             name, value ? value->data : "<deleted>"));
 
-  SVN_ERR(eb->wrapped_editor->change_dir_prop(db->wrapped_dir_baton,
-                                              name,
-                                              value,
-                                              pool));
+  if (eb->wrapped_editor)
+    SVN_ERR(eb->wrapped_editor->change_dir_prop(db->wrapped_dir_baton,
+                                                name,
+                                                value,
+                                                pool));
 
   return SVN_NO_ERROR;
 }
@@ -387,7 +429,8 @@ close_edit(void *edit_baton,
   SVN_ERR(write_indent(eb, pool));
   SVN_ERR(svn_stream_printf(eb->out, pool, "close_edit\n"));
 
-  SVN_ERR(eb->wrapped_editor->close_edit(eb->wrapped_edit_baton, pool));
+  if (eb->wrapped_editor)
+    SVN_ERR(eb->wrapped_editor->close_edit(eb->wrapped_edit_baton, pool));
 
   return SVN_NO_ERROR;
 }
@@ -401,7 +444,8 @@ abort_edit(void *edit_baton,
   SVN_ERR(write_indent(eb, pool));
   SVN_ERR(svn_stream_printf(eb->out, pool, "abort_edit\n"));
 
-  SVN_ERR(eb->wrapped_editor->abort_edit(eb->wrapped_edit_baton, pool));
+  if (eb->wrapped_editor)
+    SVN_ERR(eb->wrapped_editor->abort_edit(eb->wrapped_edit_baton, pool));
 
   return SVN_NO_ERROR;
 }
@@ -414,7 +458,7 @@ svn_delta__get_debug_editor(const svn_de
                             const char *prefix,
                             apr_pool_t *pool)
 {
-  svn_delta_editor_t *tree_editor = apr_palloc(pool, sizeof(*tree_editor));
+  svn_delta_editor_t *tree_editor = svn_delta_default_editor(pool);
   struct edit_baton *eb = apr_palloc(pool, sizeof(*eb));
   apr_file_t *errfp;
   svn_stream_t *out;
@@ -436,6 +480,7 @@ svn_delta__get_debug_editor(const svn_de
   tree_editor->add_file = add_file;
   tree_editor->open_file = open_file;
   tree_editor->apply_textdelta = apply_textdelta;
+  tree_editor->apply_textdelta_stream = apply_textdelta_stream;
   tree_editor->change_file_prop = change_file_prop;
   tree_editor->close_file = close_file;
   tree_editor->absent_file = absent_file;

Modified: subversion/branches/addremove/subversion/libsvn_delta/deprecated.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_delta/deprecated.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_delta/deprecated.c 
(original)
+++ subversion/branches/addremove/subversion/libsvn_delta/deprecated.c Sat May 
23 14:16:56 2020
@@ -30,6 +30,79 @@
 #include "svn_sorts.h"
 
 
+struct path_driver_2_to_3_baton_t
+{
+  svn_delta_path_driver_cb_func_t callback_func;
+  void *callback_baton;
+  svn_boolean_t slash_prefix;
+};
+
+/* Convert from a newer to older callback
+ */
+static svn_error_t *
+path_driver_2_to_3_func(void **dir_baton,
+                        const svn_delta_editor_t *editor,
+                        void *edit_baton,
+                        void *parent_baton,
+                        void *callback_baton,
+                        const char *path,
+                        apr_pool_t *pool)
+{
+  struct path_driver_2_to_3_baton_t *b = callback_baton;
+
+  if (b->slash_prefix)
+    path = apr_pstrcat(pool, "/", path, SVN_VA_NULL);
+
+  /* Just drop the 'editor' parameters */
+  SVN_ERR(b->callback_func(dir_baton, parent_baton,
+                           b->callback_baton,
+                           path, pool));
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_delta_path_driver2(const svn_delta_editor_t *editor,
+                       void *edit_baton,
+                       const apr_array_header_t *paths,
+                       svn_boolean_t sort_paths,
+                       svn_delta_path_driver_cb_func_t callback_func,
+                       void *callback_baton,
+                       apr_pool_t *pool)
+{
+  struct path_driver_2_to_3_baton_t b;
+  int i;
+
+  b.callback_func = callback_func;
+  b.callback_baton = callback_baton;
+  b.slash_prefix = FALSE;
+
+  /* Remove any '/' prefix from incoming paths. Arrange to add a '/'
+     prefix to all paths for the callback, if any incoming path had one. */
+  for (i = 0; i < paths->nelts; i++)
+    {
+      const char *path = APR_ARRAY_IDX(paths, i, const char *);
+
+      if (path[0] == '/')
+        {
+          /* Re-allocate the array and note that we found a '/' prefix. */
+          if (!b.slash_prefix)
+            {
+              paths = apr_array_copy(pool, paths);
+              b.slash_prefix = TRUE;
+            }
+
+          /* Modify each array element that had a '/' prefix */
+          APR_ARRAY_IDX(paths, i, const char *) = path + 1;
+        }
+    }
+
+  SVN_ERR(svn_delta_path_driver3(editor, edit_baton,
+                                 paths, sort_paths,
+                                 path_driver_2_to_3_func, &b,
+                                 pool));
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_delta_path_driver(const svn_delta_editor_t *editor,
                       void *edit_baton,

Modified: subversion/branches/addremove/subversion/libsvn_delta/element.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_delta/element.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_delta/element.c (original)
+++ subversion/branches/addremove/subversion/libsvn_delta/element.c Sat May 23 
14:16:56 2020
@@ -375,14 +375,12 @@ svn_element__tree_get(const svn_element_
   return svn_eid__hash_get(tree->e_map, eid);
 }
 
-svn_error_t *
+void
 svn_element__tree_set(svn_element__tree_t *tree,
                       int eid,
                       const svn_element__content_t *element)
 {
   svn_eid__hash_set(tree->e_map, eid, element);
-
-  return SVN_NO_ERROR;
 }
 
 void

Modified: subversion/branches/addremove/subversion/libsvn_delta/path_driver.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_delta/path_driver.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_delta/path_driver.c 
(original)
+++ subversion/branches/addremove/subversion/libsvn_delta/path_driver.c Sat May 
23 14:16:56 2020
@@ -31,7 +31,6 @@
 #include "svn_dirent_uri.h"
 #include "svn_path.h"
 #include "svn_sorts.h"
-#include "private/svn_fspath.h"
 #include "private/svn_sorts_private.h"
 
 
@@ -45,6 +44,22 @@ typedef struct dir_stack_t
 } dir_stack_t;
 
 
+/* Push onto dir_stack a new item allocated in POOL and containing
+ * DIR_BATON and POOL.
+ */
+static void
+push_dir_stack_item(apr_array_header_t *db_stack,
+                    void *dir_baton,
+                    apr_pool_t *pool)
+{
+  dir_stack_t *item = apr_pcalloc(pool, sizeof(*item));
+
+  item->dir_baton = dir_baton;
+  item->pool = pool;
+  APR_ARRAY_PUSH(db_stack, dir_stack_t *) = item;
+}
+
+
 /* Call EDITOR's open_directory() function with the PATH argument, then
  * add the resulting dir baton to the dir baton stack.
  */
@@ -72,10 +87,7 @@ open_dir(apr_array_header_t *db_stack,
                                  &db));
 
   /* Now add the dir baton to the stack. */
-  item = apr_pcalloc(subpool, sizeof(*item));
-  item->dir_baton = db;
-  item->pool = subpool;
-  APR_ARRAY_PUSH(db_stack, dir_stack_t *) = item;
+  push_dir_stack_item(db_stack, db, subpool);
 
   return SVN_NO_ERROR;
 }
@@ -131,168 +143,215 @@ count_components(const char *path)
 
 /*** Public interfaces ***/
 svn_error_t *
-svn_delta_path_driver2(const svn_delta_editor_t *editor,
+svn_delta_path_driver3(const svn_delta_editor_t *editor,
                        void *edit_baton,
-                       const apr_array_header_t *paths,
+                       const apr_array_header_t *relpaths,
                        svn_boolean_t sort_paths,
-                       svn_delta_path_driver_cb_func_t callback_func,
+                       svn_delta_path_driver_cb_func2_t callback_func,
                        void *callback_baton,
                        apr_pool_t *pool)
 {
-  apr_array_header_t *db_stack = apr_array_make(pool, 4, sizeof(void *));
-  const char *last_path = NULL;
-  int i = 0;
-  void *parent_db = NULL, *db = NULL;
-  const char *path;
+  svn_delta_path_driver_state_t *state;
+  int i;
   apr_pool_t *subpool, *iterpool;
-  dir_stack_t *item;
 
   /* Do nothing if there are no paths. */
-  if (! paths->nelts)
+  if (! relpaths->nelts)
     return SVN_NO_ERROR;
 
   subpool = svn_pool_create(pool);
   iterpool = svn_pool_create(pool);
 
   /* sort paths if necessary */
-  if (sort_paths && paths->nelts > 1)
+  if (sort_paths && relpaths->nelts > 1)
     {
-      apr_array_header_t *sorted = apr_array_copy(subpool, paths);
+      apr_array_header_t *sorted = apr_array_copy(subpool, relpaths);
       svn_sort__array(sorted, svn_sort_compare_paths);
-      paths = sorted;
+      relpaths = sorted;
     }
 
-  item = apr_pcalloc(subpool, sizeof(*item));
-
-  /* If the root of the edit is also a target path, we want to call
-     the callback function to let the user open the root directory and
-     do what needs to be done.  Otherwise, we'll do the open_root()
-     ourselves. */
-  path = APR_ARRAY_IDX(paths, 0, const char *);
-  if (svn_path_is_empty(path))
-    {
-      SVN_ERR(callback_func(&db, NULL, callback_baton, path, subpool));
-      last_path = path;
-      i++;
-    }
-  else
-    {
-      SVN_ERR(editor->open_root(edit_baton, SVN_INVALID_REVNUM, subpool, &db));
-    }
-  item->pool = subpool;
-  item->dir_baton = db;
-  APR_ARRAY_PUSH(db_stack, void *) = item;
+  SVN_ERR(svn_delta_path_driver_start(&state,
+                                      editor, edit_baton,
+                                      callback_func, callback_baton,
+                                      pool));
 
   /* Now, loop over the commit items, traversing the URL tree and
      driving the editor. */
-  for (; i < paths->nelts; i++)
+  for (i = 0; i < relpaths->nelts; i++)
     {
-      const char *pdir;
-      const char *common = "";
-      size_t common_len;
+      const char *relpath;
 
       /* Clear the iteration pool. */
       svn_pool_clear(iterpool);
 
       /* Get the next path. */
-      path = APR_ARRAY_IDX(paths, i, const char *);
+      relpath = APR_ARRAY_IDX(relpaths, i, const char *);
 
-      /*** Step A - Find the common ancestor of the last path and the
-           current one.  For the first iteration, this is just the
-           empty string. ***/
-      if (i > 0)
-        common = (last_path[0] == '/')
-          ? svn_fspath__get_longest_ancestor(last_path, path, iterpool)
-          : svn_relpath_get_longest_ancestor(last_path, path, iterpool);
-      common_len = strlen(common);
-
-      /*** Step B - Close any directories between the last path and
-           the new common ancestor, if any need to be closed.
-           Sometimes there is nothing to do here (like, for the first
-           iteration, or when the last path was an ancestor of the
-           current one). ***/
-      if ((i > 0) && (strlen(last_path) > common_len))
-        {
-          const char *rel = last_path + (common_len ? (common_len + 1) : 0);
-          int count = count_components(rel);
-          while (count--)
-            {
-              SVN_ERR(pop_stack(db_stack, editor));
-            }
-        }
+      SVN_ERR(svn_delta_path_driver_step(state, relpath, iterpool));
+    }
 
-      /*** Step C - Open any directories between the common ancestor
-           and the parent of the current path. ***/
-      if (*path == '/')
-        pdir = svn_fspath__dirname(path, iterpool);
-      else
-        pdir = svn_relpath_dirname(path, iterpool);
+  /* Destroy the iteration subpool. */
+  svn_pool_destroy(iterpool);
 
-      if (strlen(pdir) > common_len)
-        {
-          const char *piece = pdir + common_len + 1;
+  SVN_ERR(svn_delta_path_driver_finish(state, pool));
 
-          while (1)
-            {
-              const char *rel = pdir;
-
-              /* Find the first separator. */
-              piece = strchr(piece, '/');
-
-              /* Calculate REL as the portion of PDIR up to (but not
-                 including) the location to which PIECE is pointing. */
-              if (piece)
-                rel = apr_pstrmemdup(iterpool, pdir, piece - pdir);
-
-              /* Open the subdirectory. */
-              SVN_ERR(open_dir(db_stack, editor, rel, pool));
-
-              /* If we found a '/', advance our PIECE pointer to
-                 character just after that '/'.  Otherwise, we're
-                 done.  */
-              if (piece)
-                piece++;
-              else
-                break;
-            }
-        }
+  return SVN_NO_ERROR;
+}
 
-      /*** Step D - Tell our caller to handle the current path. ***/
-      item = APR_ARRAY_IDX(db_stack, db_stack->nelts - 1, void *);
-      parent_db = item->dir_baton;
-      subpool = svn_pool_create(pool);
-      SVN_ERR(callback_func(&db, parent_db, callback_baton, path, subpool));
-      if (db)
+struct svn_delta_path_driver_state_t
+{
+  const svn_delta_editor_t *editor;
+  void *edit_baton;
+  svn_delta_path_driver_cb_func2_t callback_func;
+  void *callback_baton;
+  apr_array_header_t *db_stack;
+  const char *last_path;
+  apr_pool_t *pool;  /* at least the lifetime of the entire drive */
+};
+
+svn_error_t *
+svn_delta_path_driver_start(svn_delta_path_driver_state_t **state_p,
+                            const svn_delta_editor_t *editor,
+                            void *edit_baton,
+                            svn_delta_path_driver_cb_func2_t callback_func,
+                            void *callback_baton,
+                            apr_pool_t *pool)
+{
+  svn_delta_path_driver_state_t *state = apr_pcalloc(pool, sizeof(*state));
+
+  state->editor = editor;
+  state->edit_baton = edit_baton;
+  state->callback_func = callback_func;
+  state->callback_baton = callback_baton;
+  state->db_stack = apr_array_make(pool, 4, sizeof(void *));
+  state->last_path = NULL;
+  state->pool = pool;
+
+  *state_p = state;
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_delta_path_driver_step(svn_delta_path_driver_state_t *state,
+                           const char *relpath,
+                           apr_pool_t *scratch_pool)
+{
+  const char *pdir;
+  const char *common = "";
+  size_t common_len;
+  apr_pool_t *subpool;
+  dir_stack_t *item;
+  void *parent_db, *db;
+
+  SVN_ERR_ASSERT(svn_relpath_is_canonical(relpath));
+
+  /* If the first target path is not the root of the edit, we must first
+     call open_root() ourselves. (If the first target path is the root of
+     the edit, then we expect the user's callback to do so.) */
+  if (!state->last_path && !svn_path_is_empty(relpath))
+    {
+      subpool = svn_pool_create(state->pool);
+      SVN_ERR(state->editor->open_root(state->edit_baton, SVN_INVALID_REVNUM,
+                                       subpool, &db));
+      push_dir_stack_item(state->db_stack, db, subpool);
+    }
+
+  /*** Step A - Find the common ancestor of the last path and the
+       current one.  For the first iteration, this is just the
+       empty string. ***/
+  if (state->last_path)
+    common = svn_relpath_get_longest_ancestor(state->last_path, relpath,
+                                              scratch_pool);
+  common_len = strlen(common);
+
+  /*** Step B - Close any directories between the last path and
+       the new common ancestor, if any need to be closed.
+       Sometimes there is nothing to do here (like, for the first
+       iteration, or when the last path was an ancestor of the
+       current one). ***/
+  if ((state->last_path) && (strlen(state->last_path) > common_len))
+    {
+      const char *rel = state->last_path + (common_len ? (common_len + 1) : 0);
+      int count = count_components(rel);
+      while (count--)
         {
-          item = apr_pcalloc(subpool, sizeof(*item));
-          item->dir_baton = db;
-          item->pool = subpool;
-          APR_ARRAY_PUSH(db_stack, void *) = item;
+          SVN_ERR(pop_stack(state->db_stack, state->editor));
         }
-      else
+    }
+
+  /*** Step C - Open any directories between the common ancestor
+       and the parent of the current path. ***/
+  pdir = svn_relpath_dirname(relpath, scratch_pool);
+
+  if (strlen(pdir) > common_len)
+    {
+      const char *piece = pdir + common_len + 1;
+
+      while (1)
         {
-          svn_pool_destroy(subpool);
+          const char *rel = pdir;
+
+          /* Find the first separator. */
+          piece = strchr(piece, '/');
+
+          /* Calculate REL as the portion of PDIR up to (but not
+             including) the location to which PIECE is pointing. */
+          if (piece)
+            rel = apr_pstrmemdup(scratch_pool, pdir, piece - pdir);
+
+          /* Open the subdirectory. */
+          SVN_ERR(open_dir(state->db_stack, state->editor, rel, state->pool));
+
+          /* If we found a '/', advance our PIECE pointer to
+             character just after that '/'.  Otherwise, we're
+             done.  */
+          if (piece)
+            piece++;
+          else
+            break;
         }
+    }
 
-      /*** Step E - Save our state for the next iteration.  If our
-           caller opened or added PATH as a directory, that becomes
-           our LAST_PATH.  Otherwise, we use PATH's parent
-           directory. ***/
-
-      /* NOTE:  The variable LAST_PATH needs to outlive the loop. */
-      if (db)
-        last_path = path; /* lives in a pool outside our control. */
-      else
-        last_path = apr_pstrdup(pool, pdir); /* duping into POOL. */
+  /*** Step D - Tell our caller to handle the current path. ***/
+  if (state->db_stack->nelts)
+    {
+      item = APR_ARRAY_IDX(state->db_stack, state->db_stack->nelts - 1, void 
*);
+      parent_db = item->dir_baton;
+    }
+  else
+    parent_db = NULL;
+  db = NULL;  /* predictable behaviour for callbacks that don't set it */
+  subpool = svn_pool_create(state->pool);
+  SVN_ERR(state->callback_func(&db,
+                               state->editor, state->edit_baton, parent_db,
+                               state->callback_baton,
+                               relpath, subpool));
+  if (db)
+    {
+      push_dir_stack_item(state->db_stack, db, subpool);
+    }
+  else
+    {
+      svn_pool_destroy(subpool);
     }
 
-  /* Destroy the iteration subpool. */
-  svn_pool_destroy(iterpool);
+  /*** Step E - Save our state for the next iteration.  If our
+       caller opened or added PATH as a directory, that becomes
+       our LAST_PATH.  Otherwise, we use PATH's parent
+       directory. ***/
+  state->last_path = apr_pstrdup(state->pool, db ? relpath : pdir);
+
+  return SVN_NO_ERROR;
+}
 
+svn_error_t *
+svn_delta_path_driver_finish(svn_delta_path_driver_state_t *state,
+                             apr_pool_t *scratch_pool)
+{
   /* Close down any remaining open directory batons. */
-  while (db_stack->nelts)
+  while (state->db_stack->nelts)
     {
-      SVN_ERR(pop_stack(db_stack, editor));
+      SVN_ERR(pop_stack(state->db_stack, state->editor));
     }
 
   return SVN_NO_ERROR;

Modified: subversion/branches/addremove/subversion/libsvn_delta/svndiff.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_delta/svndiff.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_delta/svndiff.c (original)
+++ subversion/branches/addremove/subversion/libsvn_delta/svndiff.c Sat May 23 
14:16:56 2020
@@ -396,7 +396,7 @@ struct decode_baton
 };
 
 
-/* Wrapper aroung svn__deencode_uint taking a file size as *VAL. */
+/* Wrapper around svn__deencode_uint taking a file size as *VAL. */
 static const unsigned char *
 decode_file_offset(svn_filesize_t *val,
                    const unsigned char *p,
@@ -1026,11 +1026,11 @@ svndiff_stream_read_fn(void *baton, char
   apr_size_t left = *len;
   apr_size_t read = 0;
 
-  while (left && !b->hit_eof)
+  while (left)
     {
       apr_size_t chunk_size;
 
-      if (b->read_pos == b->window_buffer->len)
+      if (b->read_pos == b->window_buffer->len && !b->hit_eof)
         {
           svn_txdelta_window_t *window;
 
@@ -1050,6 +1050,9 @@ svndiff_stream_read_fn(void *baton, char
       else
         chunk_size = left;
 
+      if (!chunk_size)
+          break;
+
       memcpy(buffer, b->window_buffer->data + b->read_pos, chunk_size);
       b->read_pos += chunk_size;
       buffer += chunk_size;

Modified: subversion/branches/addremove/subversion/libsvn_delta/xdelta.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_delta/xdelta.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_delta/xdelta.c (original)
+++ subversion/branches/addremove/subversion/libsvn_delta/xdelta.c Sat May 23 
14:16:56 2020
@@ -124,7 +124,7 @@ struct blocks
      This value has an upper bound proportionate to the text delta
      window size, so unless we dramatically increase the window size,
      it's safe to make this a 32-bit value.  In any case, it has to be
-     hte same width as the block position index, (struct
+     the same width as the block position index, (struct
      block).pos. */
   apr_uint32_t max;
 

Modified: subversion/branches/addremove/subversion/libsvn_diff/deprecated.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_diff/deprecated.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_diff/deprecated.c (original)
+++ subversion/branches/addremove/subversion/libsvn_diff/deprecated.c Sat May 
23 14:16:56 2020
@@ -409,7 +409,7 @@ svn_diff_mem_string_output_merge2(svn_st
                                                            conflict_latest,
                                                            conflict_separator,
                                                            style,
-                                                           /* no cancelation */
+                                                           /* no cancellation 
*/
                                                            NULL, NULL,
                                                            pool));
 }

Modified: subversion/branches/addremove/subversion/libsvn_diff/diff_file.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_diff/diff_file.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_diff/diff_file.c (original)
+++ subversion/branches/addremove/subversion/libsvn_diff/diff_file.c Sat May 23 
14:16:56 2020
@@ -1095,7 +1095,7 @@ token_compare(void *baton, void *token1,
           if (length[i] == 0)
             {
               /* Error if raw_length is 0, that's an unexpected change
-               * of the file that can happen when ingoring whitespace
+               * of the file that can happen when ignoring whitespace
                * and that can lead to an infinite loop. */
               if (raw_length[i] == 0)
                 return svn_error_createf(SVN_ERR_DIFF_DATASOURCE_MODIFIED,
@@ -1253,7 +1253,7 @@ svn_diff_file_options_parse(svn_diff_fil
   apr_array_cat(argv, args);
   APR_ARRAY_PUSH(argv, const char *) = NULL;
 
-  apr_getopt_init(&os, pool, 
+  apr_getopt_init(&os, pool,
                   argv->nelts - 1 /* Exclude trailing NULL */,
                   (const char *const *) argv->elts);
 

Modified: subversion/branches/addremove/subversion/libsvn_diff/diff_tree.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_diff/diff_tree.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_diff/diff_tree.c (original)
+++ subversion/branches/addremove/subversion/libsvn_diff/diff_tree.c Sat May 23 
14:16:56 2020
@@ -37,14 +37,6 @@
 #include "private/svn_diff_tree.h"
 #include "svn_private_config.h"
 
-typedef struct tree_processor_t
-{
-  svn_diff_tree_processor_t tp;
-
-  /* void *future_extension */
-} tree_processor_t;
-
-
 static svn_error_t *
 default_dir_opened(void **new_dir_baton,
                    svn_boolean_t *skip,
@@ -215,33 +207,30 @@ svn_diff_tree_processor_t *
 svn_diff__tree_processor_create(void *baton,
                                 apr_pool_t *result_pool)
 {
-  tree_processor_t *wrapper;
-  wrapper = apr_pcalloc(result_pool, sizeof(*wrapper));
+  svn_diff_tree_processor_t *tp = apr_pcalloc(result_pool, sizeof(*tp));
 
-  wrapper->tp.baton        = baton;
+  tp->baton        = baton;
 
-  wrapper->tp.dir_opened   = default_dir_opened;
-  wrapper->tp.dir_added    = default_dir_added;
-  wrapper->tp.dir_deleted  = default_dir_deleted;
-  wrapper->tp.dir_changed  = default_dir_changed;
-  wrapper->tp.dir_closed   = default_dir_closed;
+  tp->dir_opened   = default_dir_opened;
+  tp->dir_added    = default_dir_added;
+  tp->dir_deleted  = default_dir_deleted;
+  tp->dir_changed  = default_dir_changed;
+  tp->dir_closed   = default_dir_closed;
 
-  wrapper->tp.file_opened   = default_file_opened;
-  wrapper->tp.file_added    = default_file_added;
-  wrapper->tp.file_deleted  = default_file_deleted;
-  wrapper->tp.file_changed  = default_file_changed;
-  wrapper->tp.file_closed   = default_file_closed;
+  tp->file_opened  = default_file_opened;
+  tp->file_added   = default_file_added;
+  tp->file_deleted = default_file_deleted;
+  tp->file_changed = default_file_changed;
+  tp->file_closed  = default_file_closed;
 
-  wrapper->tp.node_absent   = default_node_absent;
+  tp->node_absent  = default_node_absent;
 
-
-  return &wrapper->tp;
+  return tp;
 }
 
 struct reverse_tree_baton_t
 {
   const svn_diff_tree_processor_t *processor;
-  const char *prefix_relpath;
 };
 
 static svn_error_t *
@@ -259,9 +248,6 @@ reverse_dir_opened(void **new_dir_baton,
 {
   struct reverse_tree_baton_t *rb = processor->baton;
 
-  if (rb->prefix_relpath)
-    relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool);
-
   SVN_ERR(rb->processor->dir_opened(new_dir_baton, skip, skip_children,
                                     relpath,
                                     right_source, left_source,
@@ -284,9 +270,6 @@ reverse_dir_added(const char *relpath,
 {
   struct reverse_tree_baton_t *rb = processor->baton;
 
-  if (rb->prefix_relpath)
-    relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool);
-
   SVN_ERR(rb->processor->dir_deleted(relpath,
                                      right_source,
                                      right_props,
@@ -307,9 +290,6 @@ reverse_dir_deleted(const char *relpath,
 {
   struct reverse_tree_baton_t *rb = processor->baton;
 
-  if (rb->prefix_relpath)
-    relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool);
-
   SVN_ERR(rb->processor->dir_added(relpath,
                                    NULL,
                                    left_source,
@@ -335,9 +315,6 @@ reverse_dir_changed(const char *relpath,
   struct reverse_tree_baton_t *rb = processor->baton;
   apr_array_header_t *reversed_prop_changes = NULL;
 
-  if (rb->prefix_relpath)
-    relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool);
-
   if (prop_changes)
     {
       SVN_ERR_ASSERT(left_props != NULL && right_props != NULL);
@@ -367,9 +344,6 @@ reverse_dir_closed(const char *relpath,
 {
   struct reverse_tree_baton_t *rb = processor->baton;
 
-  if (rb->prefix_relpath)
-    relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool);
-
   SVN_ERR(rb->processor->dir_closed(relpath,
                                     right_source,
                                     left_source,
@@ -393,9 +367,6 @@ reverse_file_opened(void **new_file_bato
 {
   struct reverse_tree_baton_t *rb = processor->baton;
 
-  if (rb->prefix_relpath)
-    relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool);
-
   SVN_ERR(rb->processor->file_opened(new_file_baton,
                                      skip,
                                      relpath,
@@ -423,9 +394,6 @@ reverse_file_added(const char *relpath,
 {
   struct reverse_tree_baton_t *rb = processor->baton;
 
-  if (rb->prefix_relpath)
-    relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool);
-
   SVN_ERR(rb->processor->file_deleted(relpath,
                                       right_source,
                                       right_file,
@@ -447,9 +415,6 @@ reverse_file_deleted(const char *relpath
 {
   struct reverse_tree_baton_t *rb = processor->baton;
 
-  if (rb->prefix_relpath)
-    relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool);
-
   SVN_ERR(rb->processor->file_added(relpath,
                                     NULL /* copyfrom src */,
                                     left_source,
@@ -480,9 +445,6 @@ reverse_file_changed(const char *relpath
   struct reverse_tree_baton_t *rb = processor->baton;
   apr_array_header_t *reversed_prop_changes = NULL;
 
-  if (rb->prefix_relpath)
-    relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool);
-
   if (prop_changes)
     {
       SVN_ERR_ASSERT(left_props != NULL && right_props != NULL);
@@ -515,9 +477,6 @@ reverse_file_closed(const char *relpath,
 {
   struct reverse_tree_baton_t *rb = processor->baton;
 
-  if (rb->prefix_relpath)
-    relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool);
-
   SVN_ERR(rb->processor->file_closed(relpath,
                                      right_source,
                                      left_source,
@@ -536,9 +495,6 @@ reverse_node_absent(const char *relpath,
 {
   struct reverse_tree_baton_t *rb = processor->baton;
 
-  if (rb->prefix_relpath)
-    relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool);
-
   SVN_ERR(rb->processor->node_absent(relpath,
                                     dir_baton,
                                     rb->processor,
@@ -549,7 +505,6 @@ reverse_node_absent(const char *relpath,
 
 const svn_diff_tree_processor_t *
 svn_diff__tree_processor_reverse_create(const svn_diff_tree_processor_t * 
processor,
-                                        const char *prefix_relpath,
                                         apr_pool_t *result_pool)
 {
   struct reverse_tree_baton_t *rb;
@@ -557,8 +512,6 @@ svn_diff__tree_processor_reverse_create(
 
   rb = apr_pcalloc(result_pool, sizeof(*rb));
   rb->processor = processor;
-  if (prefix_relpath)
-    rb->prefix_relpath = apr_pstrdup(result_pool, prefix_relpath);
 
   reverse = svn_diff__tree_processor_create(rb, result_pool);
 

Modified: subversion/branches/addremove/subversion/libsvn_diff/parse-diff.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_diff/parse-diff.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_diff/parse-diff.c (original)
+++ subversion/branches/addremove/subversion/libsvn_diff/parse-diff.c Sat May 
23 14:16:56 2020
@@ -69,6 +69,11 @@ struct svn_diff_hunk_t {
   /* APR file handle to the patch file this hunk came from. */
   apr_file_t *apr_file;
 
+  /* Whether the hunk was interpreted as pretty-print mergeinfo. If so,
+     the hunk content is in PATCH and the rest of this hunk object is
+     mostly uninitialized. */
+  svn_boolean_t is_pretty_print_mergeinfo;
+
   /* Ranges used to keep track of this hunk's texts positions within
    * the patch file. */
   struct svn_diff__hunk_range diff_text_range;
@@ -210,7 +215,7 @@ svn_diff_hunk__create_adds_single_line(s
                                        apr_pool_t *result_pool,
                                        apr_pool_t *scratch_pool)
 {
-  SVN_ERR(add_or_delete_single_line(hunk_out, line, patch, 
+  SVN_ERR(add_or_delete_single_line(hunk_out, line, patch,
                                     (!patch->reverse),
                                     result_pool, scratch_pool));
   return SVN_NO_ERROR;
@@ -899,10 +904,6 @@ parse_prop_name(const char **prop_name,
  * The hunk header has the following format:
  * ## -0,NUMBER_OF_REVERSE_MERGES +0,NUMBER_OF_FORWARD_MERGES ##
  *
- * At this point, the number of reverse merges has already been
- * parsed into HUNK->ORIGINAL_LENGTH, and the number of forward
- * merges has been parsed into HUNK->MODIFIED_LENGTH.
- *
  * The header is followed by a list of mergeinfo, one path per line.
  * This function parses such lines. Lines describing reverse merges
  * appear first, and then all lines describing forward merges appear.
@@ -914,18 +915,27 @@ parse_prop_name(const char **prop_name,
  * ":r", which in turn is followed by a mergeinfo revision range,
  *  which is terminated by whitespace or end-of-string.
  *
- * If the current line meets the above criteria and we're able
- * to parse valid mergeinfo from it, the resulting mergeinfo
- * is added to patch->mergeinfo or patch->reverse_mergeinfo,
- * and we proceed to the next line.
+ * *NUMBER_OF_REVERSE_MERGES and *NUMBER_OF_FORWARD_MERGES are the
+ * numbers of reverse and forward merges remaining to be read. This
+ * function decrements *NUMBER_OF_REVERSE_MERGES for each LINE
+ * parsed until that is zero, then *NUMBER_OF_FORWARD_MERGES for
+ * each LINE parsed until that is zero. If both are zero, it parses
+ * and discards LINE.
+ *
+ * If LINE is successfully parsed, *FOUND_MERGEINFO is set to TRUE,
+ * otherwise to FALSE.
+ *
+ * If LINE is successfully parsed and counted, the resulting mergeinfo
+ * is added to PATCH->mergeinfo or PATCH->reverse_mergeinfo.
  */
 static svn_error_t *
-parse_mergeinfo(svn_boolean_t *found_mergeinfo,
-                svn_stringbuf_t *line,
-                svn_diff_hunk_t *hunk,
-                svn_patch_t *patch,
-                apr_pool_t *result_pool,
-                apr_pool_t *scratch_pool)
+parse_pretty_mergeinfo_line(svn_boolean_t *found_mergeinfo,
+                            svn_linenum_t *number_of_reverse_merges,
+                            svn_linenum_t *number_of_forward_merges,
+                            svn_stringbuf_t *line,
+                            svn_patch_t *patch,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool)
 {
   char *slash = strchr(line->data, '/');
   char *colon = strrchr(line->data, ':');
@@ -972,7 +982,7 @@ parse_mergeinfo(svn_boolean_t *found_mer
 
       if (mergeinfo)
         {
-          if (hunk->original_length > 0) /* reverse merges */
+          if (*number_of_reverse_merges > 0) /* reverse merges */
             {
               if (patch->reverse)
                 {
@@ -994,9 +1004,9 @@ parse_mergeinfo(svn_boolean_t *found_mer
                                                  result_pool,
                                                  scratch_pool));
                 }
-              hunk->original_length--;
+              (*number_of_reverse_merges)--;
             }
-          else if (hunk->modified_length > 0) /* forward merges */
+          else if (number_of_forward_merges > 0) /* forward merges */
             {
               if (patch->reverse)
                 {
@@ -1018,7 +1028,7 @@ parse_mergeinfo(svn_boolean_t *found_mer
                                                  result_pool,
                                                  scratch_pool));
                 }
-              hunk->modified_length--;
+              (*number_of_forward_merges)--;
             }
 
           *found_mergeinfo = TRUE;
@@ -1165,18 +1175,48 @@ parse_next_hunk(svn_diff_hunk_t **hunk,
       if (in_hunk && *is_property && *prop_name &&
           strcmp(*prop_name, SVN_PROP_MERGEINFO) == 0)
         {
-          svn_boolean_t found_mergeinfo;
+          svn_boolean_t found_pretty_mergeinfo_line;
 
-          SVN_ERR(parse_mergeinfo(&found_mergeinfo, line, *hunk, patch,
-                                  result_pool, iterpool));
-          if (found_mergeinfo)
-            continue; /* Proceed to the next line in the svn:mergeinfo hunk. */
-          else
+          if (! hunk_seen)
             {
-              /* Perhaps we can also use original_lines/modified_lines here */
+              /* We're reading the first line of the hunk, so the start
+               * of the line just read is the hunk text's byte offset. */
+              start = last_line;
+            }
 
-              in_hunk = FALSE; /* On to next property */
+          SVN_ERR(parse_pretty_mergeinfo_line(&found_pretty_mergeinfo_line,
+                                              &original_lines, &modified_lines,
+                                              line, patch,
+                                              result_pool, iterpool));
+          if (found_pretty_mergeinfo_line)
+            {
+              hunk_seen = TRUE;
+              (*hunk)->is_pretty_print_mergeinfo = TRUE;
+              continue; /* Proceed to the next line in the svn:mergeinfo hunk. 
*/
             }
+
+          if ((*hunk)->is_pretty_print_mergeinfo)
+            {
+              /* We have reached the end of the pretty-print-mergeinfo hunk.
+                 (This format uses only one hunk.) */
+              if (eof)
+                {
+                  /* The hunk ends at EOF. */
+                  end = pos;
+                }
+              else
+                {
+                  /* The start of the current line marks the first byte
+                   * after the hunk text. */
+                  end = last_line;
+                }
+              original_end = end;
+              modified_end = end;
+              break;
+            }
+
+          /* Otherwise, this is a property diff in the
+             regular format so fall through to normal processing. */
         }
 
       if (in_hunk)
@@ -1195,7 +1235,7 @@ parse_next_hunk(svn_diff_hunk_t **hunk,
           c = line->data[0];
           if (c == ' '
               || ((original_lines > 0 && modified_lines > 0)
-                  && ( 
+                  && (
                /* Tolerate chopped leading spaces on empty lines. */
                       (! eof && line->len == 0)
                /* Maybe tolerate chopped leading spaces on non-empty lines. */
@@ -1971,10 +2011,10 @@ parse_hunks(svn_patch_t *patch, apr_file
           else
             last_prop_name = prop_name;
 
-          /* Skip svn:mergeinfo properties.
-           * Mergeinfo data cannot be represented as a hunk and
+          /* Skip pretty-printed svn:mergeinfo property hunks.
+           * Pretty-printed mergeinfo data cannot be represented as a hunk and
            * is therefore stored in PATCH itself. */
-          if (strcmp(prop_name, SVN_PROP_MERGEINFO) == 0)
+          if (hunk->is_pretty_print_mergeinfo)
             continue;
 
           SVN_ERR(add_property_hunk(patch, prop_name, hunk, prop_operation,
@@ -2045,7 +2085,7 @@ parse_binary_patch(svn_patch_t *patch, a
           else if (in_src)
             {
               patch->binary_patch = bpatch; /* SUCCESS! */
-              break; 
+              break;
             }
           else
             {

Modified: subversion/branches/addremove/subversion/libsvn_fs/fs-loader.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs/fs-loader.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs/fs-loader.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs/fs-loader.c Sat May 23 
14:16:56 2020
@@ -438,7 +438,7 @@ svn_fs_initialize(apr_pool_t *pool)
 static void
 default_warning_func(void *baton, svn_error_t *err)
 {
-  /* The one unforgiveable sin is to fail silently.  Dumping to stderr
+  /* The one unforgivable sin is to fail silently.  Dumping to stderr
      or /dev/tty is not acceptable default behavior for server
      processes, since those may both be equivalent to /dev/null.
 
@@ -2221,3 +2221,42 @@ svn_fs_info_dup(const void *info_void,
     return apr_pmemdup(result_pool, info, sizeof(*info));
 }
 
+svn_error_t *
+svn_fs_ioctl(svn_fs_t *fs,
+             svn_fs_ioctl_code_t ctlcode,
+             void *input,
+             void **output_p,
+             svn_cancel_func_t cancel_func,
+             void *cancel_baton,
+             apr_pool_t *result_pool,
+             apr_pool_t *scratch_pool)
+{
+  void *output;
+
+  if (fs)
+    {
+      if (!fs->vtable->ioctl)
+        return svn_error_create(SVN_ERR_FS_UNRECOGNIZED_IOCTL_CODE, NULL, 
NULL);
+
+      SVN_ERR(fs->vtable->ioctl(fs, ctlcode, input, &output,
+                                cancel_func, cancel_baton,
+                                result_pool, scratch_pool));
+    }
+  else
+    {
+      fs_library_vtable_t *vtable;
+
+      SVN_ERR(get_library_vtable(&vtable, ctlcode.fs_type, scratch_pool));
+
+      if (!vtable->ioctl)
+        return svn_error_create(SVN_ERR_FS_UNRECOGNIZED_IOCTL_CODE, NULL, 
NULL);
+
+      SVN_ERR(vtable->ioctl(ctlcode, input, &output,
+                            cancel_func, cancel_baton,
+                            result_pool, scratch_pool));
+    }
+
+  if (output_p)
+    *output_p = output;
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/addremove/subversion/libsvn_fs/fs-loader.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs/fs-loader.h?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs/fs-loader.h (original)
+++ subversion/branches/addremove/subversion/libsvn_fs/fs-loader.h Sat May 23 
14:16:56 2020
@@ -159,6 +159,13 @@ typedef struct fs_library_vtable_t
   /* For svn_fs_info_fsfs_dup(). */
   void *(*info_fsap_dup)(const void *fsap_info,
                          apr_pool_t *result_pool);
+
+  svn_error_t *(*ioctl)(svn_fs_ioctl_code_t ctlcode,
+                        void *input, void **output_p,
+                        svn_cancel_func_t cancel_func,
+                        void *cancel_baton,
+                        apr_pool_t *result_pool,
+                        apr_pool_t *scratch_pool);
 } fs_library_vtable_t;
 
 /* This is the type of symbol an FS module defines to fetch the
@@ -200,12 +207,12 @@ typedef struct fs_vtable_t
   svn_error_t *(*revision_prop)(svn_string_t **value_p, svn_fs_t *fs,
                                 svn_revnum_t rev, const char *propname,
                                 svn_boolean_t refresh,
-                                apr_pool_t *result_pool, 
+                                apr_pool_t *result_pool,
                                 apr_pool_t *scratch_pool);
   svn_error_t *(*revision_proplist)(apr_hash_t **table_p, svn_fs_t *fs,
                                     svn_revnum_t rev,
                                     svn_boolean_t refresh,
-                                    apr_pool_t *result_pool, 
+                                    apr_pool_t *result_pool,
                                     apr_pool_t *scratch_pool);
   svn_error_t *(*change_rev_prop)(svn_fs_t *fs, svn_revnum_t rev,
                                   const char *name,
@@ -266,6 +273,12 @@ typedef struct fs_vtable_t
   svn_error_t *(*bdb_set_errcall)(svn_fs_t *fs,
                                   void (*handler)(const char *errpfx,
                                                   char *msg));
+  svn_error_t *(*ioctl)(svn_fs_t *fs, svn_fs_ioctl_code_t ctlcode,
+                        void *input, void **output_p,
+                        svn_cancel_func_t cancel_func,
+                        void *cancel_baton,
+                        apr_pool_t *result_pool,
+                        apr_pool_t *scratch_pool);
 } fs_vtable_t;
 
 

Modified: 
subversion/branches/addremove/subversion/libsvn_fs_base/bdb/locks-table.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_base/bdb/locks-table.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_base/bdb/locks-table.c 
(original)
+++ subversion/branches/addremove/subversion/libsvn_fs_base/bdb/locks-table.c 
Sat May 23 14:16:56 2020
@@ -261,7 +261,7 @@ svn_fs_bdb__locks_get(svn_fs_t *fs,
   lookup_len = strlen(lookup_path);
 
   /* As long as the prefix of the returned KEY matches LOOKUP_PATH we
-     know it is either LOOKUP_PATH or a decendant thereof.  */
+     know it is either LOOKUP_PATH or a descendant thereof.  */
   while ((! db_err)
          && lookup_len < key.size
          && strncmp(lookup_path, key.data, lookup_len) == 0)

Modified: subversion/branches/addremove/subversion/libsvn_fs_base/fs.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_base/fs.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_base/fs.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_base/fs.c Sat May 23 
14:16:56 2020
@@ -574,6 +574,7 @@ static fs_vtable_t fs_vtable = {
   base_bdb_verify_root,
   base_bdb_freeze,
   base_bdb_set_errcall,
+  NULL /* ioctl */
 };
 
 /* Where the format number is stored. */
@@ -906,7 +907,7 @@ bdb_recover(const char *path, svn_boolea
      will simply join it instead, and will then be running with
      incorrectly sized (and probably terribly small) caches.  */
 
-  /* Note that since we're using a private environment, we shoudl
+  /* Note that since we're using a private environment, we should
      /not/ initialize locking. We want the environment files to go
      away. */
 
@@ -1077,7 +1078,7 @@ base_bdb_logfiles(apr_array_header_t **l
 /* Copying a live Berkeley DB-base filesystem.  */
 
 /**
- * Delete all unused log files from DBD enviroment at @a live_path that exist
+ * Delete all unused log files from DBD environment at @a live_path that exist
  * in @a backup_path.
  */
 static svn_error_t *
@@ -1515,7 +1516,8 @@ static fs_library_vtable_t library_vtabl
   base_bdb_logfiles,
   svn_fs_base__id_parse,
   base_set_svn_fs_open,
-  NULL /* info_fsap_dup */
+  NULL /* info_fsap_dup */,
+  NULL /* ioctl */
 };
 
 svn_error_t *

Modified: subversion/branches/addremove/subversion/libsvn_fs_base/key-gen.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_base/key-gen.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_base/key-gen.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_base/key-gen.c Sat May 
23 14:16:56 2020
@@ -50,7 +50,7 @@ svn_fs_base__next_key(const char *this,
    * from being propagated further. */
   SVN_ERR_ASSERT_NO_RETURN(olen != 0 && (olen == 1 || this[0] != '0'));
 
-  i = olen - 1; /* initial index: we work backwords */
+  i = olen - 1; /* initial index: we work backwards */
   while (1729)
     {
       c = this[i];

Modified: 
subversion/branches/addremove/subversion/libsvn_fs_base/notes/fs-history
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_base/notes/fs-history?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_base/notes/fs-history 
(original)
+++ subversion/branches/addremove/subversion/libsvn_fs_base/notes/fs-history 
Sat May 23 14:16:56 2020
@@ -128,7 +128,7 @@ node-revision ID consists of the same no
 that was cloned (since this is just another point along the historical
 lineage of this versioned resource), a copy ID (which will be
 discussed later), and the txn ID in which this modification is
-occuring.
+occurring.
 
 There are some cool things we can read between the lines above.  Since
 the only time a node-revision comes into existence is when it is brand

Modified: subversion/branches/addremove/subversion/libsvn_fs_base/reps-strings.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_base/reps-strings.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_base/reps-strings.c 
(original)
+++ subversion/branches/addremove/subversion/libsvn_fs_base/reps-strings.c Sat 
May 23 14:16:56 2020
@@ -1,4 +1,4 @@
-/* reps-strings.c : intepreting representations with respect to strings
+/* reps-strings.c : interpreting representations with respect to strings
  *
  * ====================================================================
  *    Licensed to the Apache Software Foundation (ASF) under one

Modified: subversion/branches/addremove/subversion/libsvn_fs_base/tree.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_base/tree.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_base/tree.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_base/tree.c Sat May 23 
14:16:56 2020
@@ -1627,7 +1627,7 @@ base_dir_optimal_order(apr_array_header_
                        apr_pool_t *result_pool,
                        apr_pool_t *scratch_pool)
 {
-  /* 1:1 copy of entries with no differnce in ordering */
+  /* 1:1 copy of entries with no difference in ordering */
   apr_hash_index_t *hi;
   apr_array_header_t *result
     = apr_array_make(result_pool, apr_hash_count(entries),
@@ -3936,7 +3936,7 @@ txn_body_fulltext_finalize_edits(void *b
                     trail->pool);
 }
 
-/* Write function for the publically returned stream. */
+/* Write function for the publicly returned stream. */
 static svn_error_t *
 text_stream_writer(void *baton,
                    const char *data,
@@ -3948,7 +3948,7 @@ text_stream_writer(void *baton,
   return svn_stream_write(tb->file_stream, data, len);
 }
 
-/* Close function for the publically returned stream. */
+/* Close function for the publicly returned stream. */
 static svn_error_t *
 text_stream_closer(void *baton)
 {

Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/cached_data.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/cached_data.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/cached_data.c 
(original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/cached_data.c Sat May 
23 14:16:56 2020
@@ -1224,7 +1224,7 @@ struct rep_read_baton
   /* Used for temporary allocations during the read. */
   apr_pool_t *pool;
 
-  /* Pool used to store file handles and other data that is persistant
+  /* Pool used to store file handles and other data that is persistent
      for the entire stream read. */
   apr_pool_t *filehandle_pool;
 };
@@ -1268,7 +1268,7 @@ parse_raw_window(void **out,
   stream = svn_stream_from_string(&raw_window, result_pool);
 
   /* parse it */
-  SVN_ERR(svn_txdelta_read_svndiff_window(&result->window, stream, 1,
+  SVN_ERR(svn_txdelta_read_svndiff_window(&result->window, stream, window->ver,
                                           result_pool));
 
   /* complete the window and return it */
@@ -1775,7 +1775,7 @@ get_combined_window(svn_stringbuf_t **re
   return SVN_NO_ERROR;
 }
 
-/* Returns whether or not the expanded fulltext of the file is cachable
+/* Returns whether or not the expanded fulltext of the file is cacheable
  * based on its size SIZE.  The decision depends on the cache used by FFD.
  */
 static svn_boolean_t
@@ -2103,13 +2103,14 @@ skip_contents(struct rep_read_baton *bat
 
 /* BATON is of type `rep_read_baton'; read the next *LEN bytes of the
    representation and store them in *BUF.  Sum as we read and verify
-   the MD5 sum at the end. */
+   the MD5 sum at the end.  This is a READ_FULL_FN for svn_stream_t. */
 static svn_error_t *
 rep_read_contents(void *baton,
                   char *buf,
                   apr_size_t *len)
 {
   struct rep_read_baton *rb = baton;
+  apr_size_t len_requested = *len;
 
   /* Get data from the fulltext cache for as long as we can. */
   if (rb->fulltext_cache)
@@ -2150,6 +2151,28 @@ rep_read_contents(void *baton,
   if (rb->current_fulltext)
     svn_stringbuf_appendbytes(rb->current_fulltext, buf, *len);
 
+  /* This is a FULL_READ_FN so a short read implies EOF and we can
+     verify the length. */
+  rb->off += *len;
+  if (*len < len_requested && rb->off != rb->len)
+      {
+        /* A warning rather than an error to allow the data to be
+           retrieved when the length is wrong but the data is
+           present, i.e. if repository corruption has stored the wrong
+           expanded length. */
+        svn_error_t *err = svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+                            _("Length mismatch while reading representation:"
+                              " expected %s,"
+                              " got %s"),
+                            apr_psprintf(rb->pool, "%" SVN_FILESIZE_T_FMT,
+                                         rb->len),
+                            apr_psprintf(rb->pool, "%" SVN_FILESIZE_T_FMT,
+                                         rb->off));
+
+        rb->fs->warning(rb->fs->warning_baton, err);
+        svn_error_clear(err);
+      }
+
   /* Perform checksumming.  We want to check the checksum as soon as
      the last byte of data is read, in case the caller never performs
      a short read, but we don't want to finalize the MD5 context
@@ -2157,7 +2180,6 @@ rep_read_contents(void *baton,
   if (!rb->checksum_finalized)
     {
       SVN_ERR(svn_checksum_update(rb->md5_checksum_ctx, buf, *len));
-      rb->off += *len;
       if (rb->off == rb->len)
         {
           svn_checksum_t *md5_checksum;
@@ -2315,7 +2337,7 @@ svn_fs_fs__get_contents_from_file(svn_st
                              rb->filehandle_pool));
 
       /* Insert the access to REP as the first element of the delta chain. */
-      svn_sort__array_insert(rb->rs_list, &rs, 0);
+      SVN_ERR(svn_sort__array_insert2(rb->rs_list, &rs, 0));
     }
 
   /* Now, the baton is complete and we can assemble the stream around it. */
@@ -2677,7 +2699,7 @@ read_dir_entries(apr_array_header_t **en
 }
 
 /* For directory NODEREV in FS, return the *FILESIZE of its in-txn
- * representation.  If the directory representation is comitted data,
+ * representation.  If the directory representation is committed data,
  * set *FILESIZE to SVN_INVALID_FILESIZE. Use SCRATCH_POOL for temporaries.
  */
 static svn_error_t *
@@ -3206,7 +3228,7 @@ init_rep_state(rep_state_t *rs,
   rs->start = entry->offset + rs->header_size;
   rs->current = rep_header->type == svn_fs_fs__rep_plain ? 0 : 4;
   rs->size = entry->size - rep_header->header_size - 7;
-  rs->ver = 1;
+  rs->ver = -1;
   rs->chunk_index = 0;
   rs->raw_window_cache = ffd->raw_window_cache;
   rs->window_cache = ffd->txdelta_window_cache;
@@ -3264,6 +3286,9 @@ cache_windows(svn_fs_t *fs,
               apr_pool_t *pool)
 {
   apr_pool_t *iterpool = svn_pool_create(pool);
+
+  SVN_ERR(auto_read_diff_version(rs, iterpool));
+
   while (rs->current < rs->size)
     {
       apr_off_t end_offset;
@@ -3320,10 +3345,11 @@ cache_windows(svn_fs_t *fs,
           /* update relative offset in representation */
           rs->current += window_len;
 
-          /* Construct the cachable raw window object. */
+          /* Construct the cacheable raw window object. */
           window.end_offset = rs->current;
           window.window.len = window_len;
           window.window.data = buf;
+          window.ver = rs->ver;
 
           /* cache the window now */
           SVN_ERR(svn_cache__set(rs->raw_window_cache, &key, &window,

Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/cached_data.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/cached_data.h?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/cached_data.h 
(original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/cached_data.h Sat May 
23 14:16:56 2020
@@ -171,7 +171,7 @@ svn_fs_fs__get_proplist(apr_hash_t **pro
                         apr_pool_t *pool);
 
 /* Create a changes retrieval context object in *RESULT_POOL and return it
- * in *CONTEXT.  It will allow svn_fs_x__get_changes to fetch consecutive
+ * in *CONTEXT.  It will allow svn_fs_fs__get_changes to fetch consecutive
  * blocks (one per invocation) from REV's changed paths list in FS. */
 svn_error_t *
 svn_fs_fs__create_changes_context(svn_fs_fs__changes_context_t **context,

Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/dag.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/dag.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/dag.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/dag.c Sat May 23 
14:16:56 2020
@@ -1166,7 +1166,7 @@ svn_fs_fs__dag_serialize(void **data,
                                 (const void * const *)&node->node_pool);
 
   /* serialize other sub-structures */
-  svn_fs_fs__id_serialize(context, (const svn_fs_id_t **)&node->id);
+  svn_fs_fs__id_serialize(context, (const svn_fs_id_t *const *)&node->id);
   svn_fs_fs__id_serialize(context, &node->fresh_root_predecessor_id);
   svn_temp_serializer__add_string(context, &node->created_path);
 

Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/dump-index.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/dump-index.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/dump-index.c 
(original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/dump-index.c Sat May 
23 14:16:56 2020
@@ -21,8 +21,8 @@
  */
 
 #include "svn_pools.h"
-#include "private/svn_fs_fs_private.h"
 
+#include "fs_fs.h"
 #include "index.h"
 #include "rev_file.h"
 #include "util.h"

Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/fs.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/fs.c?rev=1878061&r1=1878060&r2=1878061&view=diff
==============================================================================
--- subversion/branches/addremove/subversion/libsvn_fs_fs/fs.c (original)
+++ subversion/branches/addremove/subversion/libsvn_fs_fs/fs.c Sat May 23 
14:16:56 2020
@@ -47,6 +47,7 @@
 #include "verify.h"
 #include "svn_private_config.h"
 #include "private/svn_fs_util.h"
+#include "private/svn_fs_fs_private.h"
 
 #include "../libsvn_fs/fs-loader.h"
 
@@ -254,6 +255,83 @@ fs_set_uuid(svn_fs_t *fs,
 }
 
 
+static svn_error_t *
+fs_ioctl(svn_fs_t *fs, svn_fs_ioctl_code_t ctlcode,
+         void *input_void, void **output_p,
+         svn_cancel_func_t cancel_func,
+         void *cancel_baton,
+         apr_pool_t *result_pool,
+         apr_pool_t *scratch_pool)
+{
+  if (strcmp(ctlcode.fs_type, SVN_FS_TYPE_FSFS) == 0)
+    {
+      if (ctlcode.code == SVN_FS_FS__IOCTL_GET_STATS.code)
+        {
+          svn_fs_fs__ioctl_get_stats_input_t *input = input_void;
+          svn_fs_fs__ioctl_get_stats_output_t *output;
+
+          output = apr_pcalloc(result_pool, sizeof(*output));
+          SVN_ERR(svn_fs_fs__get_stats(&output->stats, fs,
+                                       input->progress_func,
+                                       input->progress_baton,
+                                       cancel_func, cancel_baton,
+                                       result_pool, scratch_pool));
+          *output_p = output;
+          return SVN_NO_ERROR;
+        }
+      else if (ctlcode.code == SVN_FS_FS__IOCTL_DUMP_INDEX.code)
+        {
+          svn_fs_fs__ioctl_dump_index_input_t *input = input_void;
+
+          SVN_ERR(svn_fs_fs__dump_index(fs, input->revision,
+                                        input->callback_func,
+                                        input->callback_baton,
+                                        cancel_func, cancel_baton,
+                                        scratch_pool));
+          *output_p = NULL;
+          return SVN_NO_ERROR;
+        }
+      else if (ctlcode.code == SVN_FS_FS__IOCTL_LOAD_INDEX.code)
+        {
+          svn_fs_fs__ioctl_load_index_input_t *input = input_void;
+
+          SVN_ERR(svn_fs_fs__load_index(fs, input->revision, input->entries,
+                                        scratch_pool));
+          *output_p = NULL;
+          return SVN_NO_ERROR;
+        }
+      else if (ctlcode.code == SVN_FS_FS__IOCTL_REVISION_SIZE.code)
+        {
+          svn_fs_fs__ioctl_revision_size_input_t *input = input_void;
+          svn_fs_fs__ioctl_revision_size_output_t *output
+            = apr_pcalloc(result_pool, sizeof(*output));
+
+          SVN_ERR(svn_fs_fs__revision_size(&output->rev_size,
+                                           fs, input->revision,
+                                           scratch_pool));
+          *output_p = output;
+          return SVN_NO_ERROR;
+        }
+      else if (ctlcode.code == SVN_FS_FS__IOCTL_BUILD_REP_CACHE.code)
+        {
+          svn_fs_fs__ioctl_build_rep_cache_input_t *input = input_void;
+
+          SVN_ERR(svn_fs_fs__build_rep_cache(fs,
+                                             input->start_rev,
+                                             input->end_rev,
+                                             input->progress_func,
+                                             input->progress_baton,
+                                             cancel_func,
+                                             cancel_baton,
+                                             scratch_pool));
+
+          *output_p = NULL;
+          return SVN_NO_ERROR;
+        }
+    }
+
+  return svn_error_create(SVN_ERR_FS_UNRECOGNIZED_IOCTL_CODE, NULL, NULL);
+}
 
 /* The vtable associated with a specific open filesystem. */
 static fs_vtable_t fs_vtable = {
@@ -279,7 +357,8 @@ static fs_vtable_t fs_vtable = {
   fs_info,
   svn_fs_fs__verify_root,
   fs_freeze,
-  fs_set_errcall
+  fs_set_errcall,
+  fs_ioctl
 };
 
 
@@ -602,7 +681,8 @@ static fs_library_vtable_t library_vtabl
   fs_logfiles,
   NULL /* parse_id */,
   fs_set_svn_fs_open,
-  fs_info_dup
+  fs_info_dup,
+  NULL /* ioctl */
 };
 
 svn_error_t *


Reply via email to