Noorul Islam K M <noo...@collab.net> writes: > Julian Foad <julian.f...@wandisco.com> writes: > >> On Fri, 2011-02-18 at 15:54 +0530, Noorul Islam K M wrote: >> >>> Noorul Islam K M <noo...@collab.net> writes: >>> >>> > 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 >> >> Ah, a child of a directory - I see. I hadn't appreciated that if the >> specified target is a directory ('/tmp/iota' here) then it will try to >> export into a child of that directory. >> >> So now you have covered these cases: >> >> If specified target ('/tmp/iota' in the example above) is a ... >> nothing -> fine >> file -> if 'force' then overwrite else error >> symlink -> ??? >> special -> ??? >> dir -> if sub-target ('/tmp/iota/iota') is a ... >> nothing -> fine >> file -> if 'force' then overwrite else error >> symlink -> ??? >> special -> error >> dir -> error >> >> Is that right? >> >> - Julian >> >> > > I think it is this way > > If specified target ('/tmp/iota' in the example above) is a ... > nothing -> fine > file -> if 'force' then overwrite else error > symlink -> if 'force' then overwrite else error > special -> if 'force' then overwrite else error > dir -> if sub-target ('/tmp/iota/iota') is a ... > nothing -> fine > file -> if 'force' then overwrite else error > symlink -> if 'force' then overwrite else error > special -> if 'force' then overwrite else error > dir -> error cannot force > > Thanks and Regards > Noorul > >>> > 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. >>> > >>> >>> Sorry the above should read >>> >>> # Special file >>> 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/ >>> ../subversion/svn/export-cmd.c:123: (apr_err=160020) >>> ../subversion/libsvn_client/export.c:1188: (apr_err=160020) >>> ../subversion/libsvn_client/export.c:535: (apr_err=160020) >>> svn: E160020: Destination file '/tmp/iota/iota' exists, and will not be >>> overwritten unless forced >>> >>> noorul@noorul:/tmp/wc/testrepo$ ~/projects/subversion/builds/trunk/bin/svn >>> export iota /tmp/iota/ --force >>> A /tmp/iota/iota >>> Export complete. >>> >>> > For symlink it successfully overwrites. >>> > >>> >>> I meant symlink type files behave the same as files. I forgot to attach >>> the latest patch. Please find attached the latest one. >>> >>> > 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 >>> >>> plain text document attachment (3799.txt) >>> 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 || kind == svn_node_unknown) && ! 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));
Pinging to get some attention to this thread. Thanks and Regards Noorul