Hi all,

 I am in the process of implementing the '--diff-copy-from' in svn diff,
just similar to the '--diff-copy-from' in the svnlook diff. I have done
the coding part for all the 'ra' layers, except the 'svnserve'. 

Meanwhile I came to know that the 'send_copyfrom_args' for 'svn
update' (client side) has been rolled back by Mike, with reference to
the issue #3711. But now, in my case, I genuinely need the
'send_copyfrom_args' for getting the 'copyfrom_revision' and the
'copyfrom_path' of the file getting diffed. 

I use the existing ra_(neon|serf|local) API to send_copy_from_args to
backend.

After learning the rollback in #3711 I am worried whether similar
reverts are possible in ra_layer also.

I am attaching the patch and log so far just to show the progress.


Thanks and regards
Prabhu
[[[
Make svn diff to accept "--diff-copy-from" inorder to compare/diff 
against the copy-source file.

* subversion/libsvn_ra/deprecated.c
  (): deprecated svn_ra_do_diff3
  (svn_ra_do_diff2): pass FALSE for 'diff_copy_from' argument in do_diff 
function.

* subversion/libsvn_ra/wrapper_template.h
  (compat_do_diff): pass FALSE for 'diff_copy_from' argument in do_diff 
function.

* subversion/libsvn_ra/ra_loader.c
  (svn_ra_do_diff4): introduced 'diff_copy_from' argument.
                     pass 'diff_copy_from' argument in do_diff function.

* subversion/libsvn_ra/ra_loader.h
  svn_ra__vtable_t: introduced 'diff-copy-from' argument in do_diff.

* subversion/libsvn_ra_local/ra_plugin.c
  (svn_ra_local__do_diff): introduced 'diff_copy_from' argument.
                           if 'diff_copy_from', pass true for send_copyfrom_args
                           if 'diff_copy_from', pass false for ignore_ancestry
* subversion/svn/cl.h
  svn_cl__opt_state_t: introduced 'diff_copy_from' option.

* subversion/svn/diff-cmd.c
  (svn_cl__diff): passed 'diff_copy_from' option to svn_client_diff5 function
                  and the svn_client_diff_peg5 function.

* subversion/svn/log-cmd.c
  (log_entry_receiver): passed false for diff_copy_from to svn_client_diff5 
function.

* subversion/svn/main.c
  (): introduced the diff_copy_from option and display information to user.
  svn_cl__options[]: added information about the diff_copy_from option.
  svn_cl__cmd_table[]: added diff-copy-from to the subcommand table.
  (main): handle the 'diff-copy-from' case.

* subversion/include/svn_client.h
  (svn_client_diff5): introduced the 'diff_copy_from' argument.
  (svn_client_diff_peg5): introduced the 'diff_copy_from' argument.

* subversion/include/svn_ra.h
  (): deprecated svn_ra_do_diff3 and introduced the 
      svn_ra_do_diff4 to accept 'diff_copy_from' argument.

* subversion/libsvn_client/deprecated.c
  (svn_client_diff4): pass false for diff_copy_from in svn_client_diff5 for 
                      backporting purpose.
  (svn_client_diff_peg4):pass false for diff_copy_from in svn_client_diff_peg5
                         for backporting purpose.

* subversion/libsvn_client/repos_diff.c
  edit_baton: store the value of diff_copy_from.
  (get_file_from_ra): introduced the 'path' argument to pass the copyfrom_path.
  (diff_deleted_dir): passed path in the 'path' argument.
  (delete_entry): pass 'path' in the get_file_from_ra function.
  (add_file): if 'diff_copy_from' and copyfrom_revision are valid, add the file
              from the copy-source.
  (close_file): if diff_copy_from is set, call the file_changed callback.
  (svn_client__get_diff_editor): introduced the 'diff_copy_from' argument and
                                 assigned it in the edit baton.

* subversion/libsvn_client/client.h
  (svn_client__get_diff_editor): introduced the 'diff_copy_from' argument.

* subversion/libsvn_client/merge.c
  (drive_merge_report_editor): pass false for diff_copy_from to svn_ra_do_diff4
                               function and svn_client__get_diff_editor funtion.

* subversion/libsvn_client/diff.c
  (diff_repos_repos): if diff_copy_from is set, perform diff with respect to the
                      copy-source.
  (diff_repos_wc): if diff_copy_from is set, perform diff with respect to the
                      copy-source.
  (do_diff): perform diff with respect to the diff_copy_from argument.
  (diff_summarize_repos_repos): pass false for 'diff_copy_from' to 
                                svn_ra_do_diff4 function.
  (svn_client_diff5): introduced the 'diff_copy_from' argument and pass it to
                      do_diff function.
  (svn_client_diff_peg5): introduced the 'diff_copy_from' argument and pass it
                          to do_diff function.

* subversion/libsvn_ra_neon/ra_neon.h
  (svn_ra_neon__do_diff): introduced the 'diff_copy_from' argument.

* subversion/libsvn_ra_neon/fetch.c
  (svn_ra_neon__do_diff): introduced the 'diff_copy_from' argument and pass it 
to
                          make_reporter.

* subversion/libsvn_ra_serf/ra_serf.h
  (svn_ra_serf__do_diff): introduced the 'diff_copy_from' argument.

* subversion/libsvn_ra_serf/update.c
  (svn_ra_serf__do_diff): introduced the 'diff_copy_from' argument and pass it 
to 
                          make_update_reporter.

Patch by: Prabhu Gnana Sundar <prabh...@collab.net>
Suggested by: Kamesh Jayachandran <kam...@collab.net>
]]]
Index: subversion/libsvn_ra/deprecated.c
===================================================================
--- subversion/libsvn_ra/deprecated.c	(revision 1037675)
+++ subversion/libsvn_ra/deprecated.c	(working copy)
@@ -248,6 +248,31 @@
                                    keep_locks, pool);
 }
 
