Julian Foad <julian.f...@wandisco.com> writes: > On Thu, 2011-02-17 at 21:04 +0530, Noorul Islam K M wrote: > >> Julian Foad <julian.f...@wandisco.com> writes: >> >> > Noorul Islam K M wrote: >> > >> >> Julian Foad <julian.f...@wandisco.com> writes: >> >> > On Tue, 2011-02-15, Noorul Islam K M wrote: >> >> >> + if ((kind == svn_node_file) && ! force) >> >> > >> >> > What if the obstruction is not a file but something else (dir or >> >> > unknown)? >> >> >> >> Obstruction of directory is already taken care of. >> > >> > I'm asking about obstruction *by* a directory (or symlink or ...), in >> > otyher words when (kind == svn_node_dir) or (kind == svn_node_unknown). >> > >> >> Are you talking about this scenario? >> >> noorul@laptop:/tmp/wc/testrepo$ touch iota >> noorul@laptop:/tmp/wc/testrepo$ >> ~/projects/subversion/src/trunk/vpath/subversion/svn/svn add iota >> A iota >> noorul@laptop:/tmp/wc/testrepo$ mkdir /tmp/iota >> noorul@laptop:/tmp/wc/testrepo$ >> ~/projects/subversion/src/trunk/vpath/subversion/svn/svn export iota >> /tmp/iota >> A /tmp/iota/iota >> Export complete. >> noorul@laptop:/tmp/wc/testrepo$ > > Yes, this scenario and other scenarios similar to this where /tmp/iota > could instead be a directory with children (and maybe one of the > children is called 'iota'), or could be a symlink or a special file. >
I modified the patch so that if the target exists as a child directory then throw the following error message. svn: E160020: Destination /tmp/iota/iota exists. Cannot overwrite directory with non-directory With the latest patch I tested the following noorul@noorul:/tmp/wc$ ~/projects/subversion/builds/trunk/bin/svnadmin create /tmp/testrepo noorul@noorul:/tmp/wc$ ~/projects/subversion/builds/trunk/bin/svn co file:///tmp/testrepo Checked out revision 0. noorul@noorul:/tmp/wc$ cd testrepo noorul@noorul:/tmp/wc/testrepo$ touch iota noorul@noorul:/tmp/wc/testrepo$ ~/projects/subversion/builds/trunk/bin/svn add iota A iota noorul@noorul:/tmp/wc/testrepo$ ~/projects/subversion/builds/trunk/bin/svn ci -m "Adding file" Adding iota Transmitting file data . Committed revision 1. noorul@noorul:/tmp/wc/testrepo$ ~/projects/subversion/builds/trunk/bin/svn up Updating '.' ... At revision 1. noorul@noorul:/tmp/wc/testrepo$ ~/projects/subversion/builds/trunk/bin/svn export iota /tmp A /tmp/iota Export complete. # Child directory noorul@noorul:/tmp/wc/testrepo$ rm -r -f /tmp/iota noorul@noorul:/tmp/wc/testrepo$ mkdir -p /tmp/iota/iota noorul@noorul:/tmp/wc/testrepo$ ~/projects/subversion/builds/trunk/bin/svn export iota /tmp/iota ../subversion/svn/export-cmd.c:123: (apr_err=160020) ../subversion/libsvn_client/export.c:1188: (apr_err=160020) ../subversion/libsvn_client/export.c:542: (apr_err=160020) svn: E160020: Destination /tmp/iota/iota exists. Cannot overwrite directory with non-directory # Special file noorul@noorul:/tmp/wc/testrepo$ rm -r -f /tmp/iota/iota noorul@noorul:/tmp/wc/testrepo$ mknod /tmp/iota/iota p noorul@noorul:/tmp/wc/testrepo$ ~/projects/subversion/builds/trunk/bin/svn export iota /tmp/iota A /tmp/iota/iota Export complete. For symlink it successfully overwrites. Update log message is here Log [[[ Fix for issue #3799. Make svn export display error when exporting file tries to overwrite target. * subversion/libsvn_client/export.c (copy_versioned_files): Return SVN_ERR_FS_ALREADY_EXISTS if export tries to overwrite existing file, child directory. * subversion/tests/cmdline/export_tests.py (export_file_overwrite_fails): Remove XFail marker (export_file_overwrite_with_force): New test (test_list): Add reference to new test * subversion/tests/cmdline/externals_tests.py (export_wc_with_externals): Fix failing test by passing --force. Patch by: Noorul Islam K M <noorul{_AT_}collab.net> ]]] Thanks and Regards Noorul
Index: subversion/tests/cmdline/externals_tests.py =================================================================== --- subversion/tests/cmdline/externals_tests.py (revision 1071880) +++ subversion/tests/cmdline/externals_tests.py (working copy) @@ -752,7 +752,8 @@ repo_url, wc_dir) # Export the working copy. svntest.actions.run_and_verify_svn(None, None, [], - 'export', wc_dir, export_target) + 'export', '--force', + wc_dir, export_target) ### We should be able to check exactly the paths that externals_test_setup() ### set up; however, --ignore-externals fails to ignore 'A/B/gamma' so this Index: subversion/tests/cmdline/export_tests.py =================================================================== --- subversion/tests/cmdline/export_tests.py (revision 1071880) +++ subversion/tests/cmdline/export_tests.py (working copy) @@ -456,7 +456,6 @@ '.', expected_output, expected_disk) -@XFail() @Issue(3799) def export_file_overwrite_fails(sbox): "exporting a file refuses to silently overwrite" @@ -703,6 +702,29 @@ os.chdir(orig_dir) +def export_file_overwrite_with_force(sbox): + "exporting a file with force option" + sbox.build(create_wc = True, read_only = True) + + iota_path = os.path.abspath(os.path.join(sbox.wc_dir, 'iota')) + not_iota_contents = "This obstructs 'iota'.\n" + iota_contents = "This is the file 'iota'.\n" + + tmpdir = sbox.get_tempname('file-overwrites') + os.mkdir(tmpdir) + + expected_disk = svntest.wc.State('', { + 'iota': Item(contents=iota_contents), + }) + + # Run it + open(os.path.join(tmpdir, 'iota'), 'w').write(not_iota_contents) + svntest.actions.run_and_verify_svn(None, svntest.verify.AnyOutput, + [], 'export', '--force', + iota_path, tmpdir) + + svntest.actions.verify_disk(tmpdir, expected_disk) + ######################################################################## # Run the tests @@ -735,6 +757,7 @@ export_working_copy_with_depths, export_externals_with_native_eol, export_to_current_dir, + export_file_overwrite_with_force, ] if __name__ == '__main__': Index: subversion/libsvn_client/export.c =================================================================== --- subversion/libsvn_client/export.c (revision 1071880) +++ subversion/libsvn_client/export.c (working copy) @@ -524,7 +524,26 @@ } else if (from_kind == svn_node_file) { + svn_node_kind_t kind; + svn_error_t *err; + SVN_ERR(append_basename_if_dir(&to_abspath, from_abspath, FALSE, pool)); + svn_error_clear(svn_io_check_path(to_abspath, &kind, pool)); + + if ((kind == svn_node_file) && ! force) + { + return svn_error_createf(SVN_ERR_FS_ALREADY_EXISTS, NULL, + _("Destination file '%s' exists, " + "and will not be overwritten unless " + "forced"), + svn_dirent_local_style(to_abspath, pool)); + } + else if (kind == svn_node_dir) + return svn_error_createf(SVN_ERR_FS_ALREADY_EXISTS, NULL, + _("Destination %s exists. Cannot overwrite " + "directory with non-directory"), + svn_dirent_local_style(to_abspath, pool)); + SVN_ERR(copy_one_versioned_file(from_abspath, to_abspath, ctx->wc_ctx, revision, native_eol, ignore_keywords, pool));