You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by cm...@apache.org on 2012/12/15 10:03:26 UTC

svn commit: r1422206 - in /subversion/trunk/subversion: svnrdump/ tests/cmdline/ tests/cmdline/svnrdump_tests_data/

Author: cmpilato
Date: Sat Dec 15 09:03:23 2012
New Revision: 1422206

URL: http://svn.apache.org/viewvc?rev=1422206&view=rev
Log:
Fix issue #4104 ("'svnrdump dump -rN:M <URL>/subpath' strips subpath
in first rev only") by teaching the special-case code in svnrdump used
to handle the first revision of non-incremental range-based dump which
doesn't begin with r0 to:

   1. generate dump stream commands for adding the missing parent tree
      structure, and

   2. use full repository relpaths for the Node-path: headers.

NOTE: I'm a bit torn about whether I should have done #1 above.
      Perhaps that bit of the functionality should be tied to a
      --parents options?

* subversion/svnrdump/svnrdump.h
  (svn_rdump__get_dump_editor, svn_rdump__get_dump_editor_v2): Add
    edit_root_relpath' parameter.

* subversion/svnrdump/svnrdump.c
  (replay_revstart, replay_revstart_v2): Update call to
    svn_rdump__get_dump_editor()
  (dump_initial_full_revision): Calculate the source repository
    relpath, passing that to an updated call to svn_rdump__get_dump_editor()

* subversion/svnrdump/dump_editor.c
  (dump_edit_baton): Add 'edit_root_relpath' member.
  (dump_node): Prepend the edit root relpath to the dump stream path
    if necessary.
  (dump_mkdir): New helper function.
  (open_root): If 'edit_root_relpath' is non-NULL, use dump_mkdir() to
    generate dump-stream additions for the dump source directory and
    its parents.
  (svn_rdump__get_dump_editor): Add 'edit_root_relpath' parameter,
    and stuff it into the dump edit baton.

* subversion/tests/cmdline/svnrdump_tests_data/root-range.expected.dump,
* subversion/tests/cmdline/svnrdump_tests_data/trunk-A-range.expected.dump,
* subversion/tests/cmdline/svnrdump_tests_data/trunk-only-range.expected.dump
  New test data.

* subversion/tests/cmdline/svnrdump_tests.py
  (range_dump, only_trunk_range_dump, only_trunk_A_range_dump): New tests.
  (test_list): Add references to new tests.

Added:
    subversion/trunk/subversion/tests/cmdline/svnrdump_tests_data/root-range.expected.dump   (with props)
    subversion/trunk/subversion/tests/cmdline/svnrdump_tests_data/trunk-A-range.expected.dump   (with props)
    subversion/trunk/subversion/tests/cmdline/svnrdump_tests_data/trunk-only-range.expected.dump   (with props)
Modified:
    subversion/trunk/subversion/svnrdump/dump_editor.c
    subversion/trunk/subversion/svnrdump/svnrdump.c
    subversion/trunk/subversion/svnrdump/svnrdump.h
    subversion/trunk/subversion/tests/cmdline/svnrdump_tests.py

Modified: subversion/trunk/subversion/svnrdump/dump_editor.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnrdump/dump_editor.c?rev=1422206&r1=1422205&r2=1422206&view=diff
==============================================================================
--- subversion/trunk/subversion/svnrdump/dump_editor.c (original)
+++ subversion/trunk/subversion/svnrdump/dump_editor.c Sat Dec 15 09:03:23 2012
@@ -101,6 +101,9 @@ struct dump_edit_baton {
   /* A backdoor ra session to fetch additional information during the edit. */
   svn_ra_session_t *ra_session;
 
+  /* The relative repository path of the root of the editor drive. */
+  const char *edit_root_relpath;
+
   /* Pool for per-revision allocations */
   apr_pool_t *pool;
 
@@ -308,12 +311,18 @@ dump_node(struct dump_edit_baton *eb,
           svn_revnum_t copyfrom_rev,
           apr_pool_t *pool)
 {
+  const char *node_relpath = repos_relpath;
+
   assert(svn_relpath_is_canonical(repos_relpath));
   assert(!copyfrom_path || svn_relpath_is_canonical(copyfrom_path));
 
+  /* Add the edit root relpath prefix if necessary. */
+  if (eb->edit_root_relpath)
+    node_relpath = svn_relpath_join(eb->edit_root_relpath, node_relpath, pool);
+
   /* Node-path: commons/STATUS */
   SVN_ERR(svn_stream_printf(eb->stream, pool,
-                            SVN_REPOS_DUMPFILE_NODE_PATH ": %s\n", repos_relpath));
+                            SVN_REPOS_DUMPFILE_NODE_PATH ": %s\n", node_relpath));
 
   /* Node-kind: file */
   if (kind == svn_node_file)