+svn_error_t *svn_ra_do_diff3(svn_ra_session_t *session,
+                             const svn_ra_reporter3_t **reporter,
+                             void **report_baton,
+                             svn_revnum_t revision,
+                             const char *diff_target,
+                             svn_depth_t depth,
+                             svn_boolean_t ignore_ancestry,
+                             svn_boolean_t text_deltas,
+                             const char *versus_url,
+                             const svn_delta_editor_t *diff_editor,
+                             void *diff_baton,
+                             apr_pool_t *pool)
+{
+  SVN_ERR_ASSERT(svn_path_is_empty(diff_target)
+                 || svn_path_is_single_path_component(diff_target));
+  return session->vtable->do_diff(session,
+                                  reporter, report_baton,
+                                  revision, diff_target,
+                                  depth, ignore_ancestry,
+                                  text_deltas, FALSE /* diff copy from */,
+                                  versus_url, diff_editor,
+                                  diff_baton, pool);
+}
+
+
 svn_error_t *svn_ra_do_diff2(svn_ra_session_t *session,
                              const svn_ra_reporter2_t **reporter,
                              void **report_baton,
@@ -270,8 +295,8 @@
                                   &(b->reporter3), &(b->reporter3_baton),
                                   revision, diff_target,
                                   SVN_DEPTH_INFINITY_OR_FILES(recurse),
-                                  ignore_ancestry, text_deltas, versus_url,
-                                  diff_editor, diff_baton, pool);
+                                  ignore_ancestry, text_deltas, FALSE,
+                                  versus_url, diff_editor, diff_baton, pool);
 }
 
 svn_error_t *svn_ra_do_diff(svn_ra_session_t *session,
Index: subversion/libsvn_ra/wrapper_template.h
===================================================================
--- subversion/libsvn_ra/wrapper_template.h	(revision 1037675)
+++ subversion/libsvn_ra/wrapper_template.h	(working copy)
@@ -361,7 +361,7 @@
   svn_depth_t depth = SVN_DEPTH_INFINITY_OR_FILES(recurse);
 
   SVN_ERR(VTBL.do_diff(session_baton, &reporter3, &baton3, revision,
-                       diff_target, depth, ignore_ancestry, TRUE,
+                       diff_target, depth, ignore_ancestry, TRUE, FALSE,
                        versus_url, diff_editor, diff_baton, pool));
 
   compat_wrap_reporter(reporter, report_baton, reporter3, baton3, pool);
Index: subversion/libsvn_ra/ra_loader.c
===================================================================
--- subversion/libsvn_ra/ra_loader.c	(revision 1037675)
+++ subversion/libsvn_ra/ra_loader.c	(working copy)
@@ -845,7 +845,7 @@
                                     status_editor, status_baton, pool);
 }
 
-svn_error_t *svn_ra_do_diff3(svn_ra_session_t *session,
+svn_error_t *svn_ra_do_diff4(svn_ra_session_t *session,
                              const svn_ra_reporter3_t **reporter,
                              void **report_baton,
                              svn_revnum_t revision,
@@ -853,6 +853,7 @@
                              svn_depth_t depth,
                              svn_boolean_t ignore_ancestry,
                              svn_boolean_t text_deltas,
+                             svn_boolean_t diff_copy_from,
                              const char *versus_url,
                              const svn_delta_editor_t *diff_editor,
                              void *diff_baton,
@@ -864,7 +865,8 @@
                                   reporter, report_baton,
                                   revision, diff_target,
                                   depth, ignore_ancestry,
-                                  text_deltas, versus_url, diff_editor,
+                                  text_deltas, diff_copy_from,
+                                  versus_url, diff_editor,
                                   diff_baton, pool);
 }
 
