[prev in list] [next in list] [prev in thread] [next in thread] 

List:       subversion-dev
Subject:    [PATCH] make diff against copy-source by default
From:       Prabhu Gnana Sundar <prabhugs () collab ! net>
Date:       2010-12-30 15:19:44
Message-ID: 1293721664.22966.42.camel () prabhugnanasundar
[Download RAW message or body]

Hi all,

This patch is a follow up to the patch that I gave last month
(November).
Here is the link to the mail archive...
http://mail-archives.apache.org/mod_mbox/subversion-dev/201011.mbox/%
3C1291110994.4021.66.camel@prabhugnanasundar%3E


After a few discussions about the inconsistent behaviour of 'svn diff'
in different scenarios, Kamesh suggested that let 'svn diff' be done
against the copy-source by default, making use of the copyfrom info.

Now this patch would do 'diff' against the copy-source by default,
whereas the prevailing default behaviour(of showing a *modified copy* as
all adds) can be achieved by using the '--show-copies-as-adds'
switch(that already exists in the code-base!).

I was quickly in to it and after spending some time in the process I
came to know that several existing 'test cases' *failed* due to the
change in the behaviour of the 'svn diff'. Later found that the 'wc
editor' needs to be taught to handle this behaviour (handling the
copyfrom info and retrieving it from the repository as against working
copy text-base).

This took quite some amount of time... 

See [1] below of the mailer.py usecase which tries to get the same
output as my patch do.

May be that's the behaviour of the 'diff' that is prefered ? :)

I have attached the patch and the log message with this mail. Please
review and respond.


[1]
I found the following usecase which is already doing the same as what my
patch intends to do.

The mailer.py script has the same behaviour of 'diff'ing just as this
patch does.
http://mail-archives.apache.org/mod_mbox/subversion-commits/201012.mbox/%3C20101228204459.1E42D238890A@eris.apache.org%3E


<snip from the above commit email>
Copied:
subversion/branches/1.6.x-svn_fs_commit_txn/subversion/include/private/svn_repos_private.h
 (from r1051763,
subversion/trunk/subversion/include/private/svn_repos_private.h)
URL:
http://svn.apache.org/viewvc/subversion/branches/1.6.x-svn_fs_commit_txn/subversion/in \
clude/private/svn_repos_private.h?p2=subversion/branches/1.6.x-svn_fs_commit_txn/subve \
rsion/include/private/svn_repos_private.h&p1=subversion/trunk/subversion/include/private/svn_repos_private.h&r1=1051763&r2=1053428&rev=1053428&view=diff
 ==============================================================================
--- subversion/trunk/subversion/include/private/svn_repos_private.h
(original)
+++
subversion/branches/1.6.x-svn_fs_commit_txn/subversion/include/private/svn_repos_private.h
 Tue Dec 28 20:44:58 2010
@@ -38,53 +38,6 @@ extern "C" {


/**
- * Permanently delete @a path at revision @a revision in @a fs.
- *
- * Do not change the content of any other node in the repository, even
other
- * nodes that were copied from this one. The only other change in the
- * repository is to "copied from" pointers that were pointing to the
- * now-deleted node. These are removed or made to point to a previous
- * version of the now-deleted node.
- * (### TODO: details.)
- *
- * @a path is relative to the repository root and must start with "/".
- *
- * If administratively forbidden, return @c SVN_ERR_RA_NOT_AUTHORIZED.
If not
- * implemented by the RA layer or by the server, return
- * @c SVN_ERR_RA_NOT_IMPLEMENTED.
- *
- * @note This functionality is not implemented in pre-1.7 servers and
may not
- * be implemented in all 1.7 and later servers.
- *
- * @note TODO: Maybe create svn_repos_fs_begin_obliteration_txn() and
- * svn_repos_fs_commit_obliteration_txn() to enable an obliteration txn
to be
- * constructed at a higher level.
- *
- * @since New in 1.7.
- */
-svn_error_t *
-svn_repos__obliterate_path_rev(svn_repos_t *repos,
- const char *username,
- svn_revnum_t revision,
- const char *path,
- apr_pool_t *pool);
-
-
-/** Validate that property @a name is valid for use in a Subversion
- * repository; return @c SVN_ERR_REPOS_BAD_ARGS if it isn't. For some
- * "svn:" properties, also validate the @a value, and return
- * @c SVN_ERR_BAD_PROPERTY_VALUE if it is not valid.
- * 
- * Use @a pool for temporary allocations.
- *
- * @since New in 1.7.
- */
-svn_error_t *
-svn_repos__validate_prop(const char *name,
- const svn_string_t *value,
- apr_pool_t *pool);
-
-/**
* Given the error @a err from svn_repos_fs_commit_txn(), return an
* string containing either or both of the svn_fs_commit_txn() error
* and the SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED wrapped error from
</snip>



Thanks and regards
Prabhu


["diff-aginst-copy-source-by-default.patch" (diff-aginst-copy-source-by-default.patch)]

Index: build.conf
===================================================================
--- build.conf	(revision 1053833)
+++ build.conf	(working copy)
@@ -336,7 +336,7 @@
 description = Subversion Working Copy Library
 type = lib
 path = subversion/libsvn_wc
-libs = libsvn_delta libsvn_diff libsvn_subr aprutil apriconv apr
+libs = libsvn_ra libsvn_delta libsvn_diff libsvn_subr aprutil apriconv apr
 install = lib
 msvc-export = svn_wc.h private\svn_wc_private.h
 
Index: subversion/libsvn_ra/deprecated.c
===================================================================
--- subversion/libsvn_ra/deprecated.c	(revision 1053833)
+++ subversion/libsvn_ra/deprecated.c	(working copy)
@@ -248,6 +248,30 @@
                                    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 svn_ra_do_diff4(session,
+                         reporter, report_baton,
+                         revision, diff_target,
+                         depth, ignore_ancestry,
+                         text_deltas, FALSE/* send copyfrom args */,
+                         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,
@@ -266,12 +290,13 @@
                  || svn_path_is_single_path_component(diff_target));
   *reporter = &reporter_3in2_wrapper;
   *report_baton = b;
