You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by da...@apache.org on 2010/11/23 04:52:56 UTC
svn commit: r1037989 - in /subversion/trunk/subversion: include/svn_client.h
libsvn_client/export.c tests/cmdline/export_tests.py
Author: danielsh
Date: Tue Nov 23 03:52:56 2010
New Revision: 1037989
URL: http://svn.apache.org/viewvc?rev=1037989&view=rev
Log:
Fix 'svn export' of a file source with a directory target.
* subversion/include/svn_client.h
(svn_client_export5):
Document the 'file source, dir target' case.
Add some punctuation.
* subversion/libsvn_client/export.c
(append_basename_if_dir): New helper.
(copy_versioned_files): Use new helper for the "WC source" case.
(svn_client_export5): Use new helper for the "URL source" case.
* subversion/tests/cmdline/export_tests.py
(export_to_explicit_cwd): Rename to..
(export_url_to_explicit_cwd): .. this.
(export_file_to_explicit_cwd): New test, similar to export_url_* variant.
(test_list): Run new test, passing, and track rename.
Modified:
subversion/trunk/subversion/include/svn_client.h
subversion/trunk/subversion/libsvn_client/export.c
subversion/trunk/subversion/tests/cmdline/export_tests.py
Modified: subversion/trunk/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_client.h?rev=1037989&r1=1037988&r2=1037989&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_client.h (original)
+++ subversion/trunk/subversion/include/svn_client.h Tue Nov 23 03:52:56 2010
@@ -4486,11 +4486,13 @@ svn_client_revprop_list(apr_hash_t **pro
* @a from_path_or_url is either the path the working copy on disk, or
* a URL to the repository you wish to export.
*
- * When exporting a directory @a to_path is the path to the directory
- * where you wish to create the exported tree, when exporting a file
- * it is the path of the file that will be created. If @a to_path is
- * the empty path the name of the file/directory in the repository
- * will be used.
+ * When exporting a directory, @a to_path is the path to the directory
+ * where you wish to create the exported tree; when exporting a file, it
+ * is the path of the file that will be created. If @a to_path is the
+ * empty path, then the basename of the export file/directory in the repository
+ * will be used. If @a to_path represents an existing directory, and a
+ * file is being exported, then a file with the that basename will be
+ * created under that directory (as with 'copy' operations).
*
* @a peg_revision is the revision where the path is first looked up
* when exporting from a repository. If @a peg_revision->kind is
Modified: subversion/trunk/subversion/libsvn_client/export.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/export.c?rev=1037989&r1=1037988&r2=1037989&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/export.c (original)
+++ subversion/trunk/subversion/libsvn_client/export.c Tue Nov 23 03:52:56 2010
@@ -95,6 +95,36 @@ get_eol_style(svn_subst_eol_style_t *sty
return SVN_NO_ERROR;
}
+/* If *APPENDABLE_DIRENT_P represents an existing directory, then append
+ * to it the basename of BASENAME_OF and return the result in
+ * *APPENDABLE_DIRENT_P. The kind of BASENAME_OF is either dirent or uri,
+ * as given by IS_URI.
+ */
+static svn_error_t *
+append_basename_if_dir(const char **appendable_dirent_p,
+ const char *basename_of,
+ svn_boolean_t is_uri,
+ apr_pool_t *pool)
+{
+ svn_node_kind_t local_kind;
+ SVN_ERR(svn_io_check_resolved_path(*appendable_dirent_p, &local_kind, pool));
+ if (local_kind == svn_node_dir)
+ {
+ const char *basename2; /* _2 because it shadows basename() */
+
+ if (is_uri)
+ basename2 = svn_path_uri_decode(svn_uri_basename(basename_of, NULL), pool);
+ else
+ basename2 = svn_dirent_basename(basename_of, NULL);
+
+ *appendable_dirent_p = svn_dirent_join(*appendable_dirent_p,
+ basename2,
+ pool);
+ }
+
+ return SVN_NO_ERROR;
+}
+
static svn_error_t *
copy_one_versioned_file(const char *from_abspath,
const char *to_abspath,
@@ -495,6 +525,7 @@ copy_versioned_files(const char *from,
}
else if (from_kind == svn_node_file)
{
+ SVN_ERR(append_basename_if_dir(&to_abspath, from_abspath, FALSE, pool));
SVN_ERR(copy_one_versioned_file(from_abspath, to_abspath, ctx->wc_ctx,
revision, native_eol, ignore_keywords,
pool));
@@ -1000,6 +1031,13 @@ svn_client_export5(svn_revnum_t *result_
NULL), pool);
eb->root_path = to_path;
}
+ else
+ {
+ SVN_ERR(append_basename_if_dir(&to_path, from_path_or_url,
+ TRUE, pool));
+ eb->root_path = to_path;
+ }
+
/* Since you cannot actually root an editor at a file, we
* manually drive a few functions of our editor. */
Modified: subversion/trunk/subversion/tests/cmdline/export_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/export_tests.py?rev=1037989&r1=1037988&r2=1037989&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/export_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/export_tests.py Tue Nov 23 03:52:56 2010
@@ -413,8 +413,8 @@ def export_HEADplus1_fails(sbox):
'export', sbox.repo_url, sbox.wc_dir,
'-r', 38956)
-def export_to_explicit_cwd(sbox):
- "export a single file to '.'"
+def export_url_to_explicit_cwd(sbox):
+ "export a single file to '.', via url"
sbox.build(create_wc = False, read_only = True)
svntest.main.safe_rmtree(sbox.wc_dir)
@@ -431,6 +431,38 @@ def export_to_explicit_cwd(sbox):
'.', expected_output,
expected_disk)
+def export_file_to_explicit_cwd(sbox):
+ "export a single file to '.', via wc"
+ sbox.build(create_wc = True, read_only = True)
+
+ iota_path = os.path.abspath(os.path.join(sbox.wc_dir, 'iota'))
+ expected_output = svntest.wc.State('', {
+ 'iota': Item(status='A '),
+ })
+ expected_disk = svntest.wc.State('', {
+ 'iota': Item(contents="This is the file 'iota'.\n"),
+ })
+
+ # prepare some variables
+ oldcwd = os.path.abspath(os.getcwd())
+ tmpdir = sbox.get_tempname('file-exports')
+ os.mkdir(tmpdir)
+
+ # do the work
+ os.chdir(tmpdir)
+ svntest.actions.run_and_verify_svn(None, None, [],
+ 'export', iota_path, '.')
+
+ # TODO: avoid manual validation
+ try:
+ if open('iota').readlines() == ["This is the file 'iota'.\n"]:
+ return
+ else:
+ raise
+ except:
+ target_file = os.path.join(oldcwd, tmpdir, 'iota')
+ raise svntest.Failure("'%s' not properly exported" % target_file)
+
def export_ignoring_keyword_translation(sbox):
"export ignoring keyword translation"
sbox.build()
@@ -674,7 +706,8 @@ test_list = [ None,
export_with_state_deleted,
export_creates_intermediate_folders,
export_HEADplus1_fails,
- export_to_explicit_cwd,
+ export_url_to_explicit_cwd,
+ export_file_to_explicit_cwd,
export_ignoring_keyword_translation,
export_working_copy_ignoring_keyword_translation,
export_with_url_unsafe_characters,