The attached patch fixes an assertion failure when exporting from a working copy with the -r option when you have svn:externals that use the root-relative ^/ syntax, and updates the export_revision_with_root_relative_external test I recently wrote that checks for this situation.
I'm completely new to the Subversion codebase and would appreciate feedback on anything I should have done differently for this fix. I'm unsure if this is the correct fix for this problem, but it definitely makes the test pass and works properly for exporting in the situation where I originally found this problem. I've tested with "make check" and everything passes. Daniel Shahaf very graciously nudged me in the direction of writing this patch myself -- thanks for all your help Daniel! The patch contains the log message, which explains the change in a bit more detail. Doug
Add ability to specify revision when exporting from a working copy. Although svn_client_export5's documentation previously specified that the revision was only relevant when exporting from a repository URL, it is still a useful feature to be able to specify a revision when exporting from a working copy. This patch ensures that export_directory doesn't pass a working copy path to the from_url parameter of svn_client__export_externals. This resolves an assertion failure if a working copy path is supplied and there are relative externals. * subversion/include/svn_client.h (svn_client_export5): Update documentation to indicate that revision is no longer only used when exporting from a repository URL. * subversion/libsvn_client/export.c (export_directory): Ensure that from_path_or_url is converted to a URL prior to passing it to svn_client__export_externals. * subversion/tests/cmdline/export_tests.py (export_revision_with_root_relative_external): Remove XFail tag, and update the test to check for correct output and export results. Index: subversion/include/svn_client.h =================================================================== --- subversion/include/svn_client.h (revision 1802087) +++ subversion/include/svn_client.h (working copy) @@ -6251,8 +6251,7 @@ svn_client_revprop_list(apr_hash_t **props, * #svn_opt_revision_unspecified, then it defaults to #svn_opt_revision_head * for URLs or #svn_opt_revision_working for WC targets. * - * @a revision is the revision that should be exported, which is only used - * when exporting from a repository. + * @a revision is the revision that should be exported. * * @a peg_revision and @a revision must not be @c NULL. * Index: subversion/libsvn_client/export.c =================================================================== --- subversion/libsvn_client/export.c (revision 1802087) +++ subversion/libsvn_client/export.c (working copy) @@ -1352,10 +1352,13 @@ export_directory(const char *from_path_or_url, if (! ignore_externals && depth == svn_depth_infinity) { const char *to_abspath; + const char *from_url; + SVN_ERR(svn_client_url_from_path2(&from_url, from_path_or_url, + ctx, scratch_pool, scratch_pool)); SVN_ERR(svn_dirent_get_absolute(&to_abspath, to_path, scratch_pool)); SVN_ERR(svn_client__export_externals(eb->externals, - from_path_or_url, + from_url, to_abspath, eb->repos_root_url, depth, native_eol, ignore_keywords, Index: subversion/tests/cmdline/export_tests.py =================================================================== --- subversion/tests/cmdline/export_tests.py (revision 1802087) +++ subversion/tests/cmdline/export_tests.py (working copy) @@ -1070,7 +1070,6 @@ def export_file_externals2(sbox): expected_output, expected_disk) -@XFail() def export_revision_with_root_relative_external(sbox): "export a revision with root-relative external" sbox.build() @@ -1089,18 +1088,37 @@ def export_revision_with_root_relative_external(sb # Update the working copy to receive file external svntest.main.run_svn(None, 'up', wc_dir) + # Update the expected disk tree to include the external. + expected_disk = svntest.main.greek_state.copy() + expected_disk.add({ + 'A/C/exfile_alpha' : Item("This is the file 'alpha'.\n"), + }) + + # Update the expected output to include the external. + expected_output = svntest.main.greek_state.copy() + expected_output.add({ + 'A/C/exfile_alpha' : Item("This is the file 'alpha'.\r"), + }) + expected_output.desc[''] = Item() + expected_output.tweak(contents=None, status='A ') + # Export revision 2 from URL export_target = sbox.add_wc_path('export_url') - svntest.actions.run_and_verify_svn(None, [], - 'export', sbox.repo_url, export_target, - '-r', 2) + expected_output.wc_dir = export_target + svntest.actions.run_and_verify_export(sbox.repo_url, + export_target, + expected_output, + expected_disk, + '-r', 2) # Export revision 2 from WC - # Fails (canonicalize: Assertion `*src != '/'' failed) export_target = sbox.add_wc_path('export_wc') - svntest.actions.run_and_verify_svn(None, [], - 'export', sbox.wc_dir, export_target, - '-r', 2) + expected_output.wc_dir = export_target + svntest.actions.run_and_verify_export(sbox.wc_dir, + export_target, + expected_output, + expected_disk, + '-r', 2) ########################################################################