-  return session->vtable->do_diff(session,
-                                  &(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);
+  return svn_ra_do_diff3(session,
+                         &(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);
 }
 
 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 1053833)
+++ 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 1053833)
+++ 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 send_copyfrom_args,
                              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, send_copyfrom_args,
+                                  versus_url, diff_editor,
                                   diff_baton, pool);
 }
 
Index: subversion/libsvn_ra/ra_loader.h
===================================================================
--- subversion/libsvn_ra/ra_loader.h	(revision 1053833)
+++ subversion/libsvn_ra/ra_loader.h	(working copy)
@@ -159,6 +159,7 @@
                           svn_depth_t depth,
                           svn_boolean_t ignore_ancestry,
                           svn_boolean_t text_deltas,
+                          svn_boolean_t send_copyfrom_args,
                           const char *versus_url,
                           const svn_delta_editor_t *diff_editor,
                           void *diff_baton,
Index: subversion/libsvn_ra_local/ra_plugin.c
===================================================================
--- subversion/libsvn_ra_local/ra_plugin.c	(revision 1053833)
+++ subversion/libsvn_ra_local/ra_plugin.c	(working copy)
@@ -822,6 +822,7 @@
                       svn_depth_t depth,
                       svn_boolean_t ignore_ancestry,
                       svn_boolean_t text_deltas,
+                      svn_boolean_t send_copyfrom_args,
                       const char *switch_url,
                       const svn_delta_editor_t *update_editor,
                       void *update_baton,
@@ -835,7 +836,7 @@
                        switch_url,
                        text_deltas,
                        depth,
-                       FALSE,
+                       send_copyfrom_args,
                        ignore_ancestry,
                        update_editor,
                        update_baton,
Index: subversion/tests/cmdline/diff_tests.py
===================================================================
--- subversion/tests/cmdline/diff_tests.py	(revision 1053833)
+++ subversion/tests/cmdline/diff_tests.py	(working copy)
@@ -3121,7 +3121,7 @@
   ]
 
   svntest.actions.run_and_verify_svn(None, diff_repos_wc, [],
-                                     'diff', '-r' , '2')
+                                     'diff', '-r' , '2', '--sca')
 
 #----------------------------------------------------------------------
 
@@ -3455,7 +3455,7 @@
   expected = svntest.verify.UnorderedOutput(expected_output)
 
   svntest.actions.run_and_verify_svn(None, expected, [], 'diff', 
-                                     '--git',
+                                     '--git', '--sca',
                                      '--old', repo_url + '@1', '--new',
                                      wc_dir)
 
@@ -3497,7 +3497,7 @@
   expected = svntest.verify.UnorderedOutput(expected_output)
 
   svntest.actions.run_and_verify_svn(None, expected, [], 'diff', 
-                                     '--git', 
+                                     '--git', '--sca', 
                                      '--old', repo_url + '@1', '--new',
                                      repo_url + '@2')
 
@@ -3750,6 +3750,92 @@
   svntest.actions.run_and_verify_svn(None, expected_output, [], 'diff',
                                      '-c2', '--git')
   os.chdir(was_cwd)