Index: subversion/libsvn_ra/ra_loader.h
===================================================================
--- subversion/libsvn_ra/ra_loader.h	(revision 1037675)
+++ subversion/libsvn_ra/ra_loader.h	(working copy)
@@ -159,10 +159,12 @@
                           svn_depth_t depth,
                           svn_boolean_t ignore_ancestry,
                           svn_boolean_t text_deltas,
+                          svn_boolean_t diff_copy_from,
                           const char *versus_url,
                           const svn_delta_editor_t *diff_editor,
                           void *diff_baton,
                           apr_pool_t *pool);
+
   svn_error_t *(*get_log)(svn_ra_session_t *session,
                           const apr_array_header_t *paths,
                           svn_revnum_t start,
Index: subversion/libsvn_ra_local/ra_plugin.c
===================================================================
--- subversion/libsvn_ra_local/ra_plugin.c	(revision 1037675)
+++ subversion/libsvn_ra_local/ra_plugin.c	(working copy)
@@ -819,6 +819,7 @@
                       svn_depth_t depth,
                       svn_boolean_t ignore_ancestry,
                       svn_boolean_t text_deltas,
+                      svn_boolean_t diff_copy_from,
                       const char *switch_url,
                       const svn_delta_editor_t *update_editor,
                       void *update_baton,
@@ -832,7 +833,7 @@
                        switch_url,
                        text_deltas,
                        depth,
-                       FALSE,
+                       diff_copy_from ? TRUE : FALSE,
                        ignore_ancestry,
                        update_editor,
                        update_baton,
Index: subversion/libsvn_ra_svn/client.c
===================================================================
--- subversion/libsvn_ra_svn/client.c	(revision 1037675)
+++ subversion/libsvn_ra_svn/client.c	(working copy)
@@ -1316,6 +1316,7 @@
                                 svn_depth_t depth,
                                 svn_boolean_t ignore_ancestry,
                                 svn_boolean_t text_deltas,
+                                svn_boolean_t diff_copy_from,
                                 const char *versus_url,
                                 const svn_delta_editor_t *diff_editor,
                                 void *diff_baton, apr_pool_t *pool)
Index: subversion/svn/cl.h
===================================================================
--- subversion/svn/cl.h	(revision 1037675)
+++ subversion/svn/cl.h	(working copy)
@@ -184,6 +184,7 @@
   svn_boolean_t no_ignore;       /* disregard default ignores & svn:ignore's */
   svn_boolean_t no_auth_cache;   /* do not cache authentication information */
   svn_boolean_t no_diff_deleted; /* do not show diffs for deleted files */
+  svn_boolean_t diff_copy_from;  /* diff from the source */
   svn_boolean_t show_copies_as_adds; /* do not diff copies with their source */
   svn_boolean_t notice_ancestry; /* notice ancestry for diff-y operations */
   svn_boolean_t ignore_ancestry; /* ignore ancestry for merge-y operations */
Index: subversion/svn/diff-cmd.c
===================================================================
--- subversion/svn/diff-cmd.c	(revision 1037675)
+++ subversion/svn/diff-cmd.c	(working copy)
@@ -347,6 +347,7 @@
                      opt_state->depth,
                      ! opt_state->notice_ancestry,
                      opt_state->no_diff_deleted,
+                     opt_state->diff_copy_from,
                      opt_state->show_copies_as_adds,
                      opt_state->force,
                      opt_state->use_git_diff_format,
@@ -392,6 +393,7 @@
                      opt_state->depth,
                      ! opt_state->notice_ancestry,
                      opt_state->no_diff_deleted,
+                     opt_state->diff_copy_from,
                      opt_state->show_copies_as_adds,
                      opt_state->force,
                      opt_state->use_git_diff_format,
Index: subversion/svn/log-cmd.c
===================================================================
--- subversion/svn/log-cmd.c	(revision 1037675)
+++ subversion/svn/log-cmd.c	(working copy)
@@ -303,6 +303,7 @@
                              svn_depth_infinity,
                              FALSE, /* ignore ancestry */
                              TRUE, /* no diff deleted */
+                             FALSE, /* diff copy from */
                              FALSE, /* show copies as adds */
                              FALSE, /* ignore content type */
                              FALSE, /* use git diff format */
@@ -336,6 +337,7 @@
                                          svn_depth_infinity,
                                          FALSE, /* ignore ancestry */
                                          TRUE, /* no diff deleted */
+                                         FALSE, /* diff copy from */
                                          FALSE, /* show copies as adds */
                                          FALSE, /* ignore content type */
                                          FALSE, /* use git diff format */
