svn commit: r1921611 [1/2] - in /subversion/trunk/subversion/libsvn_client: diff.c diff_patch.c

[email protected]
Newsgroups gmane.comp.version-control.subversion.svn
Message-ID <[email protected]>
Author: rinrab
Date: Sun Oct 27 21:09:45 2024
New Revision: 1921611

URL: http://svn.apache.org/viewvc?rev=1921611&view=rev
Log:
Move patch (or unidiff) writer into a separate source file.

The only function that it should export from itself is svn_client__get_diff_writer_svn
which were recently made as an independent function from local functions and
structures. This function also references a number of static callbacks for
the diff_processor instance, which should also be moved with it.

* subversion/libsvn_client/diff.c
  (make_repos_relpath
   adjust_paths_for_diff_labels
   diff_label
   print_git_diff_header_added
   print_git_diff_header_deleted
   print_git_diff_header_copied
   print_git_diff_header_renamed
   print_git_diff_header_modified
   maybe_print_mode_change
   print_git_diff_header
   print_diff_index_header
   display_prop_diffs
   diff_writer_info_t
   diff_props_changed
   transform_link_to_git
   diff_content_changed
   diff_file_changed
   diff_file_added
   diff_file_deleted
   diff_dir_changed
   diff_dir_added
   diff_dir_deleted
   create_diff_writer_info
   svn_client__get_diff_writer_svn): Moved to diff_patch.c.
  (includes): Cleanup unused.


* subversion/libsvn_client/diff_patch.c
  Copied from diff.c.
  (make_repos_relpath
   adjust_paths_for_diff_labels
   diff_label
   print_git_diff_header_added
   print_git_diff_header_deleted
   print_git_diff_header_copied
   print_git_diff_header_renamed
   print_git_diff_header_modified
   maybe_print_mode_change
   print_git_diff_header
   print_diff_index_header
   display_prop_diffs
   diff_writer_info_t
   diff_props_changed
   transform_link_to_git
   diff_content_changed
   diff_file_changed
   diff_file_added
   diff_file_deleted
   diff_dir_changed
   diff_dir_added
   diff_dir_deleted
   create_diff_writer_info
   svn_client__get_diff_writer_svn): Moved from diff.c.
  (includes): Cleanup unused.

Added:
    subversion/trunk/subversion/libsvn_client/diff_patch.c
      - copied, changed from r1921610, subversion/trunk/subversion/libsvn_client/diff.c
Modified:
    subversion/trunk/subversion/libsvn_client/diff.c

Modified: subversion/trunk/subversion/libsvn_client/diff.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/diff.c?rev=1921611&r1=1921610&r2=1921611&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/diff.c (original)
+++ subversion/trunk/subversion/libsvn_client/diff.c Sun Oct 27 21:09:45 2024
@@ -32,1376 +32,26 @@
 
 #include <apr_strings.h>
 #include <apr_pools.h>
-#include <apr_hash.h>
 #include "svn_types.h"
-#include "svn_hash.h"
 #include "svn_wc.h"
 #include "svn_diff.h"
 #include "svn_mergeinfo.h"
 #include "svn_client.h"
-#include "svn_string.h"
 #include "svn_error.h"
 #include "svn_dirent_uri.h"
 #include "svn_path.h"
 #include "svn_io.h"
-#include "svn_utf.h"
-#include "svn_pools.h"
-#include "svn_config.h"
-#include "svn_props.h"
-#include "svn_subst.h"
 #include "client.h"
 
 #include "private/svn_client_shelf.h"
 #include "private/svn_client_private.h"
 #include "private/svn_wc_private.h"
-#include "private/svn_diff_private.h"
-#include "private/svn_subr_private.h"
-#include "private/svn_io_private.h"
+#include "private/svn_diff_tree.h"
 #include "private/svn_ra_private.h"
 
 #include "svn_private_config.h"
 
 