+
+#----------------------------------------------------------------------
+#
+# In this test we perform 4 checks for repos-repos diff and 
+# 2 checks for repos-wc diff. 
+# Initially the diff is done against the target url of the file path.
+# The next two diffs are done against the repo root url.
+# The fourth check is done to see that the default behaviour
+# is not broken.
+# The repos-wc checks are done in similar ways.
+
+def diff_against_copysource_by_default(sbox):
+  "do diff against the copyfrom source by default"
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  file_path1 = os.path.join(wc_dir, 'A', 'B', 'E', 'alpha')
+
+# Remove the 'alpha' file and commit it in the repository
+  svntest.main.run_svn(None, 'rm', file_path1)
+  svntest.main.run_svn(None, 'ci', '-m', 'file removed', '--quiet', file_path1)
+
+# copy 'alpha' from revision 1 and modify contents
+  copyfrom_path = sbox.repo_url+"/A/B/E/alpha@1"
+  full_path = sbox.repo_url+"/A/B/E/alpha"
+  svntest.main.run_svn(None, 'cp', copyfrom_path, file_path1)
+  svntest.main.file_append(file_path1,
+                           "new line added\n")
+  svntest.main.run_svn(None, 'ci', '-m', 'file copied content modified',
+          '--quiet', file_path1)
+
+  svntest.main.run_svn(None, 'up')
+
+  expected_output1 = [
+    "Index: alpha\n",
+    "===================================================================\n",
+    "--- alpha	(revision 1)\n",
+    "+++ alpha	(revision 3)\n",
+    "@@ -1 +1,2 @@\n",
+    " This is the file 'alpha'.\n",
+    "+new line added\n" ]
+
+  expected_output2 = [
+    "Index: A/B/E/alpha\n",
+    "===================================================================\n",
+    "--- A/B/E/alpha	(revision 1)\n",
+    "+++ A/B/E/alpha	(revision 3)\n",
+    "@@ -1 +1,2 @@\n",
+    " This is the file 'alpha'.\n",
+    "+new line added\n" ]
+
+  expected_output3 = [
+    "Index: A/B/E/alpha\n",
+    "===================================================================\n",
+    "--- A/B/E/alpha	(revision 0)\n",
+    "+++ A/B/E/alpha	(revision 3)\n",
+    "@@ -0,0 +1,2 @@\n",
+    "+This is the file 'alpha'.\n",
+    "+new line added\n" ]
+
+  expected_output4 = [
+    "Index: A/B/E/alpha\n",
+    "===================================================================\n",
+    "--- A/B/E/alpha	(revision 3)\n",
+    "+++ A/B/E/alpha	(revision 1)\n",
+    "@@ -1,2 +1 @@\n",
+    " This is the file 'alpha'.\n",
+    "-new line added\n" ]
+
+  svntest.actions.run_and_verify_svn(None, expected_output1, [],
+                                     'diff', '-r', '1:3', full_path)
+  svntest.actions.run_and_verify_svn(None, expected_output2, [],
+                                     'diff', '-c', '3', sbox.repo_url)
+  svntest.actions.run_and_verify_svn(None, expected_output2, [],
+                                     'diff', '-r', '1:3', sbox.repo_url)
+  svntest.actions.run_and_verify_svn(None, expected_output3, [],
+                                     'diff', '-c', '3', '--sca', sbox.repo_url)
+  os.chdir(sbox.wc_dir)
+  svntest.main.run_svn(None, 'up', '-r2')
+  svntest.actions.run_and_verify_svn(None, expected_output2, [],
+                                     'diff', '-r', 'BASE:3')
+  svntest.actions.run_and_verify_svn(None, expected_output4, [],
+                                     'diff', '-r', '3:BASE')
+  svntest.actions.run_and_verify_svn(None, expected_output3, [],
+                                     'diff', '-r', 'BASE:3', '--sca')
+
 ########################################################################
 #Run the tests
 
@@ -3814,6 +3900,7 @@
               diff_git_empty_files,
               diff_git_with_props, 
               diff_git_with_props_on_dir,
+              diff_against_copysource_by_default,
               ]
 
 if __name__ == '__main__':
Index: subversion/libsvn_ra_svn/client.c
===================================================================
--- subversion/libsvn_ra_svn/client.c	(revision 1053833)
+++ 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 send_copyfrom_args,
                                 const char *versus_url,
                                 const svn_delta_editor_t *diff_editor,
                                 void *diff_baton, apr_pool_t *pool)
@@ -1325,10 +1326,11 @@
   svn_boolean_t recurse = DEPTH_TO_RECURSE(depth);
 
   /* Tell the server we want to start a diff. */
