Hi,
Here's a fix that I'd like another set of eyes on. It passes 'make
check', of course. I'm not entirely sure that I'm doing the right
thing closing the directory batons while I'm doing the mkdir's. I'm
keeping just the last one, and the root baton open and closing the
intermediate batons.
Thanks,
-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 5780)
+++ subversion/libsvn_client/commit.c (working copy)
@@ -341,6 +341,7 @@
void *root_baton;
svn_node_kind_t kind;
apr_array_header_t *ignores;
+ 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 +352,42 @@
/* Import a file or a directory tree. */
SVN_ERR (svn_io_check_path (path, &kind, pool));
+ if (new_entry) {
+ apr_array_header_t *temp, *dirs;
+ const char **element;
+ const char *new_path = "";
+
+ temp = svn_path_decompose(new_entry, pool);
+ dirs = apr_array_make (pool, 1, sizeof(const char *));
+
+ /* 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(temp);
+ }
+
+ /* We can only pop paths off the array, and they won't come
+ * off in the order we want to create directories. Create
+ * another array that we can access in the desired order. */
+ while ((element = (const char **) apr_array_pop(temp))) {
+ *((const char **) apr_array_push(dirs)) = *element;
+ }
+
+ while ((element = (const char **) apr_array_pop(dirs))) {
+
+ if (new_dir_baton)
+ SVN_ERR (editor->close_directory (new_dir_baton, pool));
+
+ new_path = svn_path_join(new_path, *element, 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 +405,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 +449,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 +458,8 @@
}
/* Close up the show; it's time to go home. */
+ if (new_dir_baton)
+ SVN_ERR (editor->close_directory (new_dir_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 5780)
+++ 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 5780)
+++ 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 5780)
+++ 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—<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 Fri May 2 06:14:14 2003