Author: rhuijben
Date: Mon Mar 10 12:01:09 2014
New Revision: 1575915

URL: http://svn.apache.org/r1575915
Log:
Following up on r1575525, extend test coverage of exporting externals with
some recursive external scenarios and simplify the original fix to avoid
double export of file externals in directory externals and to allow a direct
export of a specific file external, which was just skipped before.

* subversion/libsvn_client/export.c
  (export_info_baton): Remove unneeded boolean.
  (export_node): Check if we are exporting the file external itself, or the
    working copy containing the file external instead of just for file
    externals.

  (do_export): Rename back to...
  (svn_client_export5): ... this, as we don't need the boolean (which
    accidentally introduced double exports of the same file).

  (svn_client_export5): Remove wrapper.

* subversion/tests/cmdline/export_tests.py
  (export_file_externals2): New test.
  (test_list): Add test.

Modified:
    subversion/trunk/subversion/libsvn_client/export.c
    subversion/trunk/subversion/tests/cmdline/export_tests.py

Modified: subversion/trunk/subversion/libsvn_client/export.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/export.c?rev=1575915&r1=1575914&r2=1575915&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/export.c (original)
+++ subversion/trunk/subversion/libsvn_client/export.c Mon Mar 10 12:01:09 2014
@@ -172,7 +172,6 @@ struct export_info_baton
   void *notify_baton;
   const char *origin_abspath;
   svn_boolean_t exported;
-  svn_boolean_t exporting_external;
 };
 
 /* Export a file or directory. Implements svn_wc_status_func4_t */
@@ -269,7 +268,9 @@ export_node(void *baton,
                                                       scratch_pool));
     }
 
-  if (status->file_external && !eib->exporting_external)
+  /* Skip file externals if they are a descendant of the export,
+     BUT NOT if we are explictly exporting the file external. */
+  if (status->file_external && strcmp(eib->origin_abspath, local_abspath) != 0)
     return SVN_NO_ERROR;
 
   /* Produce overwrite errors for the export root */
