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 2014/02/05 15:37:23 UTC

svn commit: r1564789 - in /subversion/trunk/subversion: include/svn_repos.h libsvn_repos/deprecated.c libsvn_repos/load-fs-vtable.c svnadmin/svnadmin.c tests/cmdline/svnadmin_tests.py

Author: cmpilato
Date: Wed Feb  5 14:37:22 2014
New Revision: 1564789

URL: http://svn.apache.org/r1564789
Log:
Introduce '--ignore-dates' option for 'svnadmin load', which causes
the load process to ignore the revision datestamps found in the
dumpstream.  This allows folks to more easily use dumpfiles as
repository templates which appear (datestamp-wise) as normal commits
would.

* subversion/include/svn_repos.h
  (svn_repos_load_fs5): New version of this API which accepts
    'ignore_dates' flag.

* subversion/libsvn_repos/deprecated.c
  (svn_repos_load_fs4): Moved here from load-fs-vtable.c, and is now
    just a wrapper around svn_repos_load_fs5().

* subversion/libsvn_repos/load-fs-vtable.c
  (parse_baton): Add 'ignore_dates' member.
  (set_revision_property, close_revision): Handle ignore_dates flag.
  (svn_repos_load_fs5): New version of this API which accepts
    'ignore_dates' flag.

* subversion/svnadmin/svnadmin.c
  (svnadmin__ignore_dates): New enum value.
  (options_table): Define --ignore-dates option.
  (cmd_table): Allow 'load' to accept --ignore-dates.
  (svnadmin_opt_state): Add 'ignore_dates' member.
  (subcommand_load): Now use svn_repos_load_fs5().
  (main): Handle --ignore-dates option.

* subversion/tests/cmdline/svnadmin_tests.py
  (load_ignore_dates): New test for 'svnadmin load --ignore-dates'.
  (test_list): Add reference to new test.

Modified:
    subversion/trunk/subversion/include/svn_repos.h
    subversion/trunk/subversion/libsvn_repos/deprecated.c
    subversion/trunk/subversion/libsvn_repos/load-fs-vtable.c
    subversion/trunk/subversion/svnadmin/svnadmin.c
    subversion/trunk/subversion/tests/cmdline/svnadmin_tests.py