Index: subversion/svn/main.c
===================================================================
--- subversion/svn/main.c	(revision 1037675)
+++ subversion/svn/main.c	(working copy)
@@ -88,6 +88,7 @@
   opt_no_auth_cache,
   opt_no_autoprops,
   opt_no_diff_deleted,
+  opt_diff_copy_from,
   opt_no_ignore,
   opt_no_unlock,
   opt_non_interactive,
@@ -232,6 +233,8 @@
                     N_("try operation but make no changes")},
   {"no-diff-deleted", opt_no_diff_deleted, 0,
                     N_("do not print differences for deleted files")},
+  {"diff-copy-from", opt_diff_copy_from, 0,
+                    N_("print copy history of files")},
   {"notice-ancestry", opt_notice_ancestry, 0,
                     N_("notice ancestry when calculating differences")},
   {"ignore-ancestry", opt_ignore_ancestry, 0,
@@ -352,6 +355,7 @@
   {"nac",           opt_no_auth_cache, 0, NULL},
   {"dry",           opt_dry_run, 0, NULL},
   {"ndd",           opt_no_diff_deleted, 0, NULL},
+  {"dcf",           opt_diff_copy_from, 0, NULL},
   {"na",            opt_notice_ancestry, 0, NULL},
   {"ia",            opt_ignore_ancestry, 0, NULL},
   {"ie",            opt_ignore_externals, 0, NULL},
@@ -543,8 +547,9 @@
      "\n"
      "  Use just 'svn diff' to display local modifications in a working copy.\n"),
     {'r', 'c', opt_old_cmd, opt_new_cmd, 'N', opt_depth, opt_diff_cmd,
-     opt_internal_diff, 'x', opt_no_diff_deleted, opt_show_copies_as_adds,
-     opt_notice_ancestry, opt_summarize, opt_changelist, opt_force, opt_xml,
+     opt_internal_diff, 'x', opt_no_diff_deleted, opt_diff_copy_from,
+     opt_show_copies_as_adds, opt_notice_ancestry, opt_summarize,
+     opt_changelist, opt_force, opt_xml,
      opt_use_git_diff_format} },
   { "export", svn_cl__export, {0}, N_
     ("Create an unversioned copy of a tree.\n"
@@ -1624,6 +1629,9 @@
       case opt_no_diff_deleted:
         opt_state.no_diff_deleted = TRUE;
         break;
+      case opt_diff_copy_from:
+        opt_state.diff_copy_from = TRUE;
+        break;
       case opt_show_copies_as_adds:
         opt_state.show_copies_as_adds = TRUE;
         break;
Index: subversion/include/svn_client.h
===================================================================
--- subversion/include/svn_client.h	(revision 1037675)
+++ subversion/include/svn_client.h	(working copy)
@@ -2633,6 +2633,9 @@
  *
  * If @a no_diff_deleted is TRUE, then no diff output will be
  * generated on deleted files.
+ * 
+ * If @a diff_copy_from is TRUE, then the diff output will be generated
+ * with respect to the copy-source.
  *
  * If @a show_copies_as_adds is TRUE, then copied files will not be diffed
  * against their copyfrom source, and will appear in the diff output
@@ -2684,6 +2687,7 @@
                  svn_depth_t depth,
                  svn_boolean_t ignore_ancestry,
                  svn_boolean_t no_diff_deleted,
+                 svn_boolean_t diff_copy_from,
                  svn_boolean_t show_copies_as_adds,
                  svn_boolean_t ignore_content_type,
                  svn_boolean_t use_git_diff_format,
@@ -2797,6 +2801,9 @@
  * changed between @a start_revision and @a end_revision.  @a path can
  * be either a working-copy path or URL.
  *
+ * If @a diff_copy_from is TRUE, then the diff output will be generated
+ * with respect to the copy-source.
+ *
  * If @a peg_revision is #svn_opt_revision_unspecified, behave
  * identically to svn_client_diff5(), using @a path for both of that
  * function's @a path1 and @a path2 argments.
@@ -2815,6 +2822,7 @@
                      svn_depth_t depth,
                      svn_boolean_t ignore_ancestry,
                      svn_boolean_t no_diff_deleted,
+                     svn_boolean_t diff_copy_from,
                      svn_boolean_t show_copies_as_adds,
                      svn_boolean_t ignore_content_type,
                      svn_boolean_t use_git_diff_format,
Index: subversion/include/svn_ra.h
===================================================================
--- subversion/include/svn_ra.h	(revision 1037675)
+++ subversion/include/svn_ra.h	(working copy)
@@ -1336,6 +1336,8 @@
  * handler returned by apply_textdelta will be called once with a NULL
  * @c svn_txdelta_window_t pointer.
  *
+ * Pass TRUE to @a diff_copy_from to do the diff against the copy-source.
+ *
  * Use @a pool for memory allocation.
  *
  * @note The reporter provided by this function does NOT supply copy-
@@ -1345,10 +1347,10 @@
  * needed, and sending too much data back, a pre-1.5 'recurse'
  * directive may be sent to the server, based on @a depth.
  *
- * @since New in 1.5.
+ * @since New in 1.7.
  */
 svn_error_t *
-svn_ra_do_diff3(svn_ra_session_t *session,
+svn_ra_do_diff4(svn_ra_session_t *session,
                 const svn_ra_reporter3_t **reporter,
                 void **report_baton,
                 svn_revnum_t revision,
@@ -1356,12 +1358,35 @@
                 svn_depth_t depth,
                 svn_boolean_t ignore_ancestry,
                 svn_boolean_t text_deltas,
+                svn_boolean_t diff_copy_from,
                 const char *versus_url,
                 const svn_delta_editor_t *diff_editor,
                 void *diff_baton,
                 apr_pool_t *pool);
 
 /**
+ * Similar to svn_ra_do_diff4(), but not taking the @a diff_copy_from
+ * option, hence passing FALSE.
+ *
+ * New code should use svn_ra_do_diff4(). 
+ *
+ * @deprecated Provided for compatibility with the 1.5 API.
+ */
+SVN_DEPRECATED
+svn_error_t *
+svn_ra_do_diff3(svn_ra_session_t *session,
+                const svn_ra_reporter3_t **reporter,
+                void **report_baton,
+                svn_revnum_t revision,
+                const char *diff_target,
+                svn_depth_t depth,
+                svn_boolean_t ignore_ancestry,
+                svn_boolean_t text_deltas,
+                const char *versus_url,
+                const svn_delta_editor_t *diff_editor,
+                void *diff_baton,
+                apr_pool_t *pool);
+/**
  * Similar to svn_ra_do_diff3(), but taking @c svn_ra_reporter2_t
  * instead of @c svn_ra_reporter3_t, and therefore only able to report
  * @c svn_depth_infinity for depths.  Perform the diff according to
Index: subversion/libsvn_client/deprecated.c
===================================================================
--- subversion/libsvn_client/deprecated.c	(revision 1037675)
+++ subversion/libsvn_client/deprecated.c	(working copy)
@@ -785,7 +785,7 @@
 {
   return svn_client_diff5(options, path1, revision1, path2,
                           revision2, relative_to_dir, depth,
-                          ignore_ancestry, no_diff_deleted, FALSE,
+                          ignore_ancestry, no_diff_deleted, FALSE, FALSE,
                           FALSE, ignore_content_type, header_encoding,
                           outfile, errfile, changelists, ctx, pool);
 }
@@ -883,6 +883,7 @@
                               no_diff_deleted,
                               FALSE,
                               FALSE,
+                              FALSE,
                               ignore_content_type,
                               header_encoding,
                               outfile,
Index: subversion/libsvn_client/repos_diff.c
===================================================================
--- subversion/libsvn_client/repos_diff.c	(revision 1037675)
+++ subversion/libsvn_client/repos_diff.c	(working copy)
@@ -93,6 +93,9 @@
      FALSE otherwise. */
   svn_boolean_t walk_deleted_repos_dirs;
 
+  /* TRUE if diff has to be made against the copy source. */
+  svn_boolean_t diff_copy_from;
+
   /* A callback used to see if the client wishes to cancel the running
      operation. */
   svn_cancel_func_t cancel_func;
@@ -308,7 +311,9 @@
  * the file.
  */
 static svn_error_t *
-get_file_from_ra(struct file_baton *b, svn_revnum_t revision)
+get_file_from_ra(struct file_baton *b,
+                 const char *path,
+                 svn_revnum_t revision)
 {
   svn_stream_t *fstream;
 
@@ -317,7 +322,7 @@
                                  b->pool));
 
   SVN_ERR(svn_ra_get_file(b->edit_baton->ra_session,
-                          b->path,
+                          path,
                           revision,
                           fstream, NULL,
                           &(b->pristine_props),
@@ -508,7 +513,7 @@
 
           /* Compare a file being deleted against an empty file */
           b = make_file_baton(path, FALSE, eb, iterpool);
-          SVN_ERR(get_file_from_ra(b, revision));
+          SVN_ERR(get_file_from_ra(b, path, revision));
 
           SVN_ERR(get_empty_file(b->edit_baton, &(b->path_end_revision)));
       
@@ -573,7 +578,7 @@
 
             /* Compare a file being deleted against an empty file */
             b = make_file_baton(path, FALSE, eb, pool);
-            SVN_ERR(get_file_from_ra(b, eb->revision));
+            SVN_ERR(get_file_from_ra(b, path, eb->revision));
             SVN_ERR(get_empty_file(b->edit_baton, &(b->path_end_revision)));
 
             get_file_mime_types(&mimetype1, &mimetype2, b);
@@ -791,8 +796,6 @@
   struct dir_baton *pb = parent_baton;
   struct file_baton *b;
 
-  /* ### TODO: support copyfrom? */
-
   b = make_file_baton(path, TRUE, pb->edit_baton, pool);
   *file_baton = b;
 
@@ -804,8 +807,27 @@
       return SVN_NO_ERROR;
     }
 
-  SVN_ERR(get_empty_file(b->edit_baton, &(b->path_start_revision)));
-  b->pristine_props = pb->edit_baton->empty_hash;
+  if(pb->edit_baton->diff_copy_from && SVN_IS_VALID_REVNUM(copyfrom_revision))
+    {
+      const char *preserved_url;
+      const char *repos_root;
+      SVN_ERR(svn_ra_get_session_url(pb->edit_baton->ra_session,
+                                     &preserved_url,
+                                     pool));
+      SVN_ERR(svn_ra_get_repos_root2(pb->edit_baton->ra_session,
+                                     &repos_root,
+                                     pool));
+      SVN_ERR(svn_ra_reparent(pb->edit_baton->ra_session, repos_root,
+                              pool));
+      SVN_ERR(get_file_from_ra(b, copyfrom_path+1, copyfrom_revision));
+      SVN_ERR(svn_ra_reparent(pb->edit_baton->ra_session,
+                              preserved_url, pool));
+    }
+  else
+    {
+      SVN_ERR(get_empty_file(b->edit_baton, &(b->path_start_revision)));
+      b->pristine_props = pb->edit_baton->empty_hash;
+    }
 
   return SVN_NO_ERROR;
 }
@@ -831,7 +853,7 @@
       return SVN_NO_ERROR;
     }
 
-  SVN_ERR(get_file_from_ra(b, base_revision));
+  SVN_ERR(get_file_from_ra(b, path, base_revision));
 
   return SVN_NO_ERROR;
 }
