Didn't we already go through the discussion of "don't use --force
anymore" ?? ie. use a more descriptive option like
--overwrite-exist-revisions ?
The name --force is not descriptive of what it actually does. Which
means we need all kinds of supporting documentation to detail it. But
if somebody doesn't read the documentation and uses --force according
to an assumption of *another* meaning... they could run into
unexpected and disastrous results.
For the few cases where something like this would be needed, I have no
qualms making people type a long option name.
Cheers,
-g
On Tue, Aug 18, 2009 at 16:18, C. Michael Pilato<cmpilato_at_collab.net> wrote:
> Author: cmpilato
> Date: Tue Aug 18 07:18:50 2009
> New Revision: 38800
>
> Log:
> Make 'svnsync init' accept a --force flag which overrides the sanity
> checks ("source has revisions", "source already has svn:sync-* props")
> so that folks can easily init (or re-init) a repository backup as a
> new mirror.
>
> * subversion/svnsync/main.c
> Â (enum svnsync__opt): New 'svnsync_opt_force' value.
> Â (svnsync_cmd_table): Make 'initialize' subcommand accept --force,
> Â Â and tweak usage message to explain why that's useful.
> Â (struct subcommand_baton_t, opt_baton_t): Add 'force' member.
> Â (make_subcommand_baton): Init new 'force' member of subcommand baton.
> Â (do_initialize, main): Handle the new --force option.
>
> Modified:
> Â trunk/subversion/svnsync/main.c
>
> Modified: trunk/subversion/svnsync/main.c
> URL: http://svn.collab.net/viewvc/svn/trunk/subversion/svnsync/main.c?pathrev=38800&r1=38799&r2=38800
> ==============================================================================
> --- trunk/subversion/svnsync/main.c   Tue Aug 18 07:16:37 2009     (r38799)
> +++ trunk/subversion/svnsync/main.c   Tue Aug 18 07:18:50 2009     (r38800)
> @@ -60,7 +60,8 @@ enum svnsync__opt {
> Â svnsync_opt_config_dir,
> Â svnsync_opt_config_options,
> Â svnsync_opt_version,
> - Â svnsync_opt_trust_server_cert
> + Â svnsync_opt_trust_server_cert,
> + Â svnsync_opt_force
> Â };
>
> Â #define SVNSYNC_OPTS_DEFAULT svnsync_opt_non_interactive, \
> @@ -83,18 +84,24 @@ static const svn_opt_subcommand_desc2_t
> Â Â Â Â Â "Initialize a destination repository for synchronization from\n"
> Â Â Â Â Â "another repository.\n"
> Â Â Â Â Â "\n"
> - Â Â Â Â "The destination URL must point to the root of a repository with\n"
> - Â Â Â Â "no committed revisions. Â The destination repository must allow\n"
> - Â Â Â Â "revision property changes.\n"
> - Â Â Â Â "\n"
> Â Â Â Â Â "If the source URL is not the root of a repository, only the\n"
> Â Â Â Â Â "specified part of the repository will be synchronized.\n"
> Â Â Â Â Â "\n"
> + Â Â Â Â "The destination URL must point to the root of a repository which\n"
> + Â Â Â Â "has been configured to allow revision property changes. Â In\n"
> + Â Â Â Â "the general case, the destination repository must contain no\n"
> + Â Â Â Â "committed revisions. Â Use --force to override this restriction,\n"
> + Â Â Â Â "but understand that svnsync will assume that any revisions\n"
> + Â Â Â Â "already present in the destination repository perfectly mirror\n"
> + Â Â Â Â "their counterparts in the source repository. Â (This is useful\n"
> + Â Â Â Â "when initializing a repository made from a copy of a repository\n"
> + Â Â Â Â "as a mirror of that same repository, for example.)\n"
> + Â Â Â Â "\n"
> Â Â Â Â Â "You should not commit to, or make revision property changes in,\n"
> Â Â Â Â Â "the destination repository by any method other than 'svnsync'.\n"
> Â Â Â Â Â "In other words, the destination repository should be a read-only\n"
> Â Â Â Â Â "mirror of the source repository.\n"),
> - Â Â Â { SVNSYNC_OPTS_DEFAULT, 'q' } },
> + Â Â Â { SVNSYNC_OPTS_DEFAULT, 'q', svnsync_opt_force } },
> Â Â { "synchronize", synchronize_cmd, { "sync" },
> Â Â Â N_("usage: svnsync synchronize DEST_URL\n"
> Â Â Â Â Â "\n"
> @@ -135,6 +142,8 @@ static const apr_getopt_option_t svnsync
> Â {
> Â Â {"quiet", Â Â Â Â Â 'q', 0,
> Â Â Â Â Â Â Â Â Â Â Â Â N_("print as little as possible") },
> + Â Â {"force", Â Â Â Â Â svnsync_opt_force, 0,
> + Â Â Â Â Â Â Â Â Â Â Â N_("force operation to run") },
> Â Â {"non-interactive", svnsync_opt_non_interactive, 0,
> Â Â Â Â Â Â Â Â Â Â Â Â N_("do no interactive prompting") },
> Â Â {"no-auth-cache", Â svnsync_opt_no_auth_cache, 0,
> @@ -191,6 +200,7 @@ typedef struct {
> Â const char *config_dir;
> Â apr_hash_t *config;
> Â svn_boolean_t quiet;
> + Â svn_boolean_t force;
> Â svn_boolean_t version;
> Â svn_boolean_t help;
> Â } opt_baton_t;
> @@ -307,6 +317,7 @@ typedef struct {
> Â svn_ra_callbacks2_t source_callbacks;
> Â svn_ra_callbacks2_t sync_callbacks;
> Â svn_boolean_t quiet;
> + Â svn_boolean_t force;
> Â const char *to_url;
>
> Â /* initialize only */
> @@ -704,6 +715,7 @@ make_subcommand_baton(opt_baton_t *opt_b
> Â b->sync_callbacks.open_tmp_file = open_tmp_file;
> Â b->sync_callbacks.auth_baton = opt_baton->sync_auth_baton;
> Â b->quiet = opt_baton->quiet;
> + Â b->force = opt_baton->force;
> Â b->to_url = to_url;
> Â b->from_url = from_url;
> Â b->start_rev = start_rev;
> @@ -725,26 +737,24 @@ do_initialize(svn_ra_session_t *to_sessi
> Â {
> Â svn_ra_session_t *from_session;
> Â svn_string_t *from_url;
> - Â svn_revnum_t latest;
> + Â svn_revnum_t latest, from_latest;
> Â const char *uuid, *root_url;
> Â int normalized_rev_props_count;
>
> - Â /* First, sanity check to see that we're copying into a brand new repos. */
> -
> + Â /* First, sanity check to see that we're copying into a brand new
> + Â Â repos. Â If we aren't, and we aren't being asked to forcibly
> + Â Â complete this initialization, that's a bad news. Â */
> Â SVN_ERR(svn_ra_get_latest_revnum(to_session, &latest, pool));
> -
> - Â if (latest != 0)
> + Â if ((latest != 0) && (! baton->force))
> Â Â return svn_error_create
> Â Â Â (APR_EINVAL, NULL,
> - Â Â Â _("Cannot initialize a repository with content in it"));
> -
> - Â /* And check to see if anyone's run initialize on it before... Â We
> - Â Â may want a --force option to override this check. */
> + Â Â Â _("Destination repository already contains revision history; consider "
> + Â Â Â Â "using --force if the revisions in the repository are known to be "
> + Â Â Â Â "a mirror of the respective revisions in the source repository"));
>
> Â SVN_ERR(svn_ra_rev_prop(to_session, 0, SVNSYNC_PROP_FROM_URL,
> Â Â Â Â Â Â Â Â Â Â Â Â Â &from_url, pool));
> -
> - Â if (from_url)
> + Â if (from_url && (! baton->force))
> Â Â return svn_error_createf
> Â Â Â (APR_EINVAL, NULL,
> Â Â Â Â _("Destination repository is already synchronizing from '%s'"),
> @@ -777,25 +787,41 @@ do_initialize(svn_ra_session_t *to_sessi
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â NULL);
> Â Â }
>
> + Â /* If we're initializing a non-empty destination, we'll make sure
> + Â Â that it at least doesn't have more revisions than the source. */
> + Â if (latest != 0)
> + Â Â {
> + Â Â Â SVN_ERR(svn_ra_get_latest_revnum(from_session, &from_latest, pool));
> + Â Â Â if (from_latest < latest)
> + Â Â Â Â return svn_error_create
> + Â Â Â Â Â (APR_EINVAL, NULL,
> + Â Â Â Â Â _("Destination repository has more revisions than source "
> + Â Â Â Â Â Â "repository"));
> + Â Â }
> +
> Â SVN_ERR(svn_ra_change_rev_prop(to_session, 0, SVNSYNC_PROP_FROM_URL,
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â svn_string_create(baton->from_url, pool),
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â pool));
>
> Â SVN_ERR(svn_ra_get_uuid2(from_session, &uuid, pool));
> -
> Â SVN_ERR(svn_ra_change_rev_prop(to_session, 0, SVNSYNC_PROP_FROM_UUID,
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â svn_string_create(uuid, pool), pool));
>
> Â SVN_ERR(svn_ra_change_rev_prop(to_session, 0, SVNSYNC_PROP_LAST_MERGED_REV,
> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â svn_string_create("0", pool), pool));
> -
> - Â /* Finally, copy all non-svnsync revprops from rev 0 of the source
> - Â Â repos into the dest repos. */
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â svn_string_createf(pool, "%ld", latest),
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â pool));
>
> - Â SVN_ERR(copy_revprops(from_session, to_session, 0, FALSE,
> + Â /* Copy all non-svnsync revprops from the LATEST rev in the source
> + Â Â repository into the destination, notifying about normalized
> + Â Â props, if any. Â When LATEST is 0, this serves the practical
> + Â Â purpose of initializing data that would otherwise be overlooked
> + Â Â by the sync process (which is going to begin with r1). Â When
> + Â Â LATEST is not 0, this really serves merely aesthetic and
> + Â Â informational purposes, keeping the output of this command
> + Â Â consistent while allowing folks to see what the latest revision is. Â */
> + Â SVN_ERR(copy_revprops(from_session, to_session, latest, FALSE,
> Â Â Â Â Â Â Â Â Â Â Â Â baton->quiet, &normalized_rev_props_count, pool));
> -
> - Â /* Notify about normalized props, if any. */
> +
> Â SVN_ERR(log_properties_normalized(normalized_rev_props_count, 0, pool));
>
> Â /* TODO: It would be nice if we could set the dest repos UUID to be
> @@ -2225,6 +2251,10 @@ main(int argc, const char *argv[])
> Â Â Â Â Â Â opt_baton.version = TRUE;
> Â Â Â Â Â Â break;
>
> + Â Â Â Â Â case svnsync_opt_force:
> + Â Â Â Â Â Â opt_baton.force = TRUE;
> + Â Â Â Â Â Â break;
> +
> Â Â Â Â Â case 'q':
> Â Â Â Â Â Â opt_baton.quiet = TRUE;
> Â Â Â Â Â Â break;
>
> ------------------------------------------------------
> http://subversion.tigris.org/ds/viewMessage.do?dsForumId=495&dsMessageId=2384785
>
------------------------------------------------------
http://subversion.tigris.org/ds/viewMessage.do?dsForumId=462&dsMessageId=2384816
Received on 2009-08-18 17:50:54 CEST