@@ -416,6 +425,50 @@ dump_node(struct dump_edit_baton *eb,
 }
 
 static svn_error_t *
+dump_mkdir(struct dump_edit_baton *eb,
+           const char *repos_relpath,
+           svn_boolean_t include_props,
+           apr_pool_t *pool)
+{
+  svn_stringbuf_t *prop_header, *prop_content;
+  apr_size_t len;
+  const char *buf;
+
+  /* Node-path: ... */
+  SVN_ERR(svn_stream_printf(eb->stream, pool,
+                            SVN_REPOS_DUMPFILE_NODE_PATH ": %s\n", repos_relpath));
+
+  /* Node-kind: dir */
+  SVN_ERR(svn_stream_printf(eb->stream, pool,
+                            SVN_REPOS_DUMPFILE_NODE_KIND ": dir\n"));
+
+  /* Node-action: add */
+  SVN_ERR(svn_stream_puts(eb->stream,
+                          SVN_REPOS_DUMPFILE_NODE_ACTION ": add\n"));
+
+  if (include_props)
+    {
+      /* Dump the (empty) property block. */
+      SVN_ERR(get_props_content(&prop_header, &prop_content,
+                                apr_hash_make(pool), apr_hash_make(pool),
+                                pool, pool));
+      len = prop_header->len;
+      SVN_ERR(svn_stream_write(eb->stream, prop_header->data, &len));
+      len = prop_content->len;
+      buf = apr_psprintf(pool, SVN_REPOS_DUMPFILE_CONTENT_LENGTH
+                         ": %" APR_SIZE_T_FMT "\n", len);
+      SVN_ERR(svn_stream_puts(eb->stream, buf));
+      SVN_ERR(svn_stream_puts(eb->stream, "\n"));
+      SVN_ERR(svn_stream_write(eb->stream, prop_content->data, &len));
+      
+      /* Newlines to tie it all off. */
+      SVN_ERR(svn_stream_puts(eb->stream, "\n\n"));
+    }
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
 open_root(void *edit_baton,
           svn_revnum_t base_revision,
           apr_pool_t *pool,
@@ -434,6 +487,35 @@ open_root(void *edit_baton,
                                edit_baton, NULL, FALSE, eb->pool);
   LDR_DBG(("open_root %p\n", *root_baton));
 
+  /* If our editor is not describing changes relative to the
+     repository root, we need to manufacture the add of that path and
+     its parents in our dump output. */
+  if (eb->edit_root_relpath)
+    {
+      int i;
+      const char *parent_path = eb->edit_root_relpath;
+      apr_array_header_t *dirs_to_add =
+        apr_array_make(pool, 4, sizeof(const char *));
+      apr_pool_t *iterpool = svn_pool_create(pool);
+
+      while (! svn_path_is_empty(parent_path))
+        {
+          APR_ARRAY_PUSH(dirs_to_add, const char *) = parent_path;
+          parent_path = svn_relpath_dirname(parent_path, pool);
+        }
+
+      for (i = dirs_to_add->nelts; i > 0; --i)
+        {
+          const char *dir_to_add =
+            APR_ARRAY_IDX(dirs_to_add, i - 1, const char *);
+
+          svn_pool_clear(iterpool);
+          eb->dump_props = TRUE;
+          SVN_ERR(dump_mkdir(eb, dir_to_add, i > 1, iterpool));
+        }
+      svn_pool_destroy(iterpool);
+    }
+    
   return SVN_NO_ERROR;
 }
 
@@ -1014,6 +1096,7 @@ svn_rdump__get_dump_editor(const svn_del
                            svn_revnum_t revision,
                            svn_stream_t *stream,
                            svn_ra_session_t *ra_session,
+                           const char *edit_root_relpath,
                            svn_cancel_func_t cancel_func,
                            void *cancel_baton,
                            apr_pool_t *pool)
@@ -1026,6 +1109,7 @@ svn_rdump__get_dump_editor(const svn_del
   eb = apr_pcalloc(pool, sizeof(struct dump_edit_baton));
   eb->stream = stream;
   eb->ra_session = ra_session;
+  eb->edit_root_relpath = edit_root_relpath;
   eb->current_revision = revision;
 
   /* Create a special per-revision pool */

Modified: subversion/trunk/subversion/svnrdump/svnrdump.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnrdump/svnrdump.c?rev=1422206&r1=1422205&r2=1422206&view=diff
==============================================================================
--- subversion/trunk/subversion/svnrdump/svnrdump.c (original)
+++ subversion/trunk/subversion/svnrdump/svnrdump.c Sat Dec 15 09:03:23 2012
@@ -223,7 +223,7 @@ replay_revstart(svn_revnum_t revision,
 
   SVN_ERR(svn_rdump__get_dump_editor(editor, edit_baton, revision,
                                      rb->stdout_stream, rb->extra_ra_session,
-                                     check_cancel, NULL, pool));
+                                     NULL, check_cancel, NULL, pool));
 
   return SVN_NO_ERROR;
 }