@@ -962,7 +984,7 @@
       const char *mimetype1, *mimetype2;
       get_file_mime_types(&mimetype1, &mimetype2, b);
 
-      if (b->added)
+      if (b->added && !eb->diff_copy_from)
         SVN_ERR(eb->diff_callbacks->file_added
                 (local_dir_abspath, &content_state, &prop_state, &b->tree_conflicted,
                  b->wcpath,
@@ -1297,6 +1319,7 @@
                             svn_revnum_t revision,
                             svn_wc_notify_func2_t notify_func,
                             void *notify_baton,
+                            svn_boolean_t diff_copy_from,
                             svn_cancel_func_t cancel_func,
                             void *cancel_baton,
                             const svn_delta_editor_t **editor,
@@ -1323,6 +1346,7 @@
   eb->notify_func = notify_func;
   eb->notify_baton = notify_baton;
   eb->walk_deleted_repos_dirs = TRUE;
+  eb->diff_copy_from = diff_copy_from;
   eb->cancel_func = cancel_func;
   eb->cancel_baton = cancel_baton;
 
Index: subversion/libsvn_client/client.h
===================================================================
--- subversion/libsvn_client/client.h	(revision 1037675)
+++ subversion/libsvn_client/client.h	(working copy)
@@ -644,6 +644,7 @@
                             svn_revnum_t revision,
                             svn_wc_notify_func2_t notify_func,
                             void *notify_baton,
+                            svn_boolean_t diff_copy_from,
                             svn_cancel_func_t cancel_func,
                             void *cancel_baton,
                             const svn_delta_editor_t **editor,
Index: subversion/libsvn_client/merge.c
===================================================================
--- subversion/libsvn_client/merge.c	(revision 1037675)
+++ subversion/libsvn_client/merge.c	(working copy)
@@ -5052,14 +5052,14 @@
                                       merge_b->dry_run,
                                       merge_b->ra_session2, revision1,
                                       notification_receiver, notify_b,
-                                      merge_b->ctx->cancel_func,
+                                      FALSE, merge_b->ctx->cancel_func,
                                       merge_b->ctx->cancel_baton,
                                       &diff_editor, &diff_edit_baton,
                                       pool));