-  SVN_ERR(svn_ra_svn_write_cmd(conn, pool, "diff", "(?r)cbbcbw", rev,
+  SVN_ERR(svn_ra_svn_write_cmd(conn, pool, "diff", "(?r)cbbcbwb", rev,
                                target, recurse, ignore_ancestry,
                                versus_url, text_deltas,
-                               svn_depth_to_word(depth)));
+                               svn_depth_to_word(depth),
+                               send_copyfrom_args));
   SVN_ERR(handle_auth_request(sess_baton, pool));
 
   /* Fetch a reporter for the caller to drive.  The reporter will drive
Index: subversion/libsvn_ra_svn/protocol
===================================================================
--- subversion/libsvn_ra_svn/protocol	(revision 1053833)
+++ subversion/libsvn_ra_svn/protocol	(working copy)
@@ -358,7 +358,7 @@
 
   diff
     params:   ( [ rev:number ] target:string recurse:bool ignore-ancestry:bool
-                url:string ? text-deltas:bool ? depth:word )
+                url:string ? text-deltas:bool ? depth:word ? send_copyfrom_args:bool)
     Client switches to report command set.
     Upon finish-report, server sends auth-request.
     After auth exchange completes, server switches to editor command set.
Index: subversion/include/svn_wc.h
===================================================================
--- subversion/include/svn_wc.h	(revision 1053833)
+++ subversion/include/svn_wc.h	(working copy)
@@ -5783,6 +5783,8 @@
  * repository. The editor is allocated in @a result_pool; temporary
  * calculations are performed in @a scratch_pool.
  *
+ * @a ra_session/@a is the session to the repository root url.
+ *
  * @a anchor_path/@a target represent the base of the hierarchy to be compared.
  *
  * @a callbacks/@a callback_baton is the callback table to use when two
@@ -5829,6 +5831,7 @@
 svn_error_t *
 svn_wc_get_diff_editor6(const svn_delta_editor_t **editor,
                         void **edit_baton,
+                        svn_ra_session_t *ra_session,
                         svn_wc_context_t *wc_ctx,
                         const char *anchor_path,
                         const char *target,
Index: subversion/include/svn_ra.h
===================================================================
--- subversion/include/svn_ra.h	(revision 1053833)
+++ 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 send_copyfrom_args to send the copyfrom info.
+ *
  * Use @a pool for memory allocation.
  *
  * @note The reporter provided by this function does NOT supply copy-
@@ -1345,9 +1347,33 @@
  * 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_diff4(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,
+                svn_boolean_t send_copyfrom_args,
+                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 send_copyfrom_args
+ * 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,
@@ -1361,6 +1387,7 @@
                 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
Index: subversion/libsvn_wc/deprecated.c
===================================================================
--- subversion/libsvn_wc/deprecated.c	(revision 1053833)
+++ subversion/libsvn_wc/deprecated.c	(working copy)
@@ -1780,23 +1780,24 @@
   b->db = db;
 
   SVN_ERR(svn_wc_get_diff_editor6(editor,
-                                   edit_baton,
-                                   wc_ctx,
-                                   svn_wc_adm_access_path(anchor),
-                                   target,
-                                   &diff_callbacks3_wrapper,
-                                   b,
-                                   depth,
-                                   ignore_ancestry,
-                                   FALSE,
-                                   FALSE,
-                                   use_text_base,
-                                   reverse_order,
-                                   changelists,
-                                   cancel_func,
-                                   cancel_baton,
-                                   pool,
-                                   pool));
+                                  edit_baton,
+                                  NULL, 
+                                  wc_ctx,
+                                  svn_wc_adm_access_path(anchor),
+                                  target,
+                                  &diff_callbacks3_wrapper,
+                                  b,
+                                  depth,
+                                  ignore_ancestry,
+                                  FALSE,
+                                  FALSE,
+                                  use_text_base,
+                                  reverse_order,
+                                  changelists,
+                                  cancel_func,
+                                  cancel_baton,
+                                  pool,
+                                  pool));
 
   /* Can't destroy wc_ctx. It is used by the diff editor */
 
Index: subversion/libsvn_wc/diff.c
===================================================================
--- subversion/libsvn_wc/diff.c	(revision 1053833)
+++ subversion/libsvn_wc/diff.c	(working copy)
@@ -52,6 +52,7 @@
 #include "svn_dirent_uri.h"
 #include "svn_path.h"
 #include "svn_hash.h"
+#include "svn_ra.h"
 
 #include "private/svn_wc_private.h"
 
@@ -197,6 +198,9 @@
 /* Overall crawler editor baton.
  */
 struct edit_baton {
+
+  svn_ra_session_t *ra_session;
+
   /* A wc db. */
   svn_wc__db_t *db;
 
@@ -314,6 +318,16 @@
     drop the result into a file at TEMP_FILE_PATH. */
   const char *temp_file_path;
 
+  /* The path and APR file handle to the temporary file that contains the
+     BASE version. */
+  apr_file_t *copyfrom_temp_file;
+  const char *copyfrom_temp_path;
+
+  apr_hash_t *pristine_props;
+
+  /* The revision from where the source file is to be copied */
+  svn_revnum_t copyfrom_revision;
+
   /* The list of incoming BASE->repos propchanges. */
   apr_array_header_t *propchanges;
 
@@ -345,6 +359,7 @@
  */
 static svn_error_t *
 make_edit_baton(struct edit_baton **edit_baton,
+                svn_ra_session_t *ra_session,
                 svn_wc__db_t *db,
                 const char *anchor_path,
                 const char *target,
@@ -368,6 +383,7 @@
     SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash, changelists, pool));
 
   eb = apr_pcalloc(pool, sizeof(*eb));
+  eb->ra_session = ra_session;
   eb->db = db;
   eb->anchor_path = anchor_path;
   SVN_ERR(svn_dirent_get_absolute(&eb->anchor_abspath, eb->anchor_path, pool));
@@ -478,6 +494,31 @@
   return fb;
 }
 