-/* Utilities */
-
-#define DIFF_REVNUM_NONEXISTENT ((svn_revnum_t) -100)
-
-#define MAKE_ERR_BAD_RELATIVE_PATH(path, relative_to_dir) \
-        svn_error_createf(SVN_ERR_BAD_RELATIVE_PATH, NULL, \
-                          _("Path '%s' must be an immediate child of " \
-                            "the directory '%s'"), path, relative_to_dir)
-
-
-/* Calculate the repository relative path of DIFF_RELPATH, using
- * SESSION_RELPATH and WC_CTX, and return the result in *REPOS_RELPATH.
- * ORIG_TARGET is the related original target passed to the diff command,
- * and may be used to derive leading path components missing from PATH.
- * ANCHOR is the local path where the diff editor is anchored.
- * Do all allocations in POOL. */
-static svn_error_t *
-make_repos_relpath(const char **repos_relpath,
-                   const char *diff_relpath,
-                   const char *orig_target,
-                   const char *session_relpath,
-                   svn_wc_context_t *wc_ctx,
-                   const char *anchor,
-                   apr_pool_t *result_pool,
-                   apr_pool_t *scratch_pool)
-{
-  const char *local_abspath;
-
-  if (! session_relpath
-      || (anchor && !svn_path_is_url(orig_target)))
-    {
-      svn_error_t *err;
-      /* We're doing a WC-WC diff, so we can retrieve all information we
-       * need from the working copy. */
-      SVN_ERR(svn_dirent_get_absolute(&local_abspath,
-                                      svn_dirent_join(anchor, diff_relpath,
-                                                      scratch_pool),
-                                      scratch_pool));
-
-      err = svn_wc__node_get_repos_info(NULL, repos_relpath, NULL, NULL,
-                                        wc_ctx, local_abspath,
-                                        result_pool, scratch_pool);
-
-      if (!session_relpath
-          || ! err
-          || (err && err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND))
-        {
-           return svn_error_trace(err);
-        }
-
-      /* The path represents a local working copy path, but does not
-         exist. Fall through to calculate an in-repository location
-         based on the ra session */
-
-      /* ### Maybe we should use the nearest existing ancestor instead? */
-      svn_error_clear(err);
-    }
-
-  *repos_relpath = svn_relpath_join(session_relpath, diff_relpath,
-                                    result_pool);
-
-  return SVN_NO_ERROR;
-}
-
-/* Adjust paths to handle the case when we're dealing with different anchors.
- *
- * Set *INDEX_PATH to the new relative path. Set *LABEL_PATH1 and
- * *LABEL_PATH2 to that path annotated with the unique parts of ORIG_PATH_1
- * and ORIG_PATH_2 respectively, like this:
- *
- *   INDEX_PATH:  "path"
- *   LABEL_PATH1: "path\t(.../branches/branch1)"
- *   LABEL_PATH2: "path\t(.../trunk)"
- *
- * Make the output paths relative to RELATIVE_TO_DIR (if not null) by
- * removing it from the beginning of (ANCHOR + RELPATH).
- *
- * ANCHOR (if not null) is the local path where the diff editor is anchored.
- * RELPATH is the path to the changed node within the diff editor, so
- * relative to ANCHOR.
- *
- * RELATIVE_TO_DIR and ANCHOR are of the same form -- either absolute local
- * paths or relative paths relative to the same base.
- *
- * ORIG_PATH_1 and ORIG_PATH_2 represent the two original target paths or
- * URLs passed to the diff command.
- *
- * Allocate results in RESULT_POOL (or as a pointer to RELPATH) and
- * temporary data in SCRATCH_POOL.
- */
-static svn_error_t *
-adjust_paths_for_diff_labels(const char **index_path,
-                             const char **label_path1,
-                             const char **label_path2,
-                             const char *relative_to_dir,
-                             const char *anchor,
-                             const char *relpath,
-                             const char *orig_path_1,
-                             const char *orig_path_2,
-                             apr_pool_t *result_pool,
-                             apr_pool_t *scratch_pool)
-{
-  const char *new_path = relpath;
-  const char *new_path1 = orig_path_1;
-  const char *new_path2 = orig_path_2;
-
-  if (anchor)
-    new_path = svn_dirent_join(anchor, new_path, result_pool);
-
-  if (relative_to_dir)
-    {
-      /* Possibly adjust the paths shown in the output (see issue #2723). */
-      const char *child_path = svn_dirent_is_child(relative_to_dir, new_path,
-                                                   result_pool);
-
-      if (child_path)
-        new_path = child_path;
-      else if (! strcmp(relative_to_dir, new_path))
-        new_path = ".";
-      else
-        return MAKE_ERR_BAD_RELATIVE_PATH(
-                 svn_dirent_local_style(new_path, scratch_pool),
-                 svn_dirent_local_style(relative_to_dir, scratch_pool));
-    }
-
-  {
-    apr_size_t len;
-    svn_boolean_t is_url1;
-    svn_boolean_t is_url2;
-    /* ### Holy cow.  Due to anchor/target weirdness, we can't
-       simply join dwi->orig_path_1 with path, ditto for
-       orig_path_2.  That will work when they're directory URLs, but
-       not for file URLs.  Nor can we just use anchor1 and anchor2
-       from do_diff(), at least not without some more logic here.
-       What a nightmare.
-
-       For now, to distinguish the two paths, we'll just put the
-       unique portions of the original targets in parentheses after
-       the received path, with ellipses for handwaving.  This makes
-       the labels a bit clumsy, but at least distinctive.  Better
-       solutions are possible, they'll just take more thought. */
-
-    /* ### BH: We can now just construct the repos_relpath, etc. as the
-           anchor is available. See also make_repos_relpath() */
-
-    /* Remove the common prefix of NEW_PATH1 and NEW_PATH2. */
-    is_url1 = svn_path_is_url(new_path1);
-    is_url2 = svn_path_is_url(new_path2);
-
-    if (is_url1 && is_url2)
-      len = strlen(svn_uri_get_longest_ancestor(new_path1, new_path2,
-                                                scratch_pool));
-    else if (!is_url1 && !is_url2)
-      len = strlen(svn_dirent_get_longest_ancestor(new_path1, new_path2,
-                                                   scratch_pool));
-    else
-      len = 0; /* Path and URL */
-
-    new_path1 += len;
-    new_path2 += len;
-  }
-
-  /* ### Should diff labels print paths in local style?  Is there
-     already a standard for this?  In any case, this code depends on
-     a particular style, so not calling svn_dirent_local_style() on the
-     paths below.*/
-
-  if (new_path[0] == '\0')
-    new_path = ".";
-
-  if (new_path1[0] == '\0')
-    new_path1 = new_path;
-  else if (svn_path_is_url(new_path1))
-    new_path1 = apr_psprintf(result_pool, "%s\t(%s)", new_path, new_path1);
-  else if (new_path1[0] == '/')
-    new_path1 = apr_psprintf(result_pool, "%s\t(...%s)", new_path, new_path1);
-  else
-    new_path1 = apr_psprintf(result_pool, "%s\t(.../%s)", new_path, new_path1);
-
-  if (new_path2[0] == '\0')
-    new_path2 = new_path;
-  else if (svn_path_is_url(new_path2))
-    new_path2 = apr_psprintf(result_pool, "%s\t(%s)", new_path, new_path2);
-  else if (new_path2[0] == '/')
-    new_path2 = apr_psprintf(result_pool, "%s\t(...%s)", new_path, new_path2);
-  else
-    new_path2 = apr_psprintf(result_pool, "%s\t(.../%s)", new_path, new_path2);
-
-  *index_path = new_path;
-  *label_path1 = new_path1;
-  *label_path2 = new_path2;
-
-  return SVN_NO_ERROR;
-}
-
-
-/* Generate a label for the diff output for file PATH at revision REVNUM.
-   If REVNUM is invalid then it is assumed to be the current working
-   copy.  Assumes the paths are already in the desired style (local
-   vs internal).  Allocate the label in RESULT-POOL. */
-static const char *
-diff_label(const char *path,
-           svn_revnum_t revnum,
-           apr_pool_t *result_pool)
-{
-  const char *label;
-  if (revnum >= 0)
-    label = apr_psprintf(result_pool, _("%s\t(revision %ld)"), path, revnum);
-  else if (revnum == DIFF_REVNUM_NONEXISTENT)
-    label = apr_psprintf(result_pool, _("%s\t(nonexistent)"), path);
-  else /* SVN_INVALID_REVNUM */
-    label = apr_psprintf(result_pool, _("%s\t(working copy)"), path);
-
-  return label;
-}
-
-/* Standard modes produced in git style diffs */
-static const int exec_mode =                 0755;
-static const int noexec_mode =               0644;
-static const int kind_file_mode =         0100000;
-/*static const kind_dir_mode =            0040000;*/
-static const int kind_symlink_mode =      0120000;
-
-/* Print a git diff header for an addition within a diff between PATH1 and
- * PATH2 to the stream OS using HEADER_ENCODING. */
-static svn_error_t *
-print_git_diff_header_added(svn_stream_t *os, const char *header_encoding,
-                            const char *path1, const char *path2,
-                            svn_boolean_t exec_bit,
-                            svn_boolean_t symlink_bit,
-                            apr_pool_t *scratch_pool)
-{
-  int new_mode = (exec_bit ? exec_mode : noexec_mode)
-                 | (symlink_bit ? kind_symlink_mode : kind_file_mode);
-
-  SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, scratch_pool,
-                                      "diff --git a/%s b/%s%s",
-                                      path1, path2, APR_EOL_STR));
-  SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, scratch_pool,
-                                      "new file mode %06o" APR_EOL_STR,
-                                      new_mode));
-  return SVN_NO_ERROR;
-}
-
-/* Print a git diff header for a deletion within a diff between PATH1 and
- * PATH2 to the stream OS using HEADER_ENCODING. */
-static svn_error_t *
-print_git_diff_header_deleted(svn_stream_t *os, const char *header_encoding,
-                              const char *path1, const char *path2,
-                              svn_boolean_t exec_bit,
-                              svn_boolean_t symlink_bit,
-                              apr_pool_t *scratch_pool)
-{
-  int old_mode = (exec_bit ? exec_mode : noexec_mode)
-                 | (symlink_bit ? kind_symlink_mode : kind_file_mode);
-  SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, scratch_pool,
-                                      "diff --git a/%s b/%s%s",
-                                      path1, path2, APR_EOL_STR));
-  SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, scratch_pool,
-                                      "deleted file mode %06o" APR_EOL_STR,
-                                      old_mode));
-  return SVN_NO_ERROR;
-}
-
-/* Print a git diff header for a copy from COPYFROM_PATH to PATH to the stream
- * OS using HEADER_ENCODING. */
-static svn_error_t *
-print_git_diff_header_copied(svn_stream_t *os, const char *header_encoding,
-                             const char *copyfrom_path,
-                             svn_revnum_t copyfrom_rev,
-                             const char *path,
-                             apr_pool_t *scratch_pool)
-{
-  SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, scratch_pool,
-                                      "diff --git a/%s b/%s%s",
-                                      copyfrom_path, path, APR_EOL_STR));
-  if (copyfrom_rev != SVN_INVALID_REVNUM)
-    SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, scratch_pool,
-                                        "copy from %s@%ld%s", copyfrom_path,
-                                        copyfrom_rev, APR_EOL_STR));
-  else
-    SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, scratch_pool,
-                                        "copy from %s%s", copyfrom_path,
-                                        APR_EOL_STR));
-  SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, scratch_pool,
-                                      "copy to %s%s", path, APR_EOL_STR));
-  return SVN_NO_ERROR;
-}
-
-/* Print a git diff header for a rename from COPYFROM_PATH to PATH to the
- * stream OS using HEADER_ENCODING. */
-static svn_error_t *
-print_git_diff_header_renamed(svn_stream_t *os, const char *header_encoding,
-                              const char *copyfrom_path, const char *path,
-                              apr_pool_t *scratch_pool)
-{
-  SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, scratch_pool,
-                                      "diff --git a/%s b/%s%s",
-                                      copyfrom_path, path, APR_EOL_STR));
-  SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, scratch_pool,
-                                      "rename from %s%s", copyfrom_path,
-                                      APR_EOL_STR));
-  SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, scratch_pool,
-                                      "rename to %s%s", path, APR_EOL_STR));
-  return SVN_NO_ERROR;
-}
-
-/* Print a git diff header for a modification within a diff between PATH1 and
- * PATH2 to the stream OS using HEADER_ENCODING. */
-static svn_error_t *
-print_git_diff_header_modified(svn_stream_t *os, const char *header_encoding,
-                               const char *path1, const char *path2,
-                               apr_pool_t *scratch_pool)
-{
-  SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, scratch_pool,
-                                      "diff --git a/%s b/%s%s",
-                                      path1, path2, APR_EOL_STR));
-  return SVN_NO_ERROR;
-}
-
-/* Helper function for print_git_diff_header */
-static svn_error_t *
-maybe_print_mode_change(svn_stream_t *os,
-                        const char *header_encoding,
-                        svn_boolean_t exec_bit1,
-                        svn_boolean_t exec_bit2,
-                        svn_boolean_t symlink_bit1,
-                        svn_boolean_t symlink_bit2,
-                        const char *git_index_shas,
-                        apr_pool_t *scratch_pool)
-{
-  int old_mode = (exec_bit1 ? exec_mode : noexec_mode)
-                 | (symlink_bit1 ? kind_symlink_mode : kind_file_mode);
-  int new_mode = (exec_bit2 ? exec_mode : noexec_mode)
-                 | (symlink_bit2 ? kind_symlink_mode : kind_file_mode);
-  if (old_mode == new_mode)
-    {
-      if (git_index_shas)
-        SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, scratch_pool,
-                                            "index %s %06o" APR_EOL_STR,
-                                            git_index_shas, old_mode));
-      return SVN_NO_ERROR;
-    }
-
-  SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, scratch_pool,
-                                      "old mode %06o" APR_EOL_STR, old_mode));
-  SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, scratch_pool,
-                                      "new mode %06o" APR_EOL_STR, new_mode));
-  return SVN_NO_ERROR;
-}
-
-/* Print a git diff header showing the OPERATION to the stream OS using
- * HEADER_ENCODING.
- *
- * Return suitable diff labels for the git diff in *LABEL1 and *LABEL2.
- *
- * REV1 and REV2 are the revisions being diffed.
- * COPYFROM_PATH and COPYFROM_REV indicate where the
- * diffed item was copied from.
- * Use SCRATCH_POOL for temporary allocations. */
-static svn_error_t *
-print_git_diff_header(svn_stream_t *os,
-                      const char **label1, const char **label2,
-                      svn_diff_operation_kind_t operation,
-                      svn_revnum_t rev1,
-                      svn_revnum_t rev2,
-                      const char *diff_relpath,
-                      const char *copyfrom_path,
-                      svn_revnum_t copyfrom_rev,
-                      apr_hash_t *left_props,
-                      apr_hash_t *right_props,
-                      const char *git_index_shas,
-                      const char *header_encoding,
-                      const svn_client__diff_driver_info_t *ddi,
-                      apr_pool_t *scratch_pool)
-{
-  const char *repos_relpath1;
-  const char *repos_relpath2;
-  const char *copyfrom_repos_relpath = NULL;
-  svn_boolean_t exec_bit1 = (svn_prop_get_value(left_props,
-                                                SVN_PROP_EXECUTABLE) != NULL);
-  svn_boolean_t exec_bit2 = (svn_prop_get_value(right_props,
-                                                SVN_PROP_EXECUTABLE) != NULL);
-  svn_boolean_t symlink_bit1 = (svn_prop_get_value(left_props,
-                                                   SVN_PROP_SPECIAL) != NULL);
-  svn_boolean_t symlink_bit2 = (svn_prop_get_value(right_props,
-                                                   SVN_PROP_SPECIAL) != NULL);
-
-  SVN_ERR(make_repos_relpath(&repos_relpath1, diff_relpath,
-                             ddi->orig_path_1,
-                             ddi->session_relpath,
-                             ddi->wc_ctx,
-                             ddi->anchor,
-                             scratch_pool, scratch_pool));
-  SVN_ERR(make_repos_relpath(&repos_relpath2, diff_relpath,
-                             ddi->orig_path_2,
-                             ddi->session_relpath,
-                             ddi->wc_ctx,
-                             ddi->anchor,
-                             scratch_pool, scratch_pool));
-  if (copyfrom_path)
-    SVN_ERR(make_repos_relpath(&copyfrom_repos_relpath, copyfrom_path,
-                               ddi->orig_path_2,
-                               ddi->session_relpath,
-                               ddi->wc_ctx,
-                               ddi->anchor,
-                               scratch_pool, scratch_pool));
-
-  if (operation == svn_diff_op_deleted)
-    {
-      SVN_ERR(print_git_diff_header_deleted(os, header_encoding,
-                                            repos_relpath1, repos_relpath2,
-                                            exec_bit1, symlink_bit1,
-                                            scratch_pool));
-      *label1 = diff_label(apr_psprintf(scratch_pool, "a/%s", repos_relpath1),
-                           rev1, scratch_pool);
-      *label2 = diff_label(apr_psprintf(scratch_pool, "b/%s", repos_relpath2),
-                           rev2, scratch_pool);
-
-    }
-  else if (operation == svn_diff_op_copied)
-    {
-      SVN_ERR(print_git_diff_header_copied(os, header_encoding,
-                                           copyfrom_path, copyfrom_rev,
-                                           repos_relpath2,
-                                           scratch_pool));
-      *label1 = diff_label(apr_psprintf(scratch_pool, "a/%s", copyfrom_path),
-                           rev1, scratch_pool);
-      *label2 = diff_label(apr_psprintf(scratch_pool, "b/%s", repos_relpath2),
-                           rev2, scratch_pool);
-      SVN_ERR(maybe_print_mode_change(os, header_encoding,
-                                      exec_bit1, exec_bit2,
-                                      symlink_bit1, symlink_bit2,
-                                      git_index_shas,
-                                      scratch_pool));
-    }
-  else if (operation == svn_diff_op_added)
-    {
-      SVN_ERR(print_git_diff_header_added(os, header_encoding,
-                                          repos_relpath1, repos_relpath2,
-                                          exec_bit2, symlink_bit2,
-                                          scratch_pool));
-      *label1 = diff_label(apr_psprintf(scratch_pool, "a/%s", repos_relpath1),
-                           rev1, scratch_pool);
-      *label2 = diff_label(apr_psprintf(scratch_pool, "b/%s", repos_relpath2),
-                           rev2, scratch_pool);
-    }
-  else if (operation == svn_diff_op_modified)
-    {
-      SVN_ERR(print_git_diff_header_modified(os, header_encoding,
-                                             repos_relpath1, repos_relpath2,
-                                             scratch_pool));
-      *label1 = diff_label(apr_psprintf(scratch_pool, "a/%s", repos_relpath1),
-                           rev1, scratch_pool);
-      *label2 = diff_label(apr_psprintf(scratch_pool, "b/%s", repos_relpath2),
-                           rev2, scratch_pool);
-      SVN_ERR(maybe_print_mode_change(os, header_encoding,
-                                      exec_bit1, exec_bit2,
-                                      symlink_bit1, symlink_bit2,
-                                      git_index_shas,
-                                      scratch_pool));
-    }
-  else if (operation == svn_diff_op_moved)
-    {
-      SVN_ERR(print_git_diff_header_renamed(os, header_encoding,
-                                            copyfrom_path, repos_relpath2,
-                                            scratch_pool));
-      *label1 = diff_label(apr_psprintf(scratch_pool, "a/%s", copyfrom_path),
-                           rev1, scratch_pool);
-      *label2 = diff_label(apr_psprintf(scratch_pool, "b/%s", repos_relpath2),
-                           rev2, scratch_pool);
-      SVN_ERR(maybe_print_mode_change(os, header_encoding,
-                                      exec_bit1, exec_bit2,
-                                      symlink_bit1, symlink_bit2,
-                                      git_index_shas,
-                                      scratch_pool));
-    }
-
-  return SVN_NO_ERROR;
-}
-
-/* Print the "Index:" and "=====" lines.
- * Show the paths in platform-independent format ('/' separators)
- */
-static svn_error_t *
-print_diff_index_header(svn_stream_t *outstream,
-                        const char *header_encoding,
-                        const char *index_path,
-                        const char *suffix,
-                        apr_pool_t *scratch_pool)
-{
-  SVN_ERR(svn_stream_printf_from_utf8(outstream,
-                                      header_encoding, scratch_pool,
-                                      "Index: %s%s" APR_EOL_STR
-                                      SVN_DIFF__EQUAL_STRING APR_EOL_STR,
-                                      index_path, suffix));
-  return SVN_NO_ERROR;
-}
-
-/* A helper func that writes out verbal descriptions of property diffs
-   to OUTSTREAM.   Of course, OUTSTREAM will probably be whatever was
-   passed to svn_client_diff7(), which is probably stdout.
-
-   ### FIXME needs proper docstring
-
-   If USE_GIT_DIFF_FORMAT is TRUE, print git diff headers, which always
-   show paths relative to the repository root. DDI->session_relpath and
-   DDI->wc_ctx are needed to normalize paths relative the repository root,
-   and are ignored if USE_GIT_DIFF_FORMAT is FALSE.
-
-   If @a pretty_print_mergeinfo is true, then describe 'svn:mergeinfo'
-   property changes in a human-readable form that says what changes were
-   merged or reverse merged; otherwise (or if the mergeinfo property values
-   don't parse correctly) display them just like any other property.
- */
-static svn_error_t *
-display_prop_diffs(const apr_array_header_t *propchanges,
-                   apr_hash_t *left_props,
-                   apr_hash_t *right_props,
-                   const char *diff_relpath,
-                   svn_revnum_t rev1,
-                   svn_revnum_t rev2,
-                   const char *encoding,
-                   svn_stream_t *outstream,
-                   const char *relative_to_dir,
-                   svn_boolean_t show_diff_header,
-                   svn_boolean_t use_git_diff_format,
-                   svn_boolean_t pretty_print_mergeinfo,
-                   const svn_client__diff_driver_info_t *ddi,
-                   svn_cancel_func_t cancel_func,
-                   void *cancel_baton,
-                   apr_pool_t *scratch_pool)
-{
-  const char *repos_relpath1 = NULL;
-  const char *index_path;
-  const char *label_path1, *label_path2;
-
-  if (use_git_diff_format)
-    {
-      SVN_ERR(make_repos_relpath(&repos_relpath1, diff_relpath, ddi->orig_path_1,
-                                 ddi->session_relpath, ddi->wc_ctx, ddi->anchor,
-                                 scratch_pool, scratch_pool));
-    }
-
-  /* If we're creating a diff on the wc root, path would be empty. */
-  SVN_ERR(adjust_paths_for_diff_labels(&index_path,
-                                       &label_path1, &label_path2,
-                                       relative_to_dir, ddi->anchor,
-                                       diff_relpath,
-                                       ddi->orig_path_1, ddi->orig_path_2,
-                                       scratch_pool, scratch_pool));
-
-  if (show_diff_header)
-    {
-      const char *label1;
-      const char *label2;
-
-      label1 = diff_label(label_path1, rev1, scratch_pool);
-      label2 = diff_label(label_path2, rev2, scratch_pool);
-
-      SVN_ERR(print_diff_index_header(outstream, encoding,
-                                      index_path, "", scratch_pool));
-
-      if (use_git_diff_format)
-        SVN_ERR(print_git_diff_header(outstream, &label1, &label2,
-                                      svn_diff_op_modified,
-                                      rev1, rev2,
-                                      diff_relpath,
-                                      NULL, SVN_INVALID_REVNUM,
-                                      left_props, right_props,
-                                      NULL,
-                                      encoding, ddi, scratch_pool));
-
-      /* --- label1
-       * +++ label2 */
-      SVN_ERR(svn_diff__unidiff_write_header(
-        outstream, encoding, label1, label2, scratch_pool));
-    }
-
-  SVN_ERR(svn_stream_printf_from_utf8(outstream, encoding, scratch_pool,
-                                      APR_EOL_STR
-                                      "Property changes on: %s"
-                                      APR_EOL_STR,
-                                      use_git_diff_format
-                                            ? repos_relpath1
-                                            : index_path));
-
-  SVN_ERR(svn_stream_printf_from_utf8(outstream, encoding, scratch_pool,
-                                      SVN_DIFF__UNDER_STRING APR_EOL_STR));
-
-  SVN_ERR(svn_diff__display_prop_diffs(
-            outstream, encoding, propchanges, left_props,
-            pretty_print_mergeinfo,
-            -1 /* context_size */,
-            cancel_func, cancel_baton, scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-/*-----------------------------------------------------------------*/
-
-/*** Callbacks for 'svn diff', invoked by the repos-diff editor. ***/
-
-/* Diff writer state */
-typedef struct diff_writer_info_t
-{
-  /* If non-null, the external diff command to invoke. */
-  const char *diff_cmd;
-
-  /* This is allocated in this struct's pool or a higher-up pool. */
-  union {
-    /* If 'diff_cmd' is null, then this is the parsed options to
-       pass to the internal libsvn_diff implementation. */
-    svn_diff_file_options_t *for_internal;
-    /* Else if 'diff_cmd' is non-null, then... */
-    struct {
-      /* ...this is an argument array for the external command, and */
-      const char **argv;
-      /* ...this is the length of argv. */
-      int argc;
-    } for_external;
-  } options;
-
-  apr_pool_t *pool;
-  svn_stream_t *outstream;
-  svn_stream_t *errstream;
-
-  const char *header_encoding;
-
-  /* Set this if you want diff output even for binary files. */
-  svn_boolean_t force_binary;
-
-  /* The directory that diff target paths should be considered as
-     relative to for output generation (see issue #2723). */
-  const char *relative_to_dir;
-
-  /* Whether property differences are ignored. */
-  svn_boolean_t ignore_properties;
-
-  /* Whether to show only property changes. */
-  svn_boolean_t properties_only;
-
-  /* Whether we're producing a git-style diff. */
-  svn_boolean_t use_git_diff_format;
-
-  /* Whether addition of a file is summarized versus showing a full diff. */
-  svn_boolean_t no_diff_added;
-
-  /* Whether deletion of a file is summarized versus showing a full diff. */
-  svn_boolean_t no_diff_deleted;
-
-  /* Whether to ignore copyfrom information when showing adds */
-  svn_boolean_t show_copies_as_adds;
-
-  /* Whether to show mergeinfo prop changes in human-readable form */
-  svn_boolean_t pretty_print_mergeinfo;
-
-  /* Empty files for creating diffs or NULL if not used yet */
-  const char *empty_file;
-
-  svn_cancel_func_t cancel_func;
-  void *cancel_baton;
-
-  svn_client__diff_driver_info_t ddi;
-} diff_writer_info_t;
-
-/* An helper for diff_dir_props_changed, diff_file_changed and diff_file_added
- */
-static svn_error_t *
-diff_props_changed(const char *diff_relpath,
-                   svn_revnum_t rev1,
-                   svn_revnum_t rev2,
-                   const apr_array_header_t *propchanges,
-                   apr_hash_t *left_props,
-                   apr_hash_t *right_props,
-                   svn_boolean_t show_diff_header,
-                   diff_writer_info_t *dwi,
-                   apr_pool_t *scratch_pool)
-{
-  apr_array_header_t *props;
-
-  /* If property differences are ignored, there's nothing to do. */
-  if (dwi->ignore_properties)
-    return SVN_NO_ERROR;
-
-  SVN_ERR(svn_categorize_props(propchanges, NULL, NULL, &props,
-                               scratch_pool));
-
-  if (props->nelts > 0)
-    {
-      /* We're using the revnums from the dwi since there's
-       * no revision argument to the svn_wc_diff_callback_t
-       * dir_props_changed(). */
-      SVN_ERR(display_prop_diffs(props, left_props, right_props,
-                                 diff_relpath,
-                                 rev1,
-                                 rev2,
-                                 dwi->header_encoding,
-                                 dwi->outstream,
-                                 dwi->relative_to_dir,
-                                 show_diff_header,
-                                 dwi->use_git_diff_format,
-                                 dwi->pretty_print_mergeinfo,
-                                 &dwi->ddi,
-                                 dwi->cancel_func,
-                                 dwi->cancel_baton,
-                                 scratch_pool));
-    }
-
-  return SVN_NO_ERROR;
-}
-
-/* Given a file ORIG_TMPFILE, return a path to a temporary file that lives at
- * least as long as RESULT_POOL, containing the git-like represention of
- * ORIG_TMPFILE */
-static svn_error_t *
-transform_link_to_git(const char **new_tmpfile,
-                      const char **git_sha1,
-                      const char *orig_tmpfile,
-                      apr_pool_t *result_pool,
-                      apr_pool_t *scratch_pool)
-{
-  apr_file_t *orig;
-  apr_file_t *gitlike;
-  svn_stringbuf_t *line;
-
-  *git_sha1 = NULL;
-
-  SVN_ERR(svn_io_file_open(&orig, orig_tmpfile, APR_READ, APR_OS_DEFAULT,
-                           scratch_pool));
-  SVN_ERR(svn_io_open_unique_file3(&gitlike, new_tmpfile, NULL,
-                                   svn_io_file_del_on_pool_cleanup,
-                                   result_pool, scratch_pool));
-
-  SVN_ERR(svn_io_file_readline(orig, &line, NULL, NULL, 2 * APR_PATH_MAX + 2,
-                               scratch_pool, scratch_pool));
-
-  if (line->len > 5 && !strncmp(line->data, "link ", 5))
-    {
-      const char *sz_str;
-      svn_checksum_t *checksum;
-
-      svn_stringbuf_remove(line, 0, 5);
-
-      SVN_ERR(svn_io_file_write_full(gitlike, line->data, line->len,
-                                     NULL, scratch_pool));
-
-      /* git calculates the sha over "blob X\0" + the actual data,
-         where X is the decimal size of the blob. */
-      sz_str = apr_psprintf(scratch_pool, "blob %u", (unsigned int)line->len);
-      svn_stringbuf_insert(line, 0, sz_str, strlen(sz_str) + 1);
-
-      SVN_ERR(svn_checksum(&checksum, svn_checksum_sha1,
-                           line->data, line->len, scratch_pool));
-
-      *git_sha1 = svn_checksum_to_cstring(checksum, result_pool);
-    }
-  else
-    {
-      /* Not a link... so can't convert */
-      *new_tmpfile = apr_pstrdup(result_pool, orig_tmpfile);
-    }
-
-  SVN_ERR(svn_io_file_close(orig, scratch_pool));
-  SVN_ERR(svn_io_file_close(gitlike, scratch_pool));
-  return SVN_NO_ERROR;
-}
-
-/* Show differences between TMPFILE1 and TMPFILE2. DIFF_RELPATH, REV1, and
-   REV2 are used in the headers to indicate the file and revisions.
-
-   If either side has an svn:mime-type property that indicates 'binary'
-   content, then if DWI->force_binary is set, attempt to produce the
-   diff in the usual way, otherwise produce a 'GIT binary diff' in git mode
-   or print a warning message in non-git mode.
-
-   If FORCE_DIFF is TRUE, always write a diff, even for empty diffs.
-
-   Set *WROTE_HEADER to TRUE if a diff header was written */
-static svn_error_t *
-diff_content_changed(svn_boolean_t *wrote_header,
-                     const char *diff_relpath,
-                     const char *tmpfile1,
-                     const char *tmpfile2,
-                     svn_revnum_t rev1,
-                     svn_revnum_t rev2,
-                     apr_hash_t *left_props,
-                     apr_hash_t *right_props,
-                     svn_diff_operation_kind_t operation,
-                     svn_boolean_t force_diff,
-                     const char *copyfrom_path,
-                     svn_revnum_t copyfrom_rev,
-                     diff_writer_info_t *dwi,
-                     apr_pool_t *scratch_pool)
-{
-  const char *rel_to_dir = dwi->relative_to_dir;
-  svn_stream_t *outstream = dwi->outstream;
-  const char *label1, *label2;
-  svn_boolean_t mt1_binary = FALSE, mt2_binary = FALSE;
-  const char *index_path;
-  const char *label_path1, *label_path2;
-  const char *mimetype1 = svn_prop_get_value(left_props, SVN_PROP_MIME_TYPE);
-  const char *mimetype2 = svn_prop_get_value(right_props, SVN_PROP_MIME_TYPE);
-  const char *index_shas = NULL;
-
-  /* If only property differences are shown, there's nothing to do. */
-  if (dwi->properties_only)
-    return SVN_NO_ERROR;
-
-  /* Generate the diff headers. */
-  SVN_ERR(adjust_paths_for_diff_labels(&index_path,
-                                       &label_path1, &label_path2,
-                                       rel_to_dir, dwi->ddi.anchor,
-                                       diff_relpath,
-                                       dwi->ddi.orig_path_1, dwi->ddi.orig_path_2,
-                                       scratch_pool, scratch_pool));
-
-  label1 = diff_label(label_path1, rev1, scratch_pool);
-  label2 = diff_label(label_path2, rev2, scratch_pool);
-
-  /* Possible easy-out: if either mime-type is binary and force was not
-     specified, don't attempt to generate a viewable diff at all.
-     Print a warning and exit. */
-  if (mimetype1)
-    mt1_binary = svn_mime_type_is_binary(mimetype1);
-  if (mimetype2)
-    mt2_binary = svn_mime_type_is_binary(mimetype2);
-
-  if (dwi->use_git_diff_format)
-    {
-      const char *l_hash = NULL;
-      const char *r_hash = NULL;
-
-      /* Change symlinks to their 'git like' plain format */
-      if (svn_prop_get_value(left_props, SVN_PROP_SPECIAL))
-        SVN_ERR(transform_link_to_git(&tmpfile1, &l_hash, tmpfile1,
-                                      scratch_pool, scratch_pool));
-      if (svn_prop_get_value(right_props, SVN_PROP_SPECIAL))
-        SVN_ERR(transform_link_to_git(&tmpfile2, &r_hash, tmpfile2,
-                                      scratch_pool, scratch_pool));
-
-      if (l_hash && r_hash)
-        {
-          /* The symlink has changed. But we can't tell the user of the
-             diff whether we are writing git diffs or svn diffs of the
-             symlink... except when we add a git-like index line */
-
-          l_hash = apr_pstrndup(scratch_pool, l_hash, 8);
-          r_hash = apr_pstrndup(scratch_pool, r_hash, 8);
-
-          index_shas = apr_psprintf(scratch_pool, "%8s..%8s",
-                                    l_hash, r_hash);
-        }
-    }
-
-  if (! dwi->force_binary && (mt1_binary || mt2_binary))
-    {
-      /* Print out the diff header. */
-      SVN_ERR(print_diff_index_header(outstream, dwi->header_encoding,
-                                      index_path, "", scratch_pool));
-      *wrote_header = TRUE;
-
-      /* ### Print git diff headers. */
-
-      if (dwi->use_git_diff_format)
-        {
-          svn_stream_t *left_stream;
-          svn_stream_t *right_stream;
-
-          SVN_ERR(print_git_diff_header(outstream,
-                                        &label1, &label2,
-                                        operation,
-                                        rev1, rev2,
-                                        diff_relpath,
-                                        copyfrom_path, copyfrom_rev,
-                                        left_props, right_props,
-                                        index_shas,
-                                        dwi->header_encoding,
-                                        &dwi->ddi, scratch_pool));
-
-          SVN_ERR(svn_stream_open_readonly(&left_stream, tmpfile1,
-                                           scratch_pool, scratch_pool));
-          SVN_ERR(svn_stream_open_readonly(&right_stream, tmpfile2,
-                                           scratch_pool, scratch_pool));
-          SVN_ERR(svn_diff_output_binary(outstream,
-                                         left_stream, right_stream,
-                                         dwi->cancel_func, dwi->cancel_baton,
-                                         scratch_pool));
-        }
-      else
-        {
-          SVN_ERR(svn_stream_printf_from_utf8(outstream,
-                   dwi->header_encoding, scratch_pool,
-                   _("Cannot display: file marked as a binary type.%s"),
-                   APR_EOL_STR));
-
-          if (mt1_binary && !mt2_binary)
-            SVN_ERR(svn_stream_printf_from_utf8(outstream,
-                     dwi->header_encoding, scratch_pool,
-                     "svn:mime-type = %s" APR_EOL_STR, mimetype1));
-          else if (mt2_binary && !mt1_binary)
-            SVN_ERR(svn_stream_printf_from_utf8(outstream,
-                     dwi->header_encoding, scratch_pool,
-                     "svn:mime-type = %s" APR_EOL_STR, mimetype2));
-          else if (mt1_binary && mt2_binary)
-            {
-              if (strcmp(mimetype1, mimetype2) == 0)
-                SVN_ERR(svn_stream_printf_from_utf8(outstream,
-                         dwi->header_encoding, scratch_pool,
-                         "svn:mime-type = %s" APR_EOL_STR,
-                         mimetype1));
-              else
-                SVN_ERR(svn_stream_printf_from_utf8(outstream,
-                         dwi->header_encoding, scratch_pool,
-                         "svn:mime-type = (%s, %s)" APR_EOL_STR,
-                         mimetype1, mimetype2));
-            }
-        }
-
-      /* Exit early. */
-      return SVN_NO_ERROR;
-    }
-
-
-  if (dwi->diff_cmd)
-    {
-      svn_stream_t *errstream = dwi->errstream;
-      apr_file_t *outfile;
-      apr_file_t *errfile;
-      const char *outfilename;
-      const char *errfilename;
-      svn_stream_t *stream;
-      int exitcode;
-
-      /* Print out the diff header. */
-      SVN_ERR(print_diff_index_header(outstream, dwi->header_encoding,
-                                      index_path, "", scratch_pool));
-      *wrote_header = TRUE;
-
-      /* ### Do we want to add git diff headers here too? I'd say no. The
-       * ### 'Index' and '===' line is something subversion has added. The rest
-       * ### is up to the external diff application. We may be dealing with
-       * ### a non-git compatible diff application.*/
-
-      /* We deal in streams, but svn_io_run_diff2() deals in file handles,
-         so we may need to make temporary files and then copy the contents
-         to our stream. */
-      outfile = svn_stream__aprfile(outstream);
-      if (outfile)
-        outfilename = NULL;
-      else
-        SVN_ERR(svn_io_open_unique_file3(&outfile, &outfilename, NULL,
-                                         svn_io_file_del_on_pool_cleanup,
-                                         scratch_pool, scratch_pool));
-
-      errfile = svn_stream__aprfile(errstream);
-      if (errfile)
-        errfilename = NULL;
-      else
-        SVN_ERR(svn_io_open_unique_file3(&errfile, &errfilename, NULL,
-                                         svn_io_file_del_on_pool_cleanup,
-                                         scratch_pool, scratch_pool));
-
-      SVN_ERR(svn_io_run_diff2(".",
-                               dwi->options.for_external.argv,
-                               dwi->options.for_external.argc,
-                               label1, label2,
-                               tmpfile1, tmpfile2,
-                               &exitcode, outfile, errfile,
-                               dwi->diff_cmd, scratch_pool));
-
-      /* Now, open and copy our files to our output streams. */
-      if (outfilename)
-        {
-          SVN_ERR(svn_io_file_close(outfile, scratch_pool));
-          SVN_ERR(svn_stream_open_readonly(&stream, outfilename,
-                                           scratch_pool, scratch_pool));
-          SVN_ERR(svn_stream_copy3(stream, svn_stream_disown(outstream,
-                                                             scratch_pool),
-                                   NULL, NULL, scratch_pool));
-        }
-      if (errfilename)
-        {
-          SVN_ERR(svn_io_file_close(errfile, scratch_pool));
-          SVN_ERR(svn_stream_open_readonly(&stream, errfilename,
-                                           scratch_pool, scratch_pool));
-          SVN_ERR(svn_stream_copy3(stream, svn_stream_disown(errstream,
-                                                             scratch_pool),
-                                   NULL, NULL, scratch_pool));
-        }
-    }
-  else   /* use libsvn_diff to generate the diff  */
-    {
-      svn_diff_t *diff;
-
-      SVN_ERR(svn_diff_file_diff_2(&diff, tmpfile1, tmpfile2,
-                                   dwi->options.for_internal,
-                                   scratch_pool));
-
-      if (force_diff
-          || dwi->use_git_diff_format
-          || svn_diff_contains_diffs(diff))
-        {
-          /* Print out the diff header. */
-          SVN_ERR(print_diff_index_header(outstream, dwi->header_encoding,
-                                          index_path, "", scratch_pool));
-          *wrote_header = TRUE;
-
-          if (dwi->use_git_diff_format)
-            {
-              SVN_ERR(print_git_diff_header(outstream,
-                                            &label1, &label2,
-                                            operation,
-                                            rev1, rev2,
-                                            diff_relpath,
-                                            copyfrom_path, copyfrom_rev,
-                                            left_props, right_props,
-                                            index_shas,
-                                            dwi->header_encoding,
-                                            &dwi->ddi, scratch_pool));
-            }
-
-          /* Output the actual diff */
-          if (force_diff || svn_diff_contains_diffs(diff))
-            SVN_ERR(svn_diff_file_output_unified4(outstream, diff,
-                     tmpfile1, tmpfile2, label1, label2,
-                     dwi->header_encoding, rel_to_dir,
-                     dwi->options.for_internal->show_c_function,
-                     dwi->options.for_internal->context_size,
-                     dwi->cancel_func, dwi->cancel_baton,
-                     scratch_pool));
-        }
-    }
-
-  return SVN_NO_ERROR;
-}
-
-/* An svn_diff_tree_processor_t callback. */
-static svn_error_t *
-diff_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 struct svn_diff_tree_processor_t *processor,
-                  apr_pool_t *scratch_pool)
-{
-  diff_writer_info_t *dwi = processor->baton;
-  svn_boolean_t wrote_header = FALSE;
-
-  if (file_modified)
-    SVN_ERR(diff_content_changed(&wrote_header, relpath,
-                                 left_file, right_file,
-                                 left_source->revision,
-                                 right_source->revision,
-                                 left_props, right_props,
-                                 svn_diff_op_modified, FALSE,
-                                 NULL,
-                                 SVN_INVALID_REVNUM, dwi,
-                                 scratch_pool));
-  if (prop_changes->nelts > 0)
-    SVN_ERR(diff_props_changed(relpath,
-                               left_source->revision,
-                               right_source->revision, prop_changes,
-                               left_props, right_props, !wrote_header,
-                               dwi, scratch_pool));
-  return SVN_NO_ERROR;
-}
-
-/* Because the repos-diff editor passes at least one empty file to
-   each of these next two functions, they can be dumb wrappers around
-   the main workhorse routine. */
-
-/* An svn_diff_tree_processor_t callback. */
-static svn_error_t *
-diff_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 struct svn_diff_tree_processor_t *processor,
-                apr_pool_t *scratch_pool)
-{
-  diff_writer_info_t *dwi = processor->baton;
-  svn_boolean_t wrote_header = FALSE;
-  const char *left_file;
-  apr_hash_t *left_props;
-  apr_array_header_t *prop_changes;
-
-  if (dwi->no_diff_added)
-    {
-      const char *index_path = relpath;
-
-      if (dwi->ddi.anchor)
-        index_path = svn_dirent_join(dwi->ddi.anchor, relpath,
-                                     scratch_pool);
-
-      SVN_ERR(print_diff_index_header(dwi->outstream, dwi->header_encoding,
-                                      index_path, " (added)",
-                                      scratch_pool));
-      wrote_header = TRUE;
-      return SVN_NO_ERROR;
-    }
-
-  /* During repos->wc diff of a copy revision numbers obtained
-   * from the working copy are always SVN_INVALID_REVNUM. */
-  if (copyfrom_source && !dwi->show_copies_as_adds)
-    {
-      left_file = copyfrom_file;
-      left_props = copyfrom_props ? copyfrom_props : apr_hash_make(scratch_pool);
-    }
-  else
-    {
-      if (!dwi->empty_file)
-        SVN_ERR(svn_io_open_unique_file3(NULL, &dwi->empty_file,
-                                         NULL, svn_io_file_del_on_pool_cleanup,
-                                         dwi->pool, scratch_pool));
-
-      left_file = dwi->empty_file;
-      left_props = apr_hash_make(scratch_pool);
-
-      copyfrom_source = NULL;
-      copyfrom_file = NULL;
-    }
-
-  SVN_ERR(svn_prop_diffs(&prop_changes, right_props, left_props, scratch_pool));
-
-  if (copyfrom_source && right_file)
-    SVN_ERR(diff_content_changed(&wrote_header, relpath,
-                                 left_file, right_file,
-                                 copyfrom_source->revision,
-                                 right_source->revision,
-                                 left_props, right_props,
-                                 copyfrom_source->moved_from_relpath
-                                    ? svn_diff_op_moved
-                                    : svn_diff_op_copied,
-                                 TRUE /* force diff output */,
-                                 copyfrom_source->moved_from_relpath
-                                    ? copyfrom_source->moved_from_relpath
-                                    : copyfrom_source->repos_relpath,
-                                 copyfrom_source->revision,
-                                 dwi, scratch_pool));
-  else if (right_file)
-    SVN_ERR(diff_content_changed(&wrote_header, relpath,
-                                 left_file, right_file,
-                                 DIFF_REVNUM_NONEXISTENT,
-                                 right_source->revision,
-                                 left_props, right_props,
-                                 svn_diff_op_added,
-                                 TRUE /* force diff output */,
-                                 NULL, SVN_INVALID_REVNUM,
-                                 dwi, scratch_pool));
-
-  if (prop_changes->nelts > 0)
-    SVN_ERR(diff_props_changed(relpath,
-                               copyfrom_source ? copyfrom_source->revision
-                                               : DIFF_REVNUM_NONEXISTENT,
-                               right_source->revision,
-                               prop_changes,
-                               left_props, right_props,
-                               ! wrote_header, dwi, scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-/* An svn_diff_tree_processor_t callback. */
-static svn_error_t *
-diff_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 struct svn_diff_tree_processor_t *processor,
-                  apr_pool_t *scratch_pool)
-{
-  diff_writer_info_t *dwi = processor->baton;
-
-  if (dwi->no_diff_deleted)
-    {
-      const char *index_path = relpath;
-
-      if (dwi->ddi.anchor)
-        index_path = svn_dirent_join(dwi->ddi.anchor, relpath,
-                                     scratch_pool);
-
-      SVN_ERR(print_diff_index_header(dwi->outstream, dwi->header_encoding,
-                                      index_path, " (deleted)",
-                                      scratch_pool));
-    }
-  else
-    {
-      svn_boolean_t wrote_header = FALSE;
-
-      if (!dwi->empty_file)
-        SVN_ERR(svn_io_open_unique_file3(NULL, &dwi->empty_file,
-                                         NULL, svn_io_file_del_on_pool_cleanup,
-                                         dwi->pool, scratch_pool));
-
-      if (left_file)
-        SVN_ERR(diff_content_changed(&wrote_header, relpath,
-                                     left_file, dwi->empty_file,
-                                     left_source->revision,
-                                     DIFF_REVNUM_NONEXISTENT,
-                                     left_props,
-                                     NULL,
-                                     svn_diff_op_deleted, FALSE,
-                                     NULL, SVN_INVALID_REVNUM,
-                                     dwi,
-                                     scratch_pool));
-
-      if (left_props && apr_hash_count(left_props))
-        {
-          apr_array_header_t *prop_changes;
-
-          SVN_ERR(svn_prop_diffs(&prop_changes, apr_hash_make(scratch_pool),
-                                 left_props, scratch_pool));
-
-          SVN_ERR(diff_props_changed(relpath,
-                                     left_source->revision,
-                                     DIFF_REVNUM_NONEXISTENT,
-                                     prop_changes,
-                                     left_props, NULL,
-                                     ! wrote_header, dwi, scratch_pool));
-        }
-    }
-
-  return SVN_NO_ERROR;
-}
-
-/* An svn_wc_diff_callbacks4_t function. */
-static svn_error_t *
-diff_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)
-{
-  diff_writer_info_t *dwi = processor->baton;
-
-  SVN_ERR(diff_props_changed(relpath,
-                             left_source->revision,
-                             right_source->revision,
-                             prop_changes,
-                             left_props, right_props,
-                             TRUE /* show_diff_header */,
-                             dwi,
-                             scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-/* An svn_diff_tree_processor_t callback. */
-static svn_error_t *
-diff_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 struct svn_diff_tree_processor_t *processor,
-               apr_pool_t *scratch_pool)
-{
-  diff_writer_info_t *dwi = processor->baton;
-  apr_hash_t *left_props;
-  apr_array_header_t *prop_changes;
-
-  if (dwi->no_diff_added)
-    return SVN_NO_ERROR;
-
-  if (copyfrom_source && !dwi->show_copies_as_adds)
-    {
-      left_props = copyfrom_props ? copyfrom_props
-                                  : apr_hash_make(scratch_pool);
-    }
-  else
-    {
-      left_props = apr_hash_make(scratch_pool);
-      copyfrom_source = NULL;
-    }
-
-  SVN_ERR(svn_prop_diffs(&prop_changes, right_props, left_props,
-                         scratch_pool));
-
-  return svn_error_trace(diff_props_changed(relpath,
-                                            copyfrom_source ? copyfrom_source->revision
-                                                            : DIFF_REVNUM_NONEXISTENT,
-                                            right_source->revision,
-                                            prop_changes,
-                                            left_props, right_props,
-                                            TRUE /* show_diff_header */,
-                                            dwi,
-                                            scratch_pool));
-}
-
-/* An svn_diff_tree_processor_t callback. */
-static svn_error_t *
-diff_dir_deleted(const char *relpath,
-                 const svn_diff_source_t *left_source,
-                 /*const*/ apr_hash_t *left_props,
-                 void *dir_baton,
-                 const struct svn_diff_tree_processor_t *processor,
-                 apr_pool_t *scratch_pool)
-{
-  diff_writer_info_t *dwi = processor->baton;
-  apr_array_header_t *prop_changes;
-  apr_hash_t *right_props;
-
-  if (dwi->no_diff_deleted)
-    return SVN_NO_ERROR;
-
-  right_props = apr_hash_make(scratch_pool);
-  SVN_ERR(svn_prop_diffs(&prop_changes, right_props,
-                         left_props, scratch_pool));
-
-  SVN_ERR(diff_props_changed(relpath,
-                             left_source->revision,
-                             DIFF_REVNUM_NONEXISTENT,
-                             prop_changes,
-                             left_props, right_props,
-                             TRUE /* show_diff_header */,
-                             dwi,
-                             scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-/*-----------------------------------------------------------------*/
-
 /** The logic behind 'svn diff' and 'svn merge'.  */
 
 
@@ -2546,134 +1196,6 @@ do_diff(svn_client__diff_driver_info_t *
   return SVN_NO_ERROR;
 }
 
-/* Initialize DWI.diff_cmd and DWI.options,
- * according to OPTIONS and CONFIG.  CONFIG and OPTIONS may be null.
- * Allocate the fields in RESULT_POOL, which should be at least as long-lived
- * as the pool DWI itself is allocated in.
- */
-static svn_error_t *
-create_diff_writer_info(diff_writer_info_t *dwi,
-                        const apr_array_header_t *options,
-                        apr_hash_t *config, apr_pool_t *result_pool)
-{
-  const char *diff_cmd = NULL;
-
-  /* See if there is a diff command and/or diff arguments. */
-  if (config)
-    {
-      svn_config_t *cfg = svn_hash_gets(config, SVN_CONFIG_CATEGORY_CONFIG);
-      svn_config_get(cfg, &diff_cmd, SVN_CONFIG_SECTION_HELPERS,
-                     SVN_CONFIG_OPTION_DIFF_CMD, NULL);
-      if (options == NULL)
-        {
-          const char *diff_extensions;
-          svn_config_get(cfg, &diff_extensions, SVN_CONFIG_SECTION_HELPERS,
-                         SVN_CONFIG_OPTION_DIFF_EXTENSIONS, NULL);
-          if (diff_extensions)
-            options = svn_cstring_split(diff_extensions, " \t\n\r", TRUE,
-                                        result_pool);
-        }
-    }
-
-  if (options == NULL)
-    options = apr_array_make(result_pool, 0, sizeof(const char *));
-
-  if (diff_cmd)
-    SVN_ERR(svn_path_cstring_to_utf8(&dwi->diff_cmd, diff_cmd,
-                                     result_pool));
-  else
-    dwi->diff_cmd = NULL;
-
-  /* If there was a command, arrange options to pass to it. */
-  if (dwi->diff_cmd)
-    {
-      const char **argv = NULL;
-      int argc = options->nelts;
-      if (argc)
-        {
-          int i;
-          argv = apr_palloc(result_pool, argc * sizeof(char *));
-          for (i = 0; i < argc; i++)
-            SVN_ERR(svn_utf_cstring_to_utf8(&argv[i],
-                      APR_ARRAY_IDX(options, i, const char *), result_pool));
-        }
-      dwi->options.for_external.argv = argv;
-      dwi->options.for_external.argc = argc;
-    }
-  else  /* No command, so arrange options for internal invocation instead. */
-    {
-      dwi->options.for_internal = svn_diff_file_options_create(result_pool);
-      SVN_ERR(svn_diff_file_options_parse(dwi->options.for_internal,
-                                          options, result_pool));
-    }
-
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_client__get_diff_writer_svn(
-                svn_diff_tree_processor_t **diff_processor,
-                svn_client__diff_driver_info_t **ddi_p,
-                const apr_array_header_t *options,
-                const char *relative_to_dir,
-                svn_boolean_t no_diff_added,
-                svn_boolean_t no_diff_deleted,
-                svn_boolean_t show_copies_as_adds,
-                svn_boolean_t ignore_content_type,
-                svn_boolean_t ignore_properties,
-                svn_boolean_t properties_only,
-                svn_boolean_t use_git_diff_format,
-                svn_boolean_t pretty_print_mergeinfo,
-                const char *header_encoding,
-                svn_stream_t *outstream,
-                svn_stream_t *errstream,
-                svn_client_ctx_t *ctx,
-                apr_pool_t *pool)
-{
-  diff_writer_info_t *dwi = apr_pcalloc(pool, sizeof(*dwi));
-  svn_diff_tree_processor_t *processor;
-
-  /* setup callback and baton */
-
-  SVN_ERR(create_diff_writer_info(dwi, options,
-                                  ctx->config, pool));
-  dwi->pool = pool;
-  dwi->outstream = outstream;
-  dwi->errstream = errstream;
-  dwi->header_encoding = header_encoding;
-
-  dwi->force_binary = ignore_content_type;
-  dwi->ignore_properties = ignore_properties;
-  dwi->properties_only = properties_only;
-  dwi->relative_to_dir = relative_to_dir;
-  dwi->use_git_diff_format = use_git_diff_format;
-  dwi->no_diff_added = no_diff_added;
-  dwi->no_diff_deleted = no_diff_deleted;
-  dwi->show_copies_as_adds = show_copies_as_adds;
-  dwi->pretty_print_mergeinfo = pretty_print_mergeinfo;
-
-  dwi->cancel_func = ctx->cancel_func;
-  dwi->cancel_baton = ctx->cancel_baton;
-
-  dwi->ddi.wc_ctx = ctx->wc_ctx;
-  dwi->ddi.session_relpath = NULL;
-  dwi->ddi.anchor = NULL;
-
-  processor = svn_diff__tree_processor_create(dwi, pool);
-
-  processor->dir_added = diff_dir_added;
-  processor->dir_changed = diff_dir_changed;
-  processor->dir_deleted = diff_dir_deleted;
-
-  processor->file_added = diff_file_added;
-  processor->file_changed = diff_file_changed;
-  processor->file_deleted = diff_file_deleted;
-
-  *diff_processor = processor;
-  *ddi_p = &dwi->ddi;
-  return SVN_NO_ERROR;
-}
-
 /*----------------------------------------------------------------------- */
 
 /*** Public Interfaces. ***/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.