-  SVN_ERR(svn_ra_do_diff3(merge_b->ra_session1,
+  SVN_ERR(svn_ra_do_diff4(merge_b->ra_session1,
                           &reporter, &report_baton, revision2,
                           "", depth, merge_b->ignore_ancestry,
-                          TRUE,  /* text_deltas */
+                          TRUE /* text_deltas */, FALSE /*diff_copy_from*/,
                           url2, diff_editor, diff_edit_baton, pool));
 
   /* Drive the reporter. */
Index: subversion/libsvn_client/diff.c
===================================================================
--- subversion/libsvn_client/diff.c	(revision 1037675)
+++ subversion/libsvn_client/diff.c	(working copy)
@@ -1681,6 +1681,7 @@
                  const svn_opt_revision_t *peg_revision,
                  svn_depth_t depth,
                  svn_boolean_t ignore_ancestry,
+                 svn_boolean_t diff_copy_from,
                  apr_pool_t *pool)
 {
   svn_ra_session_t *extra_ra_session;
@@ -1733,13 +1734,13 @@
            NULL, callbacks, callback_baton, depth,
            FALSE /* doesn't matter for diff */, extra_ra_session, rev1,
            NULL /* no notify_func */, NULL /* no notify_baton */,
-           ctx->cancel_func, ctx->cancel_baton,
+           diff_copy_from, ctx->cancel_func, ctx->cancel_baton,
            &diff_editor, &diff_edit_baton, pool));
 
   /* We want to switch our txn into URL2 */