+/* Get revision REVISION of the file described by B from the repository.
+ * Set B->copyfrom_temp_path to the path of a new temporary file containing
+ * the file's text.  Set B->pristine_props to a new hash containing the
+ * file's properties.  Install a pool cleanup handler on B->pool to delete
+ * the file.
+ */
+static svn_error_t *
+get_file_from_ra(struct file_baton *b, const char *path,
+                 svn_revnum_t revision)
+{
+  svn_stream_t *fstream;
+
+  SVN_ERR(svn_stream_open_unique(&fstream, &(b->copyfrom_temp_path), NULL,
+                                 svn_io_file_del_on_pool_cleanup, b->pool,
+                                 b->pool));
+
+  SVN_ERR(svn_ra_get_file(b->eb->ra_session,
+                          path,
+                          revision,
+                          fstream, NULL,
+                          &(b->pristine_props),
+                          b->pool));
+  return svn_stream_close(fstream);
+}
+
 /* Get the empty file associated with the edit baton. This is cached so
  * that it can be reused, all empty files are the same.
  */
@@ -1436,17 +1477,28 @@
   struct file_baton *fb;
   const char *full_path;
 
-  /* ### TODO: support copyfrom? */
-
   full_path = svn_dirent_join(pb->eb->anchor_path, path, file_pool);
-  fb = make_file_baton(full_path, TRUE, pb, file_pool);
-  *file_baton = fb;
 
-  /* Add this filename to the parent directory's list of elements that
-     have been compared. */
-  apr_hash_set(pb->compared, apr_pstrdup(pb->pool, full_path),
-               APR_HASH_KEY_STRING, "");
+  if (SVN_IS_VALID_REVNUM(copyfrom_revision))
+    {
+      fb = make_file_baton(full_path, FALSE, pb, file_pool);
+      *file_baton = fb;
+      fb->copyfrom_revision = copyfrom_revision;
+      SVN_ERR(get_file_from_ra(fb, copyfrom_path+1, copyfrom_revision));
+      apr_hash_set(pb->compared, apr_pstrdup(pb->pool, copyfrom_path),
+                   APR_HASH_KEY_STRING, "");
+    }
 
+  else
+    {
+      fb = make_file_baton(full_path, TRUE, pb, file_pool);
+      *file_baton = fb;
+
+      /* Add this filename to the parent directory's list of elements that
+         have been compared. */
+      apr_hash_set(pb->compared, apr_pstrdup(pb->pool, full_path),
+                   APR_HASH_KEY_STRING, "");
+    }
   return SVN_NO_ERROR;
 }
 
@@ -1537,12 +1589,22 @@
   else
     {
       /* The current text-base is the starting point if replacing */
-      SVN_ERR(svn_wc__get_pristine_contents(&source, eb->db, fb->local_abspath,
-                                            fb->pool, fb->pool));
-      if (source == NULL)
-        source = svn_stream_empty(fb->pool);
+      if (fb->copyfrom_temp_path)
+        {
+          SVN_ERR(svn_io_file_open(&(fb->copyfrom_temp_file),
+                                   fb->copyfrom_temp_path,
+                                   APR_READ, APR_OS_DEFAULT, fb->pool));
+          source = svn_stream_from_aprfile2(fb->copyfrom_temp_file, TRUE,
+                                            fb->pool);
+        }
+      else
+        {
+          SVN_ERR(svn_wc__get_pristine_contents(&source, eb->db, fb->local_abspath,
+                                                fb->pool, fb->pool)); 
+          if (source == NULL)
+            source = svn_stream_empty(fb->pool);
+        }
     }
-
   /* This is the file that will contain the pristine repository version. It
      is created in the admin temporary area. This file continues to exists
      until after the diff callback is run, at which point it is deleted. */
@@ -1552,7 +1614,8 @@
                                  temp_dir, svn_io_file_del_on_pool_cleanup,
                                  fb->pool, fb->pool));
 