@@ -1365,20 +1366,23 @@ export_directory(const char *from_path_o
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *
-do_export(svn_revnum_t *result_rev,
-          const char *from_path_or_url,
-          const char *to_path,
-          const svn_opt_revision_t *peg_revision,
-          const svn_opt_revision_t *revision,
-          svn_boolean_t overwrite,
-          svn_boolean_t ignore_externals,
-          svn_boolean_t ignore_keywords,
-          svn_depth_t depth,
-          const char *native_eol,
-          svn_boolean_t exporting_external,
-          svn_client_ctx_t *ctx,
-          apr_pool_t *pool)
+
+
+/*** Public Interfaces ***/
+
+svn_error_t *
+svn_client_export5(svn_revnum_t *result_rev,
+                   const char *from_path_or_url,
+                   const char *to_path,
+                   const svn_opt_revision_t *peg_revision,
+                   const svn_opt_revision_t *revision,
+                   svn_boolean_t overwrite,
+                   svn_boolean_t ignore_externals,
+                   svn_boolean_t ignore_keywords,
+                   svn_depth_t depth,
+                   const char *native_eol,
+                   svn_client_ctx_t *ctx,
+                   apr_pool_t *pool)
 {
   svn_revnum_t edit_revision = SVN_INVALID_REVNUM;
   svn_boolean_t from_is_url = svn_path_is_url(from_path_or_url);
@@ -1509,7 +1513,6 @@ do_export(svn_revnum_t *result_rev,
       eib.notify_baton = ctx->notify_baton2;
       eib.origin_abspath = from_path_or_url;
       eib.exported = FALSE;
-      eib.exporting_external = exporting_external;
 
       SVN_ERR(svn_wc_walk_status(ctx->wc_ctx, from_path_or_url, depth,
                                  TRUE /* get_all */,
@@ -1557,15 +1560,15 @@ do_export(svn_revnum_t *result_rev,
                             svn_dirent_dirname(target_abspath, iterpool),
                             iterpool));
 
-              SVN_ERR(do_export(NULL,
-                                svn_dirent_join(from_path_or_url,
-                                               relpath,
-                                               iterpool),
-                                target_abspath,
-                                peg_revision, revision,
-                                TRUE, ignore_externals,
-                                ignore_keywords, depth, native_eol,
-                                TRUE, ctx, iterpool));
+              SVN_ERR(svn_client_export5(NULL,
+                                         svn_dirent_join(from_path_or_url,
+                                                         relpath,
+                                                         iterpool),
+                                         target_abspath,
+                                         peg_revision, revision,
+                                         TRUE, ignore_externals,
+                                         ignore_keywords, depth, native_eol,
+                                         ctx, iterpool));
             }
 
           svn_pool_destroy(iterpool);
@@ -1588,24 +1591,3 @@ do_export(svn_revnum_t *result_rev,
   return SVN_NO_ERROR;
 }
 
-
-/*** Public Interfaces ***/
-svn_error_t *
-svn_client_export5(svn_revnum_t *result_rev,
-                   const char *from_path_or_url,
-                   const char *to_path,
-                   const svn_opt_revision_t *peg_revision,
-                   const svn_opt_revision_t *revision,
-                   svn_boolean_t overwrite,
-                   svn_boolean_t ignore_externals,
-                   svn_boolean_t ignore_keywords,
-                   svn_depth_t depth,
-                   const char *native_eol,
-                   svn_client_ctx_t *ctx,
-                   apr_pool_t *pool)
-{
-  return svn_error_trace(do_export(result_rev, from_path_or_url, to_path,
-                                   peg_revision, revision, overwrite,
-                                   ignore_externals, ignore_keywords,
-                                   depth, native_eol, FALSE, ctx, pool));
-}

Modified: subversion/trunk/subversion/tests/cmdline/export_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/export_tests.py?rev=1575915&r1=1575914&r2=1575915&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/export_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/export_tests.py Mon Mar 10 
12:01:09 2014
@@ -1017,6 +1017,61 @@ def export_file_external(sbox):
                                         expected_output,
                                         expected_disk)
 
+@Issue(4427)
+def export_file_externals2(sbox):
+  "exporting file externals"
+  
+  sbox.build()
+  sbox.simple_mkdir('DIR', 'DIR2')
+  
+  sbox.simple_propset('svn:externals', '^/iota file', 'DIR')
+  sbox.simple_propset('svn:externals', '^/DIR TheDir', 'DIR2')
+  sbox.simple_commit()
+  sbox.simple_update()
+  
+  tmp = sbox.add_wc_path('tmp')
+  os.mkdir(tmp)
+  
+  expected_output = svntest.wc.State(tmp, {
+    'file'          : Item(status='A '),
+  })
+  expected_disk = svntest.wc.State('', {
+    'file': Item(contents="This is the file 'iota'.\n")
+  })
+  # Fails in 1.8.8 and r1575909.
+  # Direct export of file external was just skipped
+  svntest.actions.run_and_verify_export(sbox.ospath('DIR/file'),
+                                        tmp,
+                                        expected_output,
+                                        expected_disk)
+  
+  expected_output = svntest.wc.State(tmp, {
+    'DIR/file'           : Item(status='A '),
+  })
+  expected_disk = svntest.wc.State('', {
+    'file': Item(contents="This is the file 'iota'.\n")
+  })
+  # Fails in 1.8.8 (doesn't export file), passes in r1575909
+  svntest.actions.run_and_verify_export(sbox.ospath('DIR'),
+                                        os.path.join(tmp, 'DIR'),
+                                        expected_output,
+                                        expected_disk)
+                                        
+  expected_output = svntest.wc.State(tmp, {
+    'DIR2/TheDir/file' : Item(status='A '),
+  })
+  expected_disk = svntest.wc.State('', {
+    'TheDir'      : Item(),
+    'TheDir/file' : Item(contents="This is the file 'iota'.\n")
+  })
+  # Fails in 1.8.8 (doesn't export anything),
+  # Fails in r1575909 (exports file twice; once as file; once as external)
+  svntest.actions.run_and_verify_export(sbox.ospath('DIR2'),
+                                        os.path.join(tmp, 'DIR2'),
+                                        expected_output,
+                                        expected_disk)
+
+
 ########################################################################
 # Run the tests
 
@@ -1052,6 +1107,7 @@ test_list = [ None,
               export_file_overwrite_with_force,
               export_custom_keywords,
               export_file_external,
+              export_file_externals2
              ]
 
 if __name__ == '__main__':


Reply via email to