-  SVN_ERR(svn_ra_do_diff3
+  SVN_ERR(svn_ra_do_diff4
           (ra_session, &reporter, &reporter_baton, rev2, target1,
-           depth, ignore_ancestry, TRUE,
+           depth, ignore_ancestry, TRUE, diff_copy_from,
            url2, diff_editor, diff_edit_baton, pool));
 
   /* Drive the reporter; do the diff. */
@@ -1770,6 +1771,7 @@
               svn_boolean_t reverse,
               svn_depth_t depth,
               svn_boolean_t ignore_ancestry,
+              svn_boolean_t diff_copy_from,
               svn_boolean_t show_copies_as_adds,
               svn_boolean_t use_git_diff_format,
               const apr_array_header_t *changelists,
@@ -1878,13 +1880,14 @@
   else
     callback_baton->revnum2 = rev;
 
-  SVN_ERR(svn_ra_do_diff3(ra_session,
+  SVN_ERR(svn_ra_do_diff4(ra_session,
                           &reporter, &reporter_baton,
                           rev,
                           target ? svn_path_uri_decode(target, pool) : NULL,
                           depth,
                           ignore_ancestry,
                           TRUE,  /* text_deltas */
+                          diff_copy_from,
                           url1,
                           diff_editor, diff_edit_baton, pool));
 
@@ -1915,6 +1918,7 @@
         const svn_opt_revision_t *peg_revision,
         svn_depth_t depth,
         svn_boolean_t ignore_ancestry,
+        svn_boolean_t diff_copy_from,
         svn_boolean_t show_copies_as_adds,
         svn_boolean_t use_git_diff_format,
         const apr_array_header_t *changelists,
@@ -1934,15 +1938,16 @@
           SVN_ERR(diff_repos_repos(callbacks, callback_baton, ctx,
                                    path1, path2, revision1, revision2,
                                    peg_revision, depth, ignore_ancestry,
-                                   pool));
+                                   diff_copy_from, pool));
         }
       else /* path2 is a working copy path */
         {
           SVN_ERR(diff_repos_wc(path1, revision1, peg_revision,
                                 path2, revision2, FALSE, depth,
-                                ignore_ancestry, show_copies_as_adds,
-                                use_git_diff_format, changelists,
-                                callbacks, callback_baton, ctx, pool));
+                                ignore_ancestry, diff_copy_from,
+                                show_copies_as_adds, use_git_diff_format,
+                                changelists, callbacks, callback_baton,
+                                ctx, pool));
         }
     }
   else /* path1 is a working copy path */
@@ -1951,9 +1956,10 @@
         {
           SVN_ERR(diff_repos_wc(path2, revision2, peg_revision,
                                 path1, revision1, TRUE, depth,
-                                ignore_ancestry, show_copies_as_adds,
-                                use_git_diff_format, changelists,
-                                callbacks, callback_baton, ctx, pool));
+                                ignore_ancestry, diff_copy_from,
+                                show_copies_as_adds, use_git_diff_format,
+                                changelists, callbacks, callback_baton,
+                                ctx, pool));
         }
       else /* path2 is a working copy path */
         {
@@ -2020,11 +2026,11 @@
            ctx->cancel_baton, &diff_editor, &diff_edit_baton, pool));
 
   /* We want to switch our txn into URL2 */
