[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: [rfc/patch] Fix issue 734, import should 'mkdir -p'

From: David Kimdon <dwhedon_at_debian.org>
Date: 2003-05-03 17:50:19 CEST

On Fri, May 02, 2003 at 07:47:09AM -0500, cmpilato@collab.net wrote:
> Unfortunately, that's not quite right. The rules of editor driving
> require that you keep all the intermediate directories open, closing

k, thanks for the tip, here is an update. Do we like it?

-David

Fix issue #735: Create directories on import.

   * subversion/libsvn_client/commit.c (import) : Call mkdir on
     components of 'new_entry' prior to performing the actual import.

   * subversion/tests/clients/cmdline/basic_tests.py (basic_import) : Change
     existing test case to use a path to the third argument to import and
     verify that the new directories are created properly.

   * doc/book/book/ch03.xml : Change text and import example to show how
     subversion can create subdirectories on import.

   * doc/book/book/ch08.xml : Remove warning that the leading elements of
     the third argument to import must exist. Subversion will now create
     these directories.

Index: subversion/libsvn_client/commit.c
===================================================================
--- subversion/libsvn_client/commit.c (revision 5790)
+++ subversion/libsvn_client/commit.c (working copy)
@@ -341,6 +341,8 @@
   void *root_baton;
   svn_node_kind_t kind;
   apr_array_header_t *ignores;
+ apr_array_header_t *batons = NULL;
+ void *new_dir_baton = NULL;
 
   /* Get a root dir baton. We pass an invalid revnum to open_root
      to mean "base this on the youngest revision". Should we have an
@@ -351,6 +353,40 @@
   /* Import a file or a directory tree. */
   SVN_ERR (svn_io_check_path (path, &kind, pool));
 
+ if (new_entry) {
+ apr_array_header_t *dirs;
+ const char *new_path = "";
+ int i;
+
+ dirs = svn_path_decompose (new_entry, pool);
+
+ /* If we are importing a file then NEW_ENTRY's basename is
+ * the desired filename in the repository. (We don't create
+ * a directory with that name.) Discard the component. */
+ if (kind == svn_node_file) {
+ apr_array_pop (dirs);
+ }
+
+ for (i = 0; i < dirs->nelts; i++) {
+
+ if (new_dir_baton) {
+
+ if (!batons) {
+ batons = apr_array_make (pool, 1, sizeof (void *));
+ }
+
+ *((void **) apr_array_push (batons)) = new_dir_baton;
+
+ }
+ new_path = svn_path_join (new_path, ((char **)dirs->elts)[i],
+ pool);
+
+ SVN_ERR (editor->add_directory (new_path, root_baton,
+ NULL, SVN_INVALID_REVNUM,
+ pool, &new_dir_baton));
+ }
+ }
+
   /* Note that there is no need to check whether PATH's basename is
      the same name that we reserve for our admistritave
      subdirectories. It would be strange, but not illegal to import
@@ -368,20 +404,13 @@
                 (SVN_ERR_NODE_UNKNOWN_KIND, NULL,
                  "new entry name required when importing a file");
 
- SVN_ERR (import_file (editor, root_baton,
+ SVN_ERR (import_file (editor,
+ new_dir_baton ? new_dir_baton : root_baton,
                                 path, new_entry, ctx, pool));
         }
     }
   else if (kind == svn_node_dir)
     {
- void *new_dir_baton = NULL;
-
- /* Grab a new baton, making two we'll have to close. */
- if (new_entry)
- SVN_ERR (editor->add_directory (new_entry, root_baton,
- NULL, SVN_INVALID_REVNUM,
- pool, &new_dir_baton));
-
 #if 0 /* Temporarily blocked out for consideration, see below. */
       /* If we activate this notification, then
        *
@@ -419,9 +448,6 @@
                            path, new_entry ? new_entry : "",
                            nonrecursive, excludes, ctx, pool));
 
- /* Close one baton or two. */
- if (new_dir_baton)
- SVN_ERR (editor->close_directory (new_dir_baton, pool));
     }
   else if (kind == svn_node_none)
     {
@@ -431,6 +457,17 @@
     }
 
   /* Close up the show; it's time to go home. */