Modified: subversion/trunk/subversion/include/svn_repos.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_repos.h?rev=1564789&r1=1564788&r2=1564789&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_repos.h (original)
+++ subversion/trunk/subversion/include/svn_repos.h Wed Feb  5 14:37:22 2014
@@ -2854,6 +2854,11 @@ svn_repos_dump_fs(svn_repos_t *repos,
  * node properties (those in the svn: namespace) against established
  * rules for those things.
  *
+ * If @a ignore_dates is set, ignore any revision datestamps found in
+ * @a dumpstream, allowing the revisions created by the load process
+ * to be stamped as if they were newly created via the normal commit
+ * process.
+ *
  * If non-NULL, use @a notify_func and @a notify_baton to send notification
  * of events to the caller.
  *
@@ -2861,9 +2866,33 @@ svn_repos_dump_fs(svn_repos_t *repos,
  * @a cancel_baton as argument to see if the client wishes to cancel
  * the load.
  *
- * @since New in 1.8.
+ * @since New in 1.9.
  */
 svn_error_t *
+svn_repos_load_fs5(svn_repos_t *repos,
+                   svn_stream_t *dumpstream,
+                   svn_revnum_t start_rev,
+                   svn_revnum_t end_rev,
+                   enum svn_repos_load_uuid uuid_action,
+                   const char *parent_dir,
+                   svn_boolean_t use_pre_commit_hook,
+                   svn_boolean_t use_post_commit_hook,
+                   svn_boolean_t validate_props,
+                   svn_boolean_t ignore_dates,
+                   svn_repos_notify_func_t notify_func,
+                   void *notify_baton,
+                   svn_cancel_func_t cancel_func,
+                   void *cancel_baton,
+                   apr_pool_t *pool);
+
+/** Similar to svn_repos_load_fs5(), but with @a ignore_dates
+ * always passed as FALSE.
+ *
+ * @since New in 1.9.
+ * @deprecated Provided for backward compatibility with the 1.8 API.
+ */
+SVN_DEPRECATED
+svn_error_t *
 svn_repos_load_fs4(svn_repos_t *repos,
                    svn_stream_t *dumpstream,
                    svn_revnum_t start_rev,
@@ -3126,6 +3155,7 @@ svn_repos_get_fs_build_parser4(const svn
                                apr_pool_t *pool);
 
 
+
 /**
  * A vtable that is driven by svn_repos_parse_dumpstream2().
  * Similar to #svn_repos_parse_fns3_t except that it lacks

Modified: subversion/trunk/subversion/libsvn_repos/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/deprecated.c?rev=1564789&r1=1564788&r2=1564789&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_repos/deprecated.c (original)
+++ subversion/trunk/subversion/libsvn_repos/deprecated.c Wed Feb  5 14:37:22 2014
@@ -795,6 +795,30 @@ svn_repos_verify_fs(svn_repos_t *repos,
 /*** From load.c ***/
 
 svn_error_t *
+svn_repos_load_fs4(svn_repos_t *repos,
+                   svn_stream_t *dumpstream,
+                   svn_revnum_t start_rev,
+                   svn_revnum_t end_rev,
+                   enum svn_repos_load_uuid uuid_action,
+                   const char *parent_dir,
+                   svn_boolean_t use_pre_commit_hook,
+                   svn_boolean_t use_post_commit_hook,
+                   svn_boolean_t validate_props,
+                   svn_repos_notify_func_t notify_func,
+                   void *notify_baton,
+                   svn_cancel_func_t cancel_func,
+                   void *cancel_baton,
+                   apr_pool_t *pool)
+{
+  return svn_repos_load_fs5(repos, dumpstream, start_rev, end_rev,
+                            uuid_action, parent_dir,
+                            use_post_commit_hook, use_post_commit_hook,
+                            validate_props, FALSE,
+                            notify_func, notify_baton,
+                            cancel_func, cancel_baton, pool);
+}
+
+svn_error_t *
 svn_repos_load_fs3(svn_repos_t *repos,
                    svn_stream_t *dumpstream,
                    enum svn_repos_load_uuid uuid_action,

Modified: subversion/trunk/subversion/libsvn_repos/load-fs-vtable.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/load-fs-vtable.c?rev=1564789&r1=1564788&r2=1564789&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_repos/load-fs-vtable.c (original)
+++ subversion/trunk/subversion/libsvn_repos/load-fs-vtable.c Wed Feb  5 14:37:22 2014
@@ -55,6 +55,7 @@ struct parse_baton
 
   svn_boolean_t use_history;
   svn_boolean_t validate_props;
+  svn_boolean_t ignore_dates;
   svn_boolean_t use_pre_commit_hook;
   svn_boolean_t use_post_commit_hook;
   enum svn_repos_load_uuid uuid_action;
@@ -696,11 +697,17 @@ set_revision_property(void *baton,
                       const svn_string_t *value)
 {
   struct revision_baton *rb = baton;
+  struct parse_baton *pb = rb->pb;
+  svn_boolean_t is_date = strcmp(name, SVN_PROP_REVISION_DATE) == 0;
 
   /* If we're skipping this revision, we're done here. */
   if (rb->skipped)
     return SVN_NO_ERROR;
 
+  /* If we're ignoring dates, and this is one, we're done here. */
+  if (is_date && pb->ignore_dates)
+    return SVN_NO_ERROR;
+
   if (rb->rev > 0)
     {
       svn_prop_t *prop = &APR_ARRAY_PUSH(rb->revprops, svn_prop_t);
@@ -712,14 +719,13 @@ set_revision_property(void *baton,
 
       /* Remember any datestamp that passes through!  (See comment in
          close_revision() below.) */
-      if (! strcmp(name, SVN_PROP_REVISION_DATE))
+      if (is_date)
         rb->datestamp = svn_string_dup(value, rb->pool);
     }
   else if (rb->rev == 0)
     {
       /* Special case: set revision 0 properties when loading into an
          'empty' filesystem. */
-      struct parse_baton *pb = rb->pb;
       svn_revnum_t youngest_rev;
 
       SVN_ERR(svn_fs_youngest_rev(&youngest_rev, pb->fs, rb->pool));
@@ -927,10 +933,12 @@ close_revision(void *baton)
   if (rb->skipped || (rb->rev <= 0))
     return SVN_NO_ERROR;
 
-  if (!rb->datestamp)
+  /* If the dumpstream doesn't have an 'svn:date' property and we
+     aren't ignoring the dates in the dumpstream altogether, remove
+     any 'svn:date' revision property that was set by FS layer when
+     the TXN was created.  */
+  if (! (pb->ignore_dates || rb->datestamp))
     {
-      /* Remove 'svn:date' revision property that was set by FS layer when TXN
-         created if source dump doesn't have 'svn:date' property. */
       svn_prop_t *prop = &APR_ARRAY_PUSH(rb->revprops, svn_prop_t);
       prop->name = SVN_PROP_REVISION_DATE;
       prop->value = NULL;
@@ -1108,9 +1116,8 @@ svn_repos_get_fs_build_parser4(const svn
 }
 
 
-
 svn_error_t *
-svn_repos_load_fs4(svn_repos_t *repos,
+svn_repos_load_fs5(svn_repos_t *repos,
                    svn_stream_t *dumpstream,
                    svn_revnum_t start_rev,
                    svn_revnum_t end_rev,
@@ -1119,6 +1126,7 @@ svn_repos_load_fs4(svn_repos_t *repos,
                    svn_boolean_t use_pre_commit_hook,
                    svn_boolean_t use_post_commit_hook,
                    svn_boolean_t validate_props,
+                   svn_boolean_t ignore_dates,
                    svn_repos_notify_func_t notify_func,
                    void *notify_baton,
                    svn_cancel_func_t cancel_func,
@@ -1147,6 +1155,7 @@ svn_repos_load_fs4(svn_repos_t *repos,
   pb = parse_baton;
   pb->use_pre_commit_hook = use_pre_commit_hook;
   pb->use_post_commit_hook = use_post_commit_hook;
+  pb->ignore_dates = ignore_dates;
 
   return svn_repos_parse_dumpstream3(dumpstream, parser, parse_baton, FALSE,
                                      cancel_func, cancel_baton, pool);

Modified: subversion/trunk/subversion/svnadmin/svnadmin.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnadmin/svnadmin.c?rev=1564789&r1=1564788&r2=1564789&view=diff
==============================================================================
--- subversion/trunk/subversion/svnadmin/svnadmin.c (original)
+++ subversion/trunk/subversion/svnadmin/svnadmin.c Wed Feb  5 14:37:22 2014
@@ -189,6 +189,7 @@ enum svnadmin__cmdline_options_t
     svnadmin__config_dir,
     svnadmin__bypass_hooks,
     svnadmin__bypass_prop_validation,
+    svnadmin__ignore_dates,
     svnadmin__use_pre_commit_hook,
     svnadmin__use_post_commit_hook,
     svnadmin__use_pre_revprop_change_hook,
@@ -235,6 +236,9 @@ static const apr_getopt_option_t options
     {"bypass-prop-validation",  svnadmin__bypass_prop_validation, 0,
      N_("bypass property validation logic")},
 
+    {"ignore-dates",  svnadmin__ignore_dates, 0,
+     N_("ignore revision datestamps found in the stream")},
+
     {"quiet",         'q', 0,
      N_("no progress (only errors to stderr)")},
 
@@ -404,6 +408,7 @@ static const svn_opt_subcommand_desc2_t 
     "If --revision is specified, limit the loaded revisions to only those\n"
     "in the dump stream whose revision numbers match the specified range.\n"),
    {'q', 'r', svnadmin__ignore_uuid, svnadmin__force_uuid,
+    svnadmin__ignore_dates,
     svnadmin__use_pre_commit_hook, svnadmin__use_post_commit_hook,
     svnadmin__parent_dir, svnadmin__bypass_prop_validation, 'M'} },
 
@@ -534,6 +539,7 @@ struct svnadmin_opt_state
   svn_boolean_t keep_going;                         /* --keep-going */
   svn_boolean_t check_normalization;                /* --check-normalization */
   svn_boolean_t bypass_prop_validation;             /* --bypass-prop-validation */
+  svn_boolean_t ignore_dates;                       /* --ignore-dates */
   enum svn_repos_load_uuid uuid_action;             /* --ignore-uuid,
                                                        --force-uuid */
   apr_uint64_t memory_cache_size;                   /* --memory-cache-size M */
@@ -1331,11 +1337,12 @@ subcommand_load(apr_getopt_t *os, void *
   if (! opt_state->quiet)
     notify_baton.feedback_stream = recode_stream_create(stdout, pool);
 
-  err = svn_repos_load_fs4(repos, stdin_stream, lower, upper,
+  err = svn_repos_load_fs5(repos, stdin_stream, lower, upper,
                            opt_state->uuid_action, opt_state->parent_dir,
                            opt_state->use_pre_commit_hook,
                            opt_state->use_post_commit_hook,
                            !opt_state->bypass_prop_validation,
+                           opt_state->ignore_dates,
                            opt_state->quiet ? NULL : repos_notify_handler,
                            &notify_baton, check_cancel, NULL, pool);
   if (err && err->apr_err == SVN_ERR_BAD_PROPERTY_VALUE)
@@ -2468,6 +2475,9 @@ sub_main(int *exit_code, int argc, const
       case svnadmin__bypass_prop_validation:
         opt_state.bypass_prop_validation = TRUE;
         break;
+      case svnadmin__ignore_dates:
+        opt_state.ignore_dates = TRUE;
+        break;
       case svnadmin__clean_logs:
         opt_state.clean_logs = TRUE;
         break;

Modified: subversion/trunk/subversion/tests/cmdline/svnadmin_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/svnadmin_tests.py?rev=1564789&r1=1564788&r2=1564789&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/svnadmin_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/svnadmin_tests.py Wed Feb  5 14:37:22 2014
@@ -26,11 +26,12 @@
 
 # General modules
 import os
+import logging
 import re
 import shutil
 import sys
 import threading
-import logging
+import time
 
 logger = logging.getLogger()
 
@@ -2242,6 +2243,36 @@ def fsfs_hotcopy_old_non_empty(sbox):
   check_hotcopy_fsfs(sbox.repo_dir, backup_dir)
 
 
+def load_ignore_dates(sbox):
+  "svnadmin load --ignore-dates"
+
+  # All revisions in the loaded repository should come after this time.
+  start_time = time.localtime()
+  time.sleep(1)
+  
+  sbox.build(create_wc=False)
+  svntest.main.safe_rmtree(sbox.repo_dir, True)
+  svntest.main.create_repos(sbox.repo_dir)
+
+  dumpfile_skeleton = open(os.path.join(os.path.dirname(sys.argv[0]),
+                                        'svnadmin_tests_data',
+                                        'skeleton_repos.dump')).read()
+
+  load_dumpstream(sbox, dumpfile_skeleton, '--ignore-dates')
+  svntest.actions.run_and_verify_svnlook("Unexpected output", ['6\n'],
+                                         None, 'youngest', sbox.repo_dir)
+  for rev in range(6):
+    exit_code, output, errput = svntest.main.run_svnlook('date', '-r', rev,
+                                                         sbox.repo_dir)
+    if errput:
+      raise SVNUnexpectedStderr(errput)
+    rev_time = time.strptime(output[0].rstrip()[:19], '%Y-%m-%d %H:%M:%S')
+    if rev_time < start_time:
+      raise svntest.Failure("Revision time for r%d older than load start time\n"
+                            "    rev_time: %s\n"
+                            "  start_time: %s"
+                            % (rev, str(rev_time), str(start_time)))
+
 ########################################################################
 # Run the tests
 
@@ -2283,6 +2314,7 @@ test_list = [ None,
               verify_denormalized_names,
               fsfs_recover_old_non_empty,
               fsfs_hotcopy_old_non_empty,
+              load_ignore_dates,
              ]
 
 if __name__ == '__main__':