-  SVN_ERR(svn_ra_do_diff3
+  SVN_ERR(svn_ra_do_diff4
           (ra_session, &reporter, &reporter_baton, rev2, target1,
            depth, ignore_ancestry,
-           FALSE /* do not create text delta */, url2, diff_editor,
-           diff_edit_baton, pool));
+           FALSE /* do not create text delta */, FALSE /* diff_copy_from */,
+           url2, diff_editor, diff_edit_baton, pool));
 
   /* Drive the reporter; do the diff. */
   SVN_ERR(reporter->set_path(reporter_baton, "", rev1,
@@ -2177,6 +2183,7 @@
                  svn_depth_t depth,
                  svn_boolean_t ignore_ancestry,
                  svn_boolean_t no_diff_deleted,
+                 svn_boolean_t diff_copy_from,
                  svn_boolean_t show_copies_as_adds,
                  svn_boolean_t ignore_content_type,
                  svn_boolean_t use_git_diff_format,
@@ -2228,7 +2235,7 @@
 
   return do_diff(&diff_callbacks, &diff_cmd_baton, ctx,
                  path1, path2, revision1, revision2, &peg_revision,
-                 depth, ignore_ancestry, show_copies_as_adds,
+                 depth, ignore_ancestry, diff_copy_from, show_copies_as_adds,
                  use_git_diff_format, changelists, pool);
 }
 
@@ -2242,6 +2249,7 @@
                      svn_depth_t depth,
                      svn_boolean_t ignore_ancestry,
                      svn_boolean_t no_diff_deleted,
+                     svn_boolean_t diff_copy_from,
                      svn_boolean_t show_copies_as_adds,
                      svn_boolean_t ignore_content_type,
                      svn_boolean_t use_git_diff_format,
@@ -2289,7 +2297,7 @@
 
   return do_diff(&diff_callbacks, &diff_cmd_baton, ctx,
                  path, path, start_revision, end_revision, peg_revision,
-                 depth, ignore_ancestry, show_copies_as_adds,
+                 depth, ignore_ancestry, diff_copy_from, show_copies_as_adds,
                  use_git_diff_format, changelists, pool);
 }
 
Index: subversion/libsvn_ra_serf/update.c
===================================================================
--- subversion/libsvn_ra_serf/update.c	(revision 1037675)
+++ subversion/libsvn_ra_serf/update.c	(working copy)
@@ -2628,6 +2628,7 @@
                      svn_depth_t depth,
                      svn_boolean_t ignore_ancestry,
                      svn_boolean_t text_deltas,
+                     svn_boolean_t diff_copy_from,
                      const char *versus_url,
                      const svn_delta_editor_t *diff_editor,
                      void *diff_baton,
@@ -2638,7 +2639,8 @@
   return make_update_reporter(ra_session, reporter, report_baton,
                               revision,
                               session->repos_url.path, versus_url, diff_target,
-                              depth, ignore_ancestry, text_deltas, FALSE,
+                              depth, ignore_ancestry, text_deltas,
+                              diff_copy_from ? TRUE : FALSE,
                               diff_editor, diff_baton, pool);
 }
 
Index: subversion/libsvn_ra_serf/ra_serf.h
===================================================================
--- subversion/libsvn_ra_serf/ra_serf.h	(revision 1037675)
+++ subversion/libsvn_ra_serf/ra_serf.h	(working copy)
@@ -1245,6 +1245,7 @@
                      svn_depth_t depth,
                      svn_boolean_t ignore_ancestry,
                      svn_boolean_t text_deltas,
+                     svn_boolean_t diff_copy_from,
                      const char *versus_url,
                      const svn_delta_editor_t *diff_editor,
                      void *diff_baton,
Index: subversion/libsvn_ra_neon/ra_neon.h
===================================================================
--- subversion/libsvn_ra_neon/ra_neon.h	(revision 1037675)
+++ subversion/libsvn_ra_neon/ra_neon.h	(working copy)
@@ -349,6 +349,7 @@
                                    svn_depth_t depth,
                                    svn_boolean_t ignore_ancestry,
                                    svn_boolean_t text_deltas,
+                                   svn_boolean_t diff_copy_from,
                                    const char *versus_url,
                                    const svn_delta_editor_t *wc_diff,
                                    void *wc_diff_baton,
Index: subversion/libsvn_ra_neon/fetch.c
===================================================================
--- subversion/libsvn_ra_neon/fetch.c	(revision 1037675)
+++ subversion/libsvn_ra_neon/fetch.c	(working copy)
@@ -2809,6 +2809,7 @@
                                    svn_depth_t depth,
                                    svn_boolean_t ignore_ancestry,
                                    svn_boolean_t text_deltas,
+                                   svn_boolean_t diff_copy_from,
                                    const char *versus_url,
                                    const svn_delta_editor_t *wc_diff,
                                    void *wc_diff_baton,
@@ -2821,7 +2822,7 @@
                        diff_target,
                        versus_url,
                        depth,
-                       FALSE,
+                       diff_copy_from ? TRUE : FALSE,
                        ignore_ancestry,
                        FALSE,
                        wc_diff,

Reply via email to