Julian Foad <julian.f...@wandisco.com> writes:

> On Tue, 2011-02-15, Noorul Islam K M wrote:
>
>> More details about the issue can be found
>> here. http://subversion.tigris.org/issues/show_bug.cgi?id=3799
>> 
>> Using trunk when exporting a file, if the file already exists at target
>> location then operation overwrites the file without giving any
>> warning. But in the case of directory it throws an error saying
>> 
>> "Destination directory exists, and will not be overwritten unless
>> forced"
>> 
>> This patch makes export throw an error in the case of file
>> overwriting and ask to use --force option.
>> 
>> Log
>> [[[
>> 
>> Make svn export display error when exporting file tries to overwrite
>> target.
>
> Please include the issue number in the log message.
>

Please see the modified log.

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.

* 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>
]]]

>> * subversion/svn/export-cmd.c
>>   (svn_cl__export): Generalise error message to include file.
>> 
>> * subversion/libsvn_client/export.c
>>   (copy_versioned_files): Return SVN_ERR_WC_OBSTRUCTED_UPDATE if export
>>     tries to overwrite existing file.
>> 
>> * 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/export_tests.py
>> ===================================================================
>> --- subversion/tests/cmdline/export_tests.py (revision 1070515)
>> +++ 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)
>
> Should we test a non-file obstruction (a directory and/or a symlink?) as
> well?
>

I will submit a follow-up patch.

>> +  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/svn/export-cmd.c
>> ===================================================================
>> --- subversion/svn/export-cmd.c      (revision 1070515)
>> +++ subversion/svn/export-cmd.c      (working copy)
>> @@ -112,8 +112,8 @@
>>                             opt_state->native_eol, ctx, pool);
>>    if (err && err->apr_err == SVN_ERR_WC_OBSTRUCTED_UPDATE && 
>> !opt_state->force)
>>      SVN_ERR_W(err,
>> -              _("Destination directory exists; please remove "
>> -                "the directory or use --force to overwrite"));
>> +              _("Destination directory/file already exists; please remove "
>> +                "it or use --force to overwrite"));
>>  
>>    if (nwb.had_externals_error)
>>      return svn_error_create(SVN_ERR_CL_ERROR_PROCESSING_EXTERNALS, NULL,
>> Index: subversion/libsvn_client/export.c
>> ===================================================================
>> --- subversion/libsvn_client/export.c        (revision 1070515)
>> +++ subversion/libsvn_client/export.c        (working copy)
>> @@ -524,7 +524,16 @@
>>      }
>>    else if (from_kind == svn_node_file)
>>      {
>> +      svn_node_kind_t kind;
>> +
>>        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)
>
> What if the obstruction is not a file but something else (dir or
> unknown)?
>

Obstruction of directory is already taken care of.

>> +        return svn_error_createf(SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
>> +                                 _("'%s' already exists"),
>> +                                 svn_dirent_local_style(to_abspath, pool));
>
> Why not make the wording of this error message similar to the one that
> is given when exporting a directory hits an obstruction?
>
>     SVN_ERR_W(err, _("Destination directory exists, and will not be "
>                      "overwritten unless forced"));
>  
> (Including the path in the error message is good; I think we should
> tweak the directory-hits-an-obstruction error message to do so as well.)
>

Incorporated for file. For directory I will come up another patch.

Please find attached modified patch.

Thanks and Regards
Noorul

Index: subversion/tests/cmdline/externals_tests.py
===================================================================
--- subversion/tests/cmdline/externals_tests.py (revision 1071585)
+++ 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 1071585)
+++ 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 1071585)
+++ subversion/libsvn_client/export.c   (working copy)
@@ -524,7 +524,21 @@
     }
   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));
+        }
+
       SVN_ERR(copy_one_versioned_file(from_abspath, to_abspath, ctx->wc_ctx,
                                       revision, native_eol, ignore_keywords,
                                       pool));

Reply via email to