-  svn_txdelta_apply(source, temp_stream,
+  svn_txdelta_apply(source,
+                    temp_stream,
                     NULL,
                     fb->temp_file_path /* error_info */,
                     fb->pool,
@@ -1613,8 +1676,11 @@
   if (fb->added)
     base_props = apr_hash_make(pool);
   else
-    SVN_ERR(svn_wc__get_pristine_props(&base_props, eb->db,
-                                       fb->local_abspath, pool, pool));
+    if(fb->pristine_props)
+      base_props = fb->pristine_props;
+    else
+      SVN_ERR(svn_wc__get_pristine_props(&base_props, eb->db,
+                                         fb->local_abspath, pool, pool));
 
   repos_props = apply_propchanges(base_props, fb->propchanges);
 
@@ -1690,9 +1756,12 @@
   if (modified)
     {
       if (eb->use_text_base)
-        SVN_ERR(svn_wc__text_base_path_to_read(&localfile,
-                                               eb->db, fb->local_abspath,
-                                               fb->pool, pool));
+        if(fb->copyfrom_temp_path)
+          localfile = fb->copyfrom_temp_path;
+        else
+          SVN_ERR(svn_wc__text_base_path_to_read(&localfile,
+                                                 eb->db, fb->local_abspath,
+                                                 fb->pool, pool));
       else
         /* a detranslated version of the working file */
         SVN_ERR(svn_wc__internal_translated_file(
@@ -1737,10 +1806,14 @@
                                                           ? temp_file_path
                                                           : localfile,
                                            eb->reverse_order
-                                                          ? SVN_INVALID_REVNUM
+                                                          ? fb->copyfrom_revision
+                                                          ? fb->copyfrom_revision
+                                                          : SVN_INVALID_REVNUM
                                                           : eb->revnum,
                                            eb->reverse_order
                                                           ? eb->revnum
+                                                          : fb->copyfrom_revision
+                                                          ? fb->copyfrom_revision
                                                           : SVN_INVALID_REVNUM,
                                            eb->reverse_order
                                                           ? original_mimetype
@@ -1819,6 +1892,7 @@
 svn_error_t *
 svn_wc_get_diff_editor6(const svn_delta_editor_t **editor,
                         void **edit_baton,
+                        svn_ra_session_t *ra_session,
                         svn_wc_context_t *wc_ctx,
                         const char *anchor_path,
                         const char *target,
@@ -1842,7 +1916,7 @@
   const svn_delta_editor_t *inner_editor;
   const char *anchor_abspath;
 
-  SVN_ERR(make_edit_baton(&eb,
+  SVN_ERR(make_edit_baton(&eb, ra_session,
                           wc_ctx->db,
                           anchor_path, target,
                           callbacks, callback_baton,
@@ -1928,7 +2002,7 @@
   else
     svn_dirent_split(&anchor_path, &target, target_path, pool);
 
-  SVN_ERR(make_edit_baton(&eb,
+  SVN_ERR(make_edit_baton(&eb, NULL,
                           wc_ctx->db,
                           anchor_path,
                           target,
Index: subversion/libsvn_client/repos_diff.c
===================================================================
--- subversion/libsvn_client/repos_diff.c	(revision 1053833)
+++ subversion/libsvn_client/repos_diff.c	(working copy)
@@ -93,6 +93,9 @@
      FALSE otherwise. */
   svn_boolean_t walk_deleted_repos_dirs;
 
+  /* TRUE if the copied contents need to be shown as added. */
+  svn_boolean_t show_copies_as_adds;
+
   /* A callback used to see if the client wishes to cancel the running
      operation. */
   svn_cancel_func_t cancel_func;
@@ -175,10 +178,10 @@
   const char *wcpath;
 
   /* The path and APR file handle to the temporary file that contains the
-     first repository version.  Also, the pristine-property list of
-     this file. */
+     first repository version. */
   const char *path_start_revision;
   apr_file_t *file_start_revision;
+
   apr_hash_t *pristine_props;
 
   /* The path and APR file handle to the temporary file that contains the
@@ -198,6 +201,9 @@
   /* A cache of any property changes (svn_prop_t) received for this file. */
   apr_array_header_t *propchanges;
 
+  /* The copyfrom revision */
+  svn_revnum_t copyfrom_revision;
+
   /* The pool passed in by add_file or open_file.
      Also, the pool this file_baton is allocated in. */
   apr_pool_t *pool;
@@ -308,7 +314,8 @@
  * 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 +324,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 +515,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 +580,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 +798,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,9 +809,29 @@
       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->show_copies_as_adds
+     && SVN_IS_VALID_REVNUM(copyfrom_revision))
+    {
+      const char *preserved_url;
+      const char *repos_root;
+      b->copyfrom_revision = copyfrom_revision;
+      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 +856,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 +987,7 @@
       const char *mimetype1, *mimetype2;
       get_file_mime_types(&mimetype1, &mimetype2, b);
 
-      if (b->added)
+      if (b->added && eb->show_copies_as_adds)
         SVN_ERR(eb->diff_callbacks->file_added
                 (local_dir_abspath, &content_state, &prop_state, &b->tree_conflicted,
                  b->wcpath,
@@ -981,7 +1006,8 @@
                  &b->tree_conflicted, b->wcpath,
                  b->path_end_revision ? b->path_start_revision : NULL,
                  b->path_end_revision,
-                 b->edit_baton->revision,
+                 b->copyfrom_revision ? b->copyfrom_revision
+                                      : b->edit_baton->revision,
                  b->edit_baton->target_revision,
                  mimetype1, mimetype2,
                  b->propchanges, b->pristine_props,
@@ -1298,6 +1324,7 @@
                             svn_revnum_t revision,
                             svn_wc_notify_func2_t notify_func,
                             void *notify_baton,
+                            svn_boolean_t show_copies_as_adds,
                             svn_cancel_func_t cancel_func,
                             void *cancel_baton,
                             const svn_delta_editor_t **editor,
@@ -1324,6 +1351,7 @@
   eb->notify_func = notify_func;
   eb->notify_baton = notify_baton;
   eb->walk_deleted_repos_dirs = TRUE;
+  eb->show_copies_as_adds = show_copies_as_adds;
   eb->cancel_func = cancel_func;
   eb->cancel_baton = cancel_baton;
 
Index: subversion/libsvn_client/client.h
===================================================================
--- subversion/libsvn_client/client.h	(revision 1053833)
+++ 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 show_copies_as_adds,
                             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 1053833)
+++ subversion/libsvn_client/merge.c	(working copy)
@@ -5052,14 +5052,15 @@
                                       merge_b->dry_run,
                                       merge_b->ra_session2, revision1,
                                       notification_receiver, notify_b,
-                                      merge_b->ctx->cancel_func,
+                                      TRUE, 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 */
+                          FALSE, /* send_copyfrom_args */
                           url2, diff_editor, diff_edit_baton, pool));
 
   /* Drive the reporter. */
Index: subversion/libsvn_client/diff.c
===================================================================
--- subversion/libsvn_client/diff.c	(revision 1053833)
+++ subversion/libsvn_client/diff.c	(working copy)
@@ -1676,6 +1676,7 @@
                  const svn_opt_revision_t *peg_revision,
                  svn_depth_t depth,
                  svn_boolean_t ignore_ancestry,
+                 svn_boolean_t show_copies_as_adds,
                  apr_pool_t *pool)
 {
   svn_ra_session_t *extra_ra_session;
@@ -1728,13 +1729,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,
+           show_copies_as_adds, 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, show_copies_as_adds ? FALSE : TRUE,
            url2, diff_editor, diff_edit_baton, pool));
 
   /* Drive the reporter; do the diff. */
@@ -1776,6 +1777,7 @@
   const char *url1, *anchor, *anchor_url, *target;
   svn_revnum_t rev;
   svn_ra_session_t *ra_session;
+  svn_ra_session_t *extra_ra_session;
   const svn_ra_reporter3_t *reporter;
   void *reporter_baton;
   const svn_delta_editor_t *diff_editor;
@@ -1785,6 +1787,7 @@
   const char *abspath1;
   const char *abspath2;
   const char *anchor_abspath;
+  const char *repos_root;
 
   SVN_ERR_ASSERT(! svn_path_is_url(path2));
 
@@ -1843,12 +1846,24 @@
   SVN_ERR(svn_client__open_ra_session_internal(&ra_session, NULL, anchor_url,
                                                NULL, NULL, FALSE, TRUE,
                                                ctx, pool));
+  /* Establish RA session to path2's anchor */
+  SVN_ERR(svn_client__open_ra_session_internal(&extra_ra_session, NULL,
+                                               anchor_url,
+                                               NULL, NULL, FALSE, TRUE,
+                                               ctx, pool));
+  SVN_ERR(svn_ra_get_repos_root2(ra_session,
+                                 &repos_root,
+                                 pool));
+  SVN_ERR(svn_ra_reparent(extra_ra_session, repos_root,
+                          pool));
+
   callback_baton->ra_session = ra_session;
   if (use_git_diff_format)
     callback_baton->wc_root_abspath = find_wc_root(anchor_abspath, ctx->wc_ctx,
                                                    pool, pool);
 
   SVN_ERR(svn_wc_get_diff_editor6(&diff_editor, &diff_edit_baton,
+                                  extra_ra_session, 
                                   ctx->wc_ctx,
                                   anchor,
                                   target,
@@ -1873,13 +1888,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 */
+                          show_copies_as_adds ? FALSE : TRUE,
                           url1,
                           diff_editor, diff_edit_baton, pool));
 
@@ -1929,7 +1945,7 @@
           SVN_ERR(diff_repos_repos(callbacks, callback_baton, ctx,
                                    path1, path2, revision1, revision2,
                                    peg_revision, depth, ignore_ancestry,
-                                   pool));
+                                   show_copies_as_adds, pool));
         }
       else /* path2 is a working copy path */
         {
@@ -2015,10 +2031,12 @@
            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,
+           FALSE /* do not create text delta */,
+           FALSE /* send_copyfrom_args */,
+           url2, diff_editor,
            diff_edit_baton, pool));
 
   /* Drive the reporter; do the diff. */
Index: subversion/libsvn_ra_neon/ra_neon.h
===================================================================
--- subversion/libsvn_ra_neon/ra_neon.h	(revision 1053833)
+++ 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 send_copyfrom_args,
                                    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 1053833)
+++ 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 send_copyfrom_args,
                                    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,
+                       send_copyfrom_args,
                        ignore_ancestry,
                        FALSE,
                        wc_diff,
Index: subversion/libsvn_ra_serf/update.c
===================================================================
--- subversion/libsvn_ra_serf/update.c	(revision 1053833)
+++ subversion/libsvn_ra_serf/update.c	(working copy)
@@ -2631,6 +2631,7 @@
                      svn_depth_t depth,
                      svn_boolean_t ignore_ancestry,
                      svn_boolean_t text_deltas,
+                     svn_boolean_t send_copyfrom_args,
                      const char *versus_url,
                      const svn_delta_editor_t *diff_editor,
                      void *diff_baton,
@@ -2641,7 +2642,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,
+                              send_copyfrom_args,
                               diff_editor, diff_baton, pool);
 }
 
Index: subversion/libsvn_ra_serf/ra_serf.h
===================================================================
--- subversion/libsvn_ra_serf/ra_serf.h	(revision 1053833)
+++ subversion/libsvn_ra_serf/ra_serf.h	(working copy)
@@ -1247,6 +1247,7 @@
                      svn_depth_t depth,
                      svn_boolean_t ignore_ancestry,
                      svn_boolean_t text_deltas,
+                     svn_boolean_t send_copyfrom_args,
                      const char *versus_url,
                      const svn_delta_editor_t *diff_editor,
                      void *diff_baton,
Index: subversion/svnserve/serve.c
===================================================================
--- subversion/svnserve/serve.c	(revision 1053833)
+++ subversion/svnserve/serve.c	(working copy)
@@ -1774,6 +1774,8 @@
   /* Default to unknown.  Old clients won't send depth, but we'll
      handle that by converting recurse if necessary. */
   svn_depth_t depth = svn_depth_unknown;
+/* Default to false.  Pre-1.7 clients won't send send_copyfrom_args. */
+   svn_boolean_t send_copyfrom_args = FALSE;
 
   /* Parse the arguments. */
   if (params->nelts == 5)
@@ -1786,10 +1788,11 @@
     }
   else
     {
-      SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "(?r)cbbcb?w",
+      SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "(?r)cbbcb?w?b",
                                      &rev, &target, &recurse,
                                      &ignore_ancestry, &versus_url,
-                                     &text_deltas, &depth_word));
+                                     &text_deltas, &depth_word,
+                                     &send_copyfrom_args));
     }
   target = svn_uri_canonicalize(target, pool);
   versus_url = svn_uri_canonicalize(versus_url, pool);
