Hi, In my previous patch [1] I suggested the addition of the '--diff-copy-from' switch to 'svn diff' to solve the cases where 'svn diff' would do the diff against the copyfrom source file when a file is reinstated or diff target is *not* explicit file.
But since there is already a point that diff behaves differently in different scenarios, making 'svn diff' work the same in all scenarios is one good option. This patch would solve the problem of making 'svn diff' work the same in all conditions by passing 'TRUE' for the 'diff_copy_from' option by default. Hence I removed the '--diff-copy-from' switch in this patch. This is a more generic way to bridge the gap. I am attaching the patch and the log with this mail. Please review and comment on the same. I still retain this param on svn_client_diff5 and svn_ra_diff4 in case somebody wants old behaviour, otherwise I can remove that too. Regards Prabhu [1]http://mail-archives.apache.org/mod_mbox/subversion-dev/201011.mbox/% 3c1291018400.4021.3.ca...@prabhugnanasundar%3e
Index: subversion/libsvn_ra/deprecated.c =================================================================== --- subversion/libsvn_ra/deprecated.c (revision 1040016) +++ 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 1040016) +++ 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 1040016) +++ 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 1040016) +++ 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 1040016) +++ 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 1040016) +++ 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) @@ -1325,10 +1326,10 @@ 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), diff_copy_from)); SVN_ERR(handle_auth_request(sess_baton, pool)); /* Fetch a reporter for the caller to drive. The reporter will drive Index: subversion/svn/cl.h =================================================================== --- subversion/svn/cl.h (revision 1040016) +++ 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 1040016) +++ subversion/svn/diff-cmd.c (working copy) @@ -347,6 +347,7 @@ opt_state->depth, ! opt_state->notice_ancestry, opt_state->no_diff_deleted, + TRUE /* 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, + TRUE /* 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 1040016) +++ 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/include/svn_client.h =================================================================== --- subversion/include/svn_client.h (revision 1040016) +++ subversion/include/svn_client.h (working copy) @@ -2631,8 +2631,11 @@ * and the addition of another, but if this flag is TRUE, unrelated * items will be diffed as if they were related. * - * If @a no_diff_deleted is TRUE, then no diff output will be - * generated on deleted files. + * If @a diff_copy_from is TRUE, diff copied files against the copyfrom + * source, instead of diffing against the history of the file's path. + * + * 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, diff copied files against the copyfrom + * source, instead of diffing against the history of the file's path. + * * 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 1040016) +++ 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 1040016) +++ 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 1040016) +++ 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; @@ -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,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 +325,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 +516,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 +581,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 +799,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 +810,28 @@ 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; + 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 +857,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 +988,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, @@ -981,7 +1007,7 @@ &b->tree_conflicted, b->wcpath, b->path_end_revision ? b->path_start_revision : NULL, b->path_end_revision, - b->edit_baton->revision, + eb->diff_copy_from ? b->copyfrom_revision : b->edit_baton->revision, b->edit_baton->target_revision, mimetype1, mimetype2, b->propchanges, b->pristine_props, @@ -1297,6 +1323,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 +1350,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 1040016) +++ 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 1040016) +++ 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 1040016) +++ 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_neon/ra_neon.h =================================================================== --- subversion/libsvn_ra_neon/ra_neon.h (revision 1040016) +++ 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 1040016) +++ 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, Index: subversion/libsvn_ra_serf/update.c =================================================================== --- subversion/libsvn_ra_serf/update.c (revision 1040016) +++ 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 1040016) +++ 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/svnserve/serve.c =================================================================== --- subversion/svnserve/serve.c (revision 1040016) +++ 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 diff-copy-from. */ + svn_boolean_t diff_copy_from = 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, + &diff_copy_from)); } 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, diff_copy_from, + ignore_ancestry)); SVN_ERR(log_command(b, conn, pool, "%s", svn_log__diff(full_path, from_rev, versus_path, rev, depth, ignore_ancestry,
[[[ 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/libsvn_ra_svn/client.c (ra_svn_diff): introduced 'diff_copy_from' option and pass it to svn_ra_svn_write_cmd function. * subversion/svn/cl.h svn_cl__opt_state_t: introduced 'diff_copy_from' option. * subversion/svn/diff-cmd.c (svn_cl__diff): passed 'TRUE' for the '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/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. * subversion/svnserve/serve.c (diff): introduced the 'diff_copy_from' argument and pass it to accept_reporter. Patch by: Prabhu Gnana Sundar <prabh...@collab.net> Suggested by: Kamesh Jayachandran <kam...@collab.net> ]]]