+ if (new_dir_baton)
+ SVN_ERR (editor->close_directory (new_dir_baton, pool));
+
+ {
+ void **baton;
+
+ while ((baton = (void **) apr_array_pop (batons))) {
+ SVN_ERR (editor->close_directory (*baton, pool));
+ }
+ }
+
   SVN_ERR (editor->close_directory (root_baton, pool));
   SVN_ERR (editor->close_edit (edit_baton, pool));
 
Index: subversion/tests/clients/cmdline/basic_tests.py
===================================================================
--- subversion/tests/clients/cmdline/basic_tests.py (revision 5790)
+++ subversion/tests/clients/cmdline/basic_tests.py (working copy)
@@ -1148,7 +1148,7 @@
     'Cannot change node kind', None, [], 'import',
     '--username', svntest.main.wc_author,
     '--password', svntest.main.wc_passwd,
- '-m', 'Log message for new import', url, new_path, 'new_file')
+ '-m', 'Log message for new import', url, new_path, 'dir1/dir2/new_file')
 
   lastline = string.strip(output.pop())
   cm = re.compile ("(Committed|Imported) revision [0-9]+.")
@@ -1163,19 +1163,23 @@
   # Create expected disk tree for the update (disregarding props)
   expected_disk = svntest.main.greek_state.copy()
   expected_disk.add({
- 'new_file' : Item('some text'),
+ os.path.join('dir1', 'dir2', 'new_file') : Item('some text'),
     })
 
   # Create expected status tree for the update (disregarding props).
   # Newly imported file should be at revision 2.
   expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
   expected_status.add({
- 'new_file' : Item(status=' ', wc_rev=2, repos_rev=2),
+ 'dir1' : Item(status=' ', wc_rev=2, repos_rev=2),
+ 'dir1/dir2' : Item(status=' ', wc_rev=2, repos_rev=2),
+ 'dir1/dir2/new_file' : Item(status=' ', wc_rev=2, repos_rev=2),
     })
 
   # Create expected output tree for the update.
   expected_output = svntest.wc.State(wc_dir, {
- 'new_file' : Item(status='A '),
+ 'dir1' : Item(status='A '),
+ 'dir1/dir2' : Item(status='A '),
+ 'dir1/dir2/new_file' : Item(status='A '),
   })
 
   # do update and check three ways
Index: doc/book/book/ch03.xml
===================================================================
--- doc/book/book/ch03.xml (revision 5790)
+++ doc/book/book/ch03.xml (working copy)
@@ -1996,11 +1996,11 @@
 
       <para>If you give <command>svn import</command> a third
         argument, it will use the argument as the name of a new
- subdirectory to create within the URL.</para>
+ path to create within the URL.</para>
 
       <screen>
 $ svnadmin create /usr/local/svn/newrepos
-$ svn import file:///usr/local/svn/newrepos mytree fooproject
+$ svn import file:///usr/local/svn/newrepos mytree fooproject/trunk
 Adding mytree/foo.c
 Adding mytree/bar.c
 Adding mytree/subdir
@@ -2012,10 +2012,10 @@
       <para>The repository would now look like this:</para>
 
       <screen>
-/fooproject/foo.c
-/fooproject/bar.c
-/fooproject/subdir
-/fooproject/subdir/quux.h
+/fooproject/trunk/foo.c
+/fooproject/trunk/bar.c
+/fooproject/trunk/subdir
+/fooproject/trunk/subdir/quux.h
       </screen>
 
     </sect2>
Index: doc/book/book/ch08.xml
===================================================================
--- doc/book/book/ch08.xml (revision 5790)
+++ doc/book/book/ch08.xml (working copy)
@@ -1366,10 +1366,7 @@
             </screen>
 
             <para>This imports the local directory 'myproj' into
- 'trunk/vendors' in your repository. The directory
- 'trunk/vendors' must exist before you import into
- it&mdash;<command>svn import</command> will not
- recursively create directories for you:</para>
+ 'trunk/vendors' in your repository:</para>
 
             <screen>
 $ svn import -m "New import" http://svn.red-bean.com/repos/test myproj trunk/vendors/myproj

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Sat May 3 17:52:50 2003

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.