@@ -298,7 +298,7 @@ replay_revstart_v2(svn_revnum_t revision
   SVN_ERR(svn_rdump__get_dump_editor_v2(editor, revision,
                                         rb->stdout_stream,
                                         rb->extra_ra_session,
-                                        check_cancel, NULL, pool, pool));
+                                        NULL, check_cancel, NULL, pool, pool));
 
   return SVN_NO_ERROR;
 }
@@ -425,6 +425,19 @@ dump_initial_full_revision(svn_ra_sessio
   void *report_baton;
   const svn_delta_editor_t *dump_editor;
   void *dump_baton;
+  const char *session_url, *source_relpath;
+
+  /* Determine whether we're dumping the repository root URL or some
+     child thereof.  If we're dumping a subtree of the repository
+     rather than the root, we have to jump through some hoops to make
+     our update-driven dump generation work the way a replay-driven
+     one would.
+
+     See http://subversion.tigris.org/issues/show_bug.cgi?id=4101
+  */
+  SVN_ERR(svn_ra_get_session_url(session, &session_url, pool));
+  SVN_ERR(svn_ra_get_path_relative_to_root(session, &source_relpath,
+                                           session_url, pool));
 
   /* Start with a revision record header. */
   SVN_ERR(dump_revision_header(session, stdout_stream, revision, pool));
@@ -437,7 +450,7 @@ dump_initial_full_revision(svn_ra_sessio
      full dump of REV. */
   SVN_ERR(svn_rdump__get_dump_editor(&dump_editor, &dump_baton, revision,
                                      stdout_stream, extra_ra_session,
-                                     check_cancel, NULL, pool));
+                                     source_relpath, check_cancel, NULL, pool));
   SVN_ERR(svn_ra_do_update2(session, &reporter, &report_baton, revision,
                             "", svn_depth_infinity, FALSE,
                             dump_editor, dump_baton, pool));

