📄 main.c
字号:
"ought to be run. Recovery requires exclusive access and will\n" "exit if the repository is in use by another process.\n"), {svnadmin__wait} }, {"rmlocks", subcommand_rmlocks, {0}, N_ ("usage: svnadmin rmlocks REPOS_PATH LOCKED_PATH...\n\n" "Unconditionally remove lock from each LOCKED_PATH.\n"), {0} }, {"rmtxns", subcommand_rmtxns, {0}, N_ ("usage: svnadmin rmtxns REPOS_PATH TXN_NAME...\n\n" "Delete the named transaction(s).\n"), {'q'} }, {"setlog", subcommand_setlog, {0}, N_ ("usage: svnadmin setlog REPOS_PATH -r REVISION FILE\n\n" "Set the log-message on revision REVISION to the contents of FILE. Use\n" "--bypass-hooks to avoid triggering the revision-property-related hooks\n" "(for example, if you do not want an email notification sent\n" "from your post-revprop-change hook, or because the modification of\n" "revision properties has not been enabled in the pre-revprop-change\n" "hook).\n\n" "NOTE: revision properties are not historied, so this command\n" "will permanently overwrite the previous log message.\n"), {'r', svnadmin__bypass_hooks} }, {"verify", subcommand_verify, {0}, N_ ("usage: svnadmin verify REPOS_PATH\n\n" "Verifies the data stored in the repository.\n"), {0} }, { NULL, NULL, {0}, NULL, {0} }};/* Baton for passing option/argument state to a subcommand function. */struct svnadmin_opt_state{ const char *repository_path; const char *new_repository_path; /* hotcopy dest. path */ const char *fs_type; /* --fs-type */ svn_boolean_t pre_1_4_compatible; /* --pre-1.4-compatible */ svn_opt_revision_t start_revision, end_revision; /* -r X[:Y] */ svn_boolean_t help; /* --help or -? */ svn_boolean_t version; /* --version */ svn_boolean_t incremental; /* --incremental */ svn_boolean_t use_deltas; /* --deltas */ svn_boolean_t use_pre_commit_hook; /* --use-pre-commit-hook */ svn_boolean_t use_post_commit_hook; /* --use-post-commit-hook */ svn_boolean_t quiet; /* --quiet */ svn_boolean_t bdb_txn_nosync; /* --bdb-txn-nosync */ svn_boolean_t bdb_log_keep; /* --bdb-log-keep */ svn_boolean_t clean_logs; /* --clean-logs */ svn_boolean_t bypass_hooks; /* --bypass-hooks */ svn_boolean_t wait; /* --wait */ enum svn_repos_load_uuid uuid_action; /* --ignore-uuid, --force-uuid */ const char *parent_dir; const char *config_dir; /* Overriding Configuration Directory */};/* Set *REVNUM to the revision specified by REVISION (or to SVN_INVALID_REVNUM if that has the type 'unspecified'), possibly making use of the YOUNGEST revision number in REPOS. */static svn_error_t *get_revnum(svn_revnum_t *revnum, const svn_opt_revision_t *revision, svn_revnum_t youngest, svn_repos_t *repos, apr_pool_t *pool){ if (revision->kind == svn_opt_revision_number) *revnum = revision->value.number; else if (revision->kind == svn_opt_revision_head) *revnum = youngest; else if (revision->kind == svn_opt_revision_date) SVN_ERR(svn_repos_dated_revision (revnum, repos, revision->value.date, pool)); else if (revision->kind == svn_opt_revision_unspecified) *revnum = SVN_INVALID_REVNUM; else return svn_error_create (SVN_ERR_CL_ARG_PARSING_ERROR, NULL, _("Invalid revision specifier")); if (*revnum > youngest) return svn_error_createf (SVN_ERR_CL_ARG_PARSING_ERROR, NULL, _("Revisions must not be greater than the youngest revision (%ld)"), youngest); return SVN_NO_ERROR;}/* This implements `svn_opt_subcommand_t'. */static svn_error_t *subcommand_create(apr_getopt_t *os, void *baton, apr_pool_t *pool){ struct svnadmin_opt_state *opt_state = baton; svn_repos_t *repos; apr_hash_t *config; apr_hash_t *fs_config = apr_hash_make(pool);; apr_hash_set(fs_config, SVN_FS_CONFIG_BDB_TXN_NOSYNC, APR_HASH_KEY_STRING, (opt_state->bdb_txn_nosync ? "1" : "0")); apr_hash_set(fs_config, SVN_FS_CONFIG_BDB_LOG_AUTOREMOVE, APR_HASH_KEY_STRING, (opt_state->bdb_log_keep ? "0" : "1")); if (opt_state->fs_type) apr_hash_set(fs_config, SVN_FS_CONFIG_FS_TYPE, APR_HASH_KEY_STRING, opt_state->fs_type); if (opt_state->pre_1_4_compatible) apr_hash_set(fs_config, SVN_FS_CONFIG_PRE_1_4_COMPATIBLE, APR_HASH_KEY_STRING, "1"); SVN_ERR(svn_config_get_config(&config, opt_state->config_dir, pool)); SVN_ERR(svn_repos_create(&repos, opt_state->repository_path, NULL, NULL, config, fs_config, pool)); svn_fs_set_warning_func(svn_repos_fs(repos), warning_func, NULL); return SVN_NO_ERROR;}/* This implements `svn_opt_subcommand_t'. */static svn_error_t *subcommand_deltify(apr_getopt_t *os, void *baton, apr_pool_t *pool){ struct svnadmin_opt_state *opt_state = baton; svn_repos_t *repos; svn_fs_t *fs; svn_revnum_t start = SVN_INVALID_REVNUM, end = SVN_INVALID_REVNUM; svn_revnum_t youngest, revision; apr_pool_t *subpool = svn_pool_create(pool); SVN_ERR(open_repos(&repos, opt_state->repository_path, pool)); fs = svn_repos_fs(repos); SVN_ERR(svn_fs_youngest_rev(&youngest, fs, pool)); /* Find the revision numbers at which to start and end. */ SVN_ERR(get_revnum(&start, &opt_state->start_revision, youngest, repos, pool)); SVN_ERR(get_revnum(&end, &opt_state->end_revision, youngest, repos, pool)); /* Fill in implied revisions if necessary. */ if (start == SVN_INVALID_REVNUM) start = youngest; if (end == SVN_INVALID_REVNUM) end = start; if (start > end) return svn_error_create (SVN_ERR_CL_ARG_PARSING_ERROR, NULL, _("First revision cannot be higher than second")); /* Loop over the requested revision range, performing the predecessor deltification on paths changed in each. */ for (revision = start; revision <= end; revision++) { svn_pool_clear(subpool); SVN_ERR(check_cancel(NULL)); if (! opt_state->quiet) SVN_ERR(svn_cmdline_printf(subpool, _("Deltifying revision %ld..."), revision)); SVN_ERR(svn_fs_deltify_revision(fs, revision, subpool)); if (! opt_state->quiet) SVN_ERR(svn_cmdline_printf(subpool, _("done.\n"))); } svn_pool_destroy(subpool); return SVN_NO_ERROR;}/* Baton for recode_write(). */struct recode_write_baton{ apr_pool_t *pool; FILE *out;};/* This implements the 'svn_write_fn_t' interface. Write DATA to ((struct recode_write_baton *) BATON)->out, in the console encoding, using svn_cmdline_fprintf(). DATA is a UTF8-encoded C string, therefore ignore LEN. ### This recoding mechanism might want to be abstracted into ### svn_io.h or svn_cmdline.h, if it proves useful elsewhere. */static svn_error_t *recode_write(void *baton, const char *data, apr_size_t *len){ struct recode_write_baton *rwb = baton; svn_pool_clear(rwb->pool); return svn_cmdline_fputs(data, rwb->out, rwb->pool);}/* Create a stream, to write to STD_STREAM, that uses recode_write() to perform UTF-8 to console encoding translation. */static svn_stream_t *recode_stream_create(FILE *std_stream, apr_pool_t *pool){ struct recode_write_baton *std_stream_rwb = apr_palloc(pool, sizeof(struct recode_write_baton)); svn_stream_t *rw_stream = svn_stream_create(std_stream_rwb, pool); std_stream_rwb->pool = svn_pool_create(pool); std_stream_rwb->out = std_stream; svn_stream_set_write(rw_stream, recode_write); return rw_stream;}/* This implements `svn_opt_subcommand_t'. */static svn_error_t *subcommand_dump(apr_getopt_t *os, void *baton, apr_pool_t *pool){ struct svnadmin_opt_state *opt_state = baton; svn_repos_t *repos; svn_fs_t *fs; svn_stream_t *stdout_stream, *stderr_stream = NULL; svn_revnum_t lower = SVN_INVALID_REVNUM, upper = SVN_INVALID_REVNUM; svn_revnum_t youngest; SVN_ERR(open_repos(&repos, opt_state->repository_path, pool)); fs = svn_repos_fs(repos); SVN_ERR(svn_fs_youngest_rev(&youngest, fs, pool)); /* Find the revision numbers at which to start and end. */ SVN_ERR(get_revnum(&lower, &opt_state->start_revision, youngest, repos, pool)); SVN_ERR(get_revnum(&upper, &opt_state->end_revision, youngest, repos, pool)); /* Fill in implied revisions if necessary. */ if (lower == SVN_INVALID_REVNUM) { lower = 0; upper = youngest; } else if (upper == SVN_INVALID_REVNUM) { upper = lower; } if (lower > upper) return svn_error_create (SVN_ERR_CL_ARG_PARSING_ERROR, NULL, _("First revision cannot be higher than second")); /* Run the dump to STDOUT. Let the user redirect output into a file if they want. :-) */ SVN_ERR(create_stdio_stream(&stdout_stream, apr_file_open_stdout, pool)); /* Progress feedback goes to STDERR, unless they asked to suppress it. */ if (! opt_state->quiet) stderr_stream = recode_stream_create(stderr, pool); SVN_ERR(svn_repos_dump_fs2(repos, stdout_stream, stderr_stream, lower, upper, opt_state->incremental, opt_state->use_deltas, check_cancel, NULL, pool)); return SVN_NO_ERROR;}/* This implements `svn_opt_subcommand_t'. */static svn_error_t *subcommand_help(apr_getopt_t *os, void *baton, apr_pool_t *pool){ struct svnadmin_opt_state *opt_state = baton; const char *header = _("general usage: svnadmin SUBCOMMAND REPOS_PATH [ARGS & OPTIONS ...]\n" "Type 'svnadmin help <subcommand>' for help on a specific subcommand.\n" "Type 'svnadmin --version' to see the program version and FS modules.\n" "\n" "Available subcommands:\n"); const char *fs_desc_start = _("The following repository back-end (FS) modules are available:\n\n"); svn_stringbuf_t *version_footer; version_footer = svn_stringbuf_create(fs_desc_start, pool); SVN_ERR(svn_fs_print_modules(version_footer, pool)); SVN_ERR(svn_opt_print_help(os, "svnadmin", opt_state ? opt_state->version : FALSE, FALSE, version_footer->data, header, cmd_table, options_table, NULL, pool)); return SVN_NO_ERROR;}/* This implements `svn_opt_subcommand_t'. */static svn_error_t *subcommand_load(apr_getopt_t *os, void *baton, apr_pool_t *pool){ struct svnadmin_opt_state *opt_state = baton; svn_repos_t *repos; svn_stream_t *stdin_stream, *stdout_stream = NULL; SVN_ERR(open_repos(&repos, opt_state->repository_path, pool)); /* Read the stream from STDIN. Users can redirect a file. */ SVN_ERR(create_stdio_stream(&stdin_stream, apr_file_open_stdin, pool)); /* Progress feedback goes to STDOUT, unless they asked to suppress it. */ if (! opt_state->quiet) stdout_stream = recode_stream_create(stdout, pool); SVN_ERR(svn_repos_load_fs2(repos, stdin_stream, stdout_stream, opt_state->uuid_action, opt_state->parent_dir, opt_state->use_pre_commit_hook, opt_state->use_post_commit_hook, check_cancel, NULL, pool)); return SVN_NO_ERROR;}/* This implements `svn_opt_subcommand_t'. */static svn_error_t *subcommand_lstxns(apr_getopt_t *os, void *baton, apr_pool_t *pool){ struct svnadmin_opt_state *opt_state = baton; svn_repos_t *repos; svn_fs_t *fs; apr_array_header_t *txns; int i; SVN_ERR(open_repos(&repos, opt_state->repository_path, pool)); fs = svn_repos_fs(repos); SVN_ERR(svn_fs_list_transactions(&txns, fs, pool)); /* Loop, printing revisions. */ for (i = 0; i < txns->nelts; i++) { SVN_ERR(svn_cmdline_printf(pool, "%s\n", APR_ARRAY_IDX(txns, i, const char *))); } return SVN_NO_ERROR;}/* A callback which is called when the recovery starts. */static svn_error_t *recovery_started(void *baton){ apr_pool_t *pool = (apr_pool_t *)baton; SVN_ERR(svn_cmdline_printf(pool, _("Repository lock acquired.\n" "Please wait; recovering the" " repository may take some time...\n"))); SVN_ERR(svn_cmdline_fflush(stdout)); /* Enable cancellation signal handlers. */ setup_cancellation_signals(signal_handler); return SVN_NO_ERROR;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -