3 Star 11 Fork 3

GiteeStudio / git-svn-fast-import

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
svn-fast-export.c 10.94 KB
一键复制 编辑 原始数据 按行查看 历史
江二十三 提交于 2017-09-13 17:24 . remove static
/* Copyright (C) 2014-2015 by Maxim Bublis <b@codemonkey.ru>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "export.h"
#include "options.h"
#include <apr_signal.h>
#include <svn_cmdline.h>
#include <svn_dirent_uri.h>
#include <svn_opt.h>
#include <svn_pools.h>
#include <svn_repos.h>
#include <svn_utf.h>
void symbolize();
// A flag to see if the process has been cancelled.
static volatile sig_atomic_t cancelled = FALSE;
// A signal handler to support cancellation.
static void signal_handler(int signum) {
apr_signal(signum, SIG_IGN);
cancelled = TRUE;
}
// Setups signal handlers.
static void setup_signal_handlers() {
apr_signal(SIGINT, signal_handler);
#ifdef SIGPIPE
// Disable SIGPIPE generation for the platforms that have it.
apr_signal(SIGPIPE, SIG_IGN);
#endif
symbolize();
}
// Cancellation callback.
svn_error_t *check_cancel(void *ctx) {
if (cancelled) {
return svn_error_create(SVN_ERR_CANCELLED, NULL, "Caught signal");
}
return SVN_NO_ERROR;
}
enum {
option_incremental = SVN_OPT_FIRST_LONGOPT_ID,
option_no_ignore_abspath,
option_export_rev_marks,
option_import_rev_marks,
option_export_branches,
option_import_branches
};
static struct apr_getopt_option_t cmdline_options[] = {
{"help", 'h', 0, "Print this message and exit"},
{"revision", 'r', 1, "Set revision range."},
{"stdlayout", 's', 0, ""},
{"incremental", option_incremental, 0, ""},
{"branch", 'b', 1, "Set repository path as a branch."},
{"branches", 'B', 1, "Set repository path as a root for branches."},
{"tag", 't', 1, "Set repository path as a tag."},
{"tags", 'T', 1, "Set repository path as a root for tags."},
{"ignore-path", 'I', 1, "Ignore a path relative to branch root."},
{"ignore-abspath", 'i', 1, "Ignore repository path."},
{"no-ignore-abspath", option_no_ignore_abspath, 1,
"Do not ignore repository path."},
{"authors-file", 'A', 1, ""},
{"export-rev-marks", option_export_rev_marks, 1, ""},
{"import-rev-marks", option_import_rev_marks, 1, ""},
{"export-branches", option_export_branches, 1, ""},
{"import-branches", option_import_branches, 1, ""},
{"checksum-cache", 'c', 1, "Use checksum cache."},
{0, 0, 0, 0}};
// Set revnum to revision specified by revision arg (or to
// SVN_INVALID_REVNUM if that has the type 'unspecified'),
// possibly making use of the youngest revision number in repos.
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;
}
svn_error_t *do_main(int *exit_code, int argc, const char **argv,
apr_pool_t *pool) {
apr_getopt_t *opt_parser;
apr_status_t apr_err;
const char *repo_path = NULL;
svn_opt_revision_t start_revision, end_revision;
svn_error_t *err;
svn_fs_t *fs;
svn_stream_t *output;
svn_revnum_t lower = SVN_INVALID_REVNUM, upper = SVN_INVALID_REVNUM;
svn_revnum_t youngest;
svn_repos_t *repo;
// Trunk path prefix;
const char *trunk_path = "";
// Path to a file containing mapping of
// Subversion committers to Git authors.
const char *authors_path = NULL;
// Path to a file where marks should be exported/imported.
const char *export_marks_path = NULL, *import_marks_path = NULL;
const char *export_branches_path = NULL, *import_branches_path = NULL;
const char *checksum_cache_path = NULL;
svn_boolean_t incremental = FALSE;
export_ctx_t *ctx = export_ctx_create(pool);
// Initialize the FS library.
SVN_ERR(svn_fs_initialize(pool));
start_revision.kind = svn_opt_revision_unspecified;
end_revision.kind = svn_opt_revision_unspecified;
// Parse options.
apr_err = apr_getopt_init(&opt_parser, pool, argc, argv);
if (apr_err != APR_SUCCESS) {
return svn_error_wrap_apr(apr_err, NULL);
}
while (TRUE) {
int opt_id;
const char *opt_arg;
// Parse the next option.
apr_err = apr_getopt_long(opt_parser, cmdline_options, &opt_id, &opt_arg);
if (APR_STATUS_IS_EOF(apr_err)) {
break;
} else if (apr_err) {
return svn_error_wrap_apr(apr_err, NULL);
}
switch (opt_id) {
case 'r':
if (start_revision.kind != svn_opt_revision_unspecified) {
return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
"Multiple revision arguments encountered");
}
if (svn_opt_parse_revision(&start_revision, &end_revision, opt_arg,
pool) != 0) {
return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
"Syntax error in revision argument");
}
break;
case 's':
trunk_path = "trunk";
branch_storage_add_prefix(ctx->branches, "branches", FALSE, pool);
branch_storage_add_prefix(ctx->branches, "tags", FALSE, pool);
break;
case 'b':
case 't':
branch_storage_add_branch(ctx->branches,
branch_refname_from_path(opt_arg, pool),
opt_arg, pool);
break;
case 'B':
case 'T':
branch_storage_add_prefix(ctx->branches, opt_arg, FALSE, pool);
break;
case 'i':
tree_insert(ctx->absignores, opt_arg, opt_arg, pool);
break;
case 'I':
tree_insert(ctx->ignores, opt_arg, opt_arg, pool);
break;
case option_no_ignore_abspath:
tree_insert(ctx->no_ignores, opt_arg, opt_arg, pool);
break;
case 'A':
authors_path = opt_arg;
break;
case option_incremental:
incremental = TRUE;
break;
case option_export_rev_marks:
export_marks_path = opt_arg;
break;
case option_import_rev_marks:
import_marks_path = opt_arg;
break;
case option_export_branches:
export_branches_path = opt_arg;
break;
case option_import_branches:
import_branches_path = opt_arg;
break;
case 'c':
checksum_cache_path = opt_arg;
break;
case 'h':
print_usage(cmdline_options, pool);
*exit_code = EXIT_FAILURE;
return SVN_NO_ERROR;
}
}
// Get the repository path.
if (opt_parser->ind < opt_parser->argc) {
SVN_ERR(svn_utf_cstring_to_utf8(&repo_path,
opt_parser->argv[opt_parser->ind++], pool));
repo_path = svn_dirent_internal_style(repo_path, pool);
}
if (repo_path == NULL) {
svn_error_clear(
svn_cmdline_fprintf(stderr, pool, "Repository path required\n"));
*exit_code = EXIT_FAILURE;
return SVN_NO_ERROR;
}
SVN_ERR(svn_repos_open3(&repo, repo_path, NULL, pool, pool));
fs = svn_repos_fs(repo);
SVN_ERR(svn_fs_youngest_rev(&youngest, fs, pool));
// Find the revision numbers at which to start and end.
SVN_ERR(get_revnum(&lower, &start_revision, youngest, repo, pool));
SVN_ERR(get_revnum(&upper, &end_revision, youngest, repo, 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");
}
if (authors_path != NULL) {
SVN_ERR(author_storage_load_path(ctx->authors, authors_path, pool));
}
branch_storage_add_branch(ctx->branches, "refs/heads/master", trunk_path,
pool);
if (incremental == TRUE && import_branches_path != NULL &&
import_marks_path != NULL) {
SVN_ERR(
branch_storage_load_path(ctx->branches, import_branches_path, pool));
SVN_ERR(commit_cache_load_path(ctx->commits, import_marks_path,
ctx->branches, pool));
if (lower <= ctx->commits->last_revnum) {
lower = ctx->commits->last_revnum + 1;
}
}
if (checksum_cache_path != NULL) {
SVN_ERR(checksum_cache_load_path(ctx->blobs, checksum_cache_path, pool));
}
SVN_ERR(svn_stream_for_stdout(&output, pool));
setup_signal_handlers();
err =
export_revision_range(output, fs, lower, upper, ctx, check_cancel, pool);
if (export_marks_path != NULL) {
err = svn_error_compose_create(
err, commit_cache_dump_path(ctx->commits, export_marks_path, pool));
}
if (export_branches_path != NULL) {
err = svn_error_compose_create(
err,
branch_storage_dump_path(ctx->branches, export_branches_path, pool));
}
if (checksum_cache_path != NULL) {
err = svn_error_compose_create(
err, checksum_cache_dump_path(ctx->blobs, checksum_cache_path, pool));
}
return err;
}
int main(int argc, const char **argv) {
apr_pool_t *pool;
svn_error_t *err;
int exit_code = EXIT_SUCCESS;
// symbolize();
// Initialize the app.
if (svn_cmdline_init("svn-fast-export", stderr) != EXIT_SUCCESS) {
return EXIT_FAILURE;
}
// Create top-level pool. Use a separate mutexless allocator,
// as this app is single-threaded.
pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
err = do_main(&exit_code, argc, argv, pool);
if (err) {
exit_code = EXIT_FAILURE;
svn_cmdline_handle_exit_error(err, NULL, "svn-fast-export: ");
}
svn_pool_destroy(pool);
return exit_code;
}
C
1
https://gitee.com/oscstudio/git-svn-fast-import.git
git@gitee.com:oscstudio/git-svn-fast-import.git
oscstudio
git-svn-fast-import
git-svn-fast-import
master

搜索帮助