Modified: subversion/trunk/subversion/svnrdump/svnrdump.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnrdump/svnrdump.h?rev=1422206&r1=1422205&r2=1422206&view=diff
==============================================================================
--- subversion/trunk/subversion/svnrdump/svnrdump.h (original)
+++ subversion/trunk/subversion/svnrdump/svnrdump.h Sat Dec 15 09:03:23 2012
@@ -39,9 +39,13 @@ extern "C" {
 
 /**
  * Get a dump editor @a editor along with a @a edit_baton allocated in
- * @a pool.  The editor will write output to @a stream.  Use @a
- * cancel_func and @a cancel_baton to check for user cancellation of
- * the operation (for timely-but-safe termination).
+ * @a pool.  The editor will write output to @a stream.
+ *
+ * @a edit_root_relpath is the relative repository path of the drive
+ * which will happen on @a *editor.
+ *
+ * Use @a cancel_func and @a cancel_baton to check for user
+ * cancellation of the operation (for timely-but-safe termination).
  */
 svn_error_t *
 svn_rdump__get_dump_editor(const svn_delta_editor_t **editor,
@@ -49,6 +53,7 @@ svn_rdump__get_dump_editor(const svn_del
                            svn_revnum_t revision,
                            svn_stream_t *stream,
                            svn_ra_session_t *ra_session,
+                           const char *edit_root_relpath,
                            svn_cancel_func_t cancel_func,
                            void *cancel_baton,
                            apr_pool_t *pool);
@@ -59,6 +64,7 @@ svn_rdump__get_dump_editor_v2(svn_editor
                               svn_revnum_t revision,
                               svn_stream_t *stream,
                               svn_ra_session_t *ra_session,
+                              const char *edit_root_relpath,
                               svn_cancel_func_t cancel_func,
                               void *cancel_baton,
                               apr_pool_t *scratch_pool,

Modified: subversion/trunk/subversion/tests/cmdline/svnrdump_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/svnrdump_tests.py?rev=1422206&r1=1422205&r2=1422206&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/svnrdump_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/svnrdump_tests.py Sat Dec 15 09:03:23 2012
@@ -94,11 +94,13 @@ def compare_repos_dumps(svnrdump_sbox, s
 
 def run_dump_test(sbox, dumpfile_name, expected_dumpfile_name = None,
                   subdir = None, bypass_prop_validation = False,
-                  ignore_base_checksums = False):
+                  ignore_base_checksums = False, extra_options = []):
+
   """Load a dumpfile using 'svnadmin load', dump it with 'svnrdump
   dump' and check that the same dumpfile is produced or that
   expected_dumpfile_name is produced if provided. Additionally, the
-  subdir argument appends itself to the URL"""
+  subdir argument appends itself to the URL.  EXTRA_OPTIONS is an
+  array of optional additional options to pass to 'svnrdump dump'."""
 
   # Create an empty sandbox repository
   build_repos(sbox)
@@ -121,10 +123,10 @@ def run_dump_test(sbox, dumpfile_name, e
     repo_url = repo_url + subdir
 
   # Create a dump file using svnrdump
+  opts = extra_options + ['-q', 'dump', repo_url]
   svnrdump_dumpfile = \
       svntest.actions.run_and_verify_svnrdump(None, svntest.verify.AnyOutput,
-                                              [], 0, '-q', 'dump',
-                                              repo_url)
+                                              [], 0, *opts)
 
   if expected_dumpfile_name:
     svnadmin_dumpfile = open(os.path.join(svnrdump_tests_dir,
@@ -335,7 +337,7 @@ def copy_revprops_load(sbox):
 def only_trunk_dump(sbox):
   "dump: subdirectory"
   run_dump_test(sbox, "trunk-only.dump", subdir="/trunk",
-                expected_dumpfile_name="trunk-only.expected.dump",)
+                expected_dumpfile_name="trunk-only.expected.dump")
 
 def only_trunk_A_with_changes_dump(sbox):
   "dump: subdirectory with changes on root"
@@ -738,7 +740,34 @@ def svnrdump_load_partial_incremental_du
                                           svntest.verify.AnyOutput,
                                           [], 0, 'load', sbox.repo_url)
 
-  ########################################################################
+
+#----------------------------------------------------------------------
+@Issue(4101)
+def range_dump(sbox):
+  "dump: using -rX:Y"
+  run_dump_test(sbox, "trunk-only.dump",
+                expected_dumpfile_name="root-range.expected.dump",
+                extra_options=['-r2:HEAD'])
+
+@Issue(4101)
+def only_trunk_range_dump(sbox):
+  "dump: subdirectory using -rX:Y"
+  run_dump_test(sbox, "trunk-only.dump", subdir="/trunk",
+                expected_dumpfile_name="trunk-only-range.expected.dump",
+                extra_options=['-r1:HEAD'])
+
+@Issue(4101)
+def only_trunk_A_range_dump(sbox):
+  "dump: deeper subdirectory using -rX:Y"
+  run_dump_test(sbox, "trunk-only.dump", subdir="/trunk/A",
+                expected_dumpfile_name="trunk-A-range.expected.dump",
+                extra_options=['-r2:HEAD'])
+
+
+#----------------------------------------------------------------------
+
+
+########################################################################
 # Run the tests
 
 
@@ -789,6 +818,9 @@ test_list = [ None,
               reflect_dropped_renumbered_revs,
               dont_drop_valid_mergeinfo_during_incremental_svnrdump_loads,
               svnrdump_load_partial_incremental_dump,
+              range_dump,
+              only_trunk_range_dump,
+              only_trunk_A_range_dump,
              ]
 
 if __name__ == '__main__':

Added: subversion/trunk/subversion/tests/cmdline/svnrdump_tests_data/root-range.expected.dump
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/svnrdump_tests_data/root-range.expected.dump?rev=1422206&view=auto
==============================================================================
Binary file - no diff available.

Propchange: subversion/trunk/subversion/tests/cmdline/svnrdump_tests_data/root-range.expected.dump
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: subversion/trunk/subversion/tests/cmdline/svnrdump_tests_data/trunk-A-range.expected.dump
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/svnrdump_tests_data/trunk-A-range.expected.dump?rev=1422206&view=auto
==============================================================================
Binary file - no diff available.

Propchange: subversion/trunk/subversion/tests/cmdline/svnrdump_tests_data/trunk-A-range.expected.dump
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: subversion/trunk/subversion/tests/cmdline/svnrdump_tests_data/trunk-only-range.expected.dump
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/svnrdump_tests_data/trunk-only-range.expected.dump?rev=1422206&view=auto
==============================================================================
Binary file - no diff available.

Propchange: subversion/trunk/subversion/tests/cmdline/svnrdump_tests_data/trunk-only-range.expected.dump
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream



Re: svn commit: r1422206 - in /subversion/trunk/subversion: svnrdump/ tests/cmdline/ tests/cmdline/svnrdump_tests_data/

Posted by "C. Michael Pilato" <cm...@collab.net>.
On 12/17/2012 12:24 AM, vijay wrote:
> On Saturday 15 December 2012 02:33 PM, cmpilato@apache.org wrote:
>> Author: cmpilato
>> Date: Sat Dec 15 09:03:23 2012
>> New Revision: 1422206
>>
>> URL: http://svn.apache.org/viewvc?rev=1422206&view=rev
>> Log:
>> Fix issue #4104 ("'svnrdump dump -rN:M <URL>/subpath' strips subpath
>> in first rev only")
> 
> Issue #4101, right?

Oops!  Good catch.

-- 
C. Michael Pilato <cm...@collab.net>
CollabNet   <>   www.collab.net   <>   Enterprise Cloud Development


Re: svn commit: r1422206 - in /subversion/trunk/subversion: svnrdump/ tests/cmdline/ tests/cmdline/svnrdump_tests_data/

Posted by vijay <vi...@collab.net>.
On Saturday 15 December 2012 02:33 PM, cmpilato@apache.org wrote:
> Author: cmpilato
> Date: Sat Dec 15 09:03:23 2012
> New Revision: 1422206
>
> URL: http://svn.apache.org/viewvc?rev=1422206&view=rev
> Log:
> Fix issue #4104 ("'svnrdump dump -rN:M <URL>/subpath' strips subpath
> in first rev only")

Issue #4101, right?

Thanks & Regards,
Vijayaguru