@@ -1812,7 +1815,8 @@
     svn_revnum_t from_rev;
     SVN_ERR(accept_report(NULL, &from_rev,
                           conn, pool, b, rev, target, versus_path,
-                          text_deltas, depth, FALSE, ignore_ancestry));
+                          text_deltas, depth, send_copyfrom_args,
+                          ignore_ancestry));
     SVN_ERR(log_command(b, conn, pool, "%s",
                         svn_log__diff(full_path, from_rev, versus_path,
                                       rev, depth, ignore_ancestry,

["diff-against-copy-source-by-default.log" (diff-against-copy-source-by-default.log)]

[[[
Make svn diff to send the copyfrom info by default. Can use the "--show-copies-as-adds"
option to retain the copied contents as added (as it existed so far).

* build.conf
  (): Included 'libsvn_ra' to the libsvn_wc

* subversion/libsvn_ra/deprecated.c
  (): deprecated svn_ra_do_diff3
  (svn_ra_do_diff2): made it to call the svn_ra_do_diff3.

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

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

* subversion/libsvn_ra/ra_loader.h
  svn_ra__vtable_t: introduced 'send_copyfrom_args' argument in do_diff.

* subversion/libsvn_ra_local/ra_plugin.c
  (svn_ra_local__do_diff): introduced 'send_copyfrom_args' argument.

* subversion/libsvn_ra_svn/client.c
  (ra_svn_diff): introduced 'send_copyfrom_args' option and pass it to
                 svn_ra_svn_write_cmd function.

* subversion/include/svn_wc.h
  (svn_wc_get_diff_editor6): introduced the ra_session.

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

* subversion/libsvn_wc/deprecated.c
  (svn_wc_get_diff_editor5): introduced ra_session to svn_wc_get_diff_editor6
                             and corrected the indentation.

* subversion/libsvn_wc/diff.c
  (): included the svn_ra.h header file.
  (): persisted the ra_session, copyfrom file, copyfrom path and pristine properties
      in the edit_baton.
  (make_edit_baton) : introduced the ra_session.
  (get_file_from_ra): newly added to fetch file from repository.
  (add_file)        : support copyfrom by making use of the copyfrom info.
  (apply_textdelta) : makes use of the copyfrom_temp file making use of the
                      copyfrom info.
  (close_file)      : makes use of the copyfrom info and tweaked the file_changed to
                      display the copyfrom revision number.
  (svn_wc_get_diff_editor6) : introduced the ra_session.
                              pass NULL for ra_session to make_edit_baton.

* subversion/libsvn_client/repos_diff.c
  edit_baton: store the value of send_copyfrom_args.
  (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 copyfrom_revision is 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 'send_copyfrom_args' argument and
                                 assigned it in the edit baton.

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

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

* subversion/libsvn_client/diff.c
  (diff_repos_repos): if send_copyfrom_args is set, show the copied contents as
                      added.
  (diff_repos_wc): if send_copyfrom_args is set, show the copied contents as
                   added. Created a new ra_session to get file from ra.
  (do_diff): perform diff with respect to the send_copyfrom_args argument.
  (diff_summarize_repos_repos): pass false for 'send_copyfrom_args' to 
                                svn_ra_do_diff4 function.

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

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

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

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

* subversion/svnserve/serve.c
  (diff): introduced the 'send_copyfrom_args' argument and pass it to accept_reporter.

* subversion/libsvn_ra_svn/protocol
  (): updated diff to accept show-copies-as-adds as boolean.

* subversion/tests/cmdline/diff_tests.py
  (): added a new test diff_against_copysource_by_default.


Patch by: Prabhu Gnana Sundar <prabhugs{_AT_}collab.net>
Reviewed by: Kamesh Jayachandran <kamesh{_AT_}collab.net>
]]]


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic