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. Index: subversion/include/svn_repos.h =================================================================== --- subversion/include/svn_repos.h (revision 1564487) +++ subversion/include/svn_repos.h (working copy) @@ -2854,6 +2854,11 @@ * 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 @@ * @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, Index: subversion/libsvn_repos/deprecated.c =================================================================== --- subversion/libsvn_repos/deprecated.c (revision 1564487) +++ subversion/libsvn_repos/deprecated.c (working copy) @@ -795,6 +795,30 @@ /*** 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, Index: subversion/libsvn_repos/load-fs-vtable.c =================================================================== --- subversion/libsvn_repos/load-fs-vtable.c (revision 1564487) +++ subversion/libsvn_repos/load-fs-vtable.c (working copy) @@ -55,6 +55,7 @@ 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,30 +697,35 @@ 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) ? FALSE : TRUE; /* If we're skipping this revision, we're done here. */ if (rb->skipped) return SVN_NO_ERROR; + /* If we're ignore dates, 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); + /* Remember any datestamp that passes through! (See comment in + close_revision() below.) */ + if (is_date) + rb->datestamp = svn_string_dup(value, rb->pool); + /* Collect property changes to apply them in one FS call in close_revision. */ prop->name = apr_pstrdup(rb->pool, name); prop->value = svn_string_dup(value, rb->pool); - - /* Remember any datestamp that passes through! (See comment in - close_revision() below.) */ - if (! strcmp(name, SVN_PROP_REVISION_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 @@ 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_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_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 @@ 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); Index: subversion/svnadmin/svnadmin.c =================================================================== --- subversion/svnadmin/svnadmin.c (revision 1564487) +++ subversion/svnadmin/svnadmin.c (working copy) @@ -189,6 +189,7 @@ 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 @@ {"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 @@ "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 @@ 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 @@ 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, ¬ify_baton, check_cancel, NULL, pool); if (err && err->apr_err == SVN_ERR_BAD_PROPERTY_VALUE) @@ -2468,6 +2475,9 @@ 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;