aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColin Guthrie <colin@mageia.org>2014-05-29 00:47:39 +0100
committerColin Guthrie <colin@mageia.org>2014-05-29 00:47:39 +0100
commitf8ed2101da602b39e6b914382baa4fd6872b7ea9 (patch)
tree48e594dd690ab7763cbaa474f493fbcd53ed3049
parent1dbf0a91195c6e8bd4404cc6b922ba35dd5e9b4e (diff)
downloadsvn2git-f8ed2101da602b39e6b914382baa4fd6872b7ea9.tar
svn2git-f8ed2101da602b39e6b914382baa4fd6872b7ea9.tar.gz
svn2git-f8ed2101da602b39e6b914382baa4fd6872b7ea9.tar.bz2
svn2git-f8ed2101da602b39e6b914382baa4fd6872b7ea9.tar.xz
svn2git-f8ed2101da602b39e6b914382baa4fd6872b7ea9.zip
Support repository renaming.
This allows us to svn mv the cauldron/PKG/current folder to a new name and have this copied over to git. It does not yet handle the case where subsequent commits to previous distros for the old name are magically moved over to the new name for the repo (which I think is the correct behaviour as noted on the sysadm mailing list) so some kind of rename mapping will have to be kept (if I ever implement resuming support, then this map will have to be dumped to a file and restored again about restart) Another problem is that the tags are apparently all squashed up due to the svn mv commit, but this should be handled via a simple return... after dealing with the repo rename (although some changes may get lost :( if this is not a straight copy (i.e. svn cp + changes in the same txn)
-rw-r--r--src/svn.cpp80
1 files changed, 59 insertions, 21 deletions
diff --git a/src/svn.cpp b/src/svn.cpp
index 72f73cd..6bb0d2b 100644
--- a/src/svn.cpp
+++ b/src/svn.cpp
@@ -436,6 +436,7 @@ public:
const char *path_from, svn_revnum_t rev_from,
apr_hash_t *changes, const QString &current, const Rules::Match &rule,
const MatchRuleList &matchRules, apr_pool_t *pool);
+ Repository* autoCreateRepo(const svn_fs_path_change_t *change, const Rules::Match &rule, const QString &repository, const QString &branch);
int exportInternal(const char *path, const svn_fs_path_change_t *change,
const char *path_from, svn_revnum_t rev_from,
const QString &current, const Rules::Match &rule, const MatchRuleList &matchRules);
@@ -679,6 +680,31 @@ int SvnRevision::exportDispatch(const char *key, const svn_fs_path_change_t *cha
return EXIT_FAILURE;
}
+Repository* SvnRevision::autoCreateRepo(const svn_fs_path_change_t *change, const Rules::Match &rule, const QString &repository, const QString &branch)
+{
+ Repository *repo = NULL;
+ if (change->change_kind == svn_fs_path_change_delete) {
+ qCritical() << "Rule" << rule
+ << "references unknown repository" << repository;
+
+ return NULL;
+ }
+
+ // Attempt to auto create the repo
+ qWarning() << "Auto-creating repository" << repository << "with branch"
+ << branch << "at revision" << revnum << "due to rule match";
+
+ repo = new Repository(repository, branch, revnum);
+ if (!repo)
+ return NULL;
+ repositories->insert(repository, repo);
+
+ printf(".");
+ fflush(stdout);
+
+ return repo;
+}
+
int SvnRevision::exportInternal(const char *key, const svn_fs_path_change_t *change,
const char *path_from, svn_revnum_t rev_from,
const QString &current, const Rules::Match &rule, const MatchRuleList &matchRules)
@@ -688,34 +714,17 @@ int SvnRevision::exportInternal(const char *key, const svn_fs_path_change_t *cha
splitPathName(rule, current, &svnprefix, &repository, &branch, &path);
Repository *repo = repositories->value(repository, 0);
- if (!repo) {
- if (change->change_kind != svn_fs_path_change_delete) {
- // Attempt to auto create the repo
- qWarning() << "Auto-creating repository" << repository << "with branch"
- << branch << "at revision" << revnum << "due to rule match";
-
- repo = new Repository(repository, branch, revnum);
- if (!repo)
- return EXIT_FAILURE;
- repositories->insert(repository, repo);
-
- //repo->setupIncremental(INT_MAX);
- }
+// qDebug() << " " << qPrintable(current) << "rev" << revnum << "->"
+// << qPrintable(repository) << qPrintable(branch) << qPrintable(path);
+ if (change->change_kind == svn_fs_path_change_delete && current == svnprefix && path.isEmpty()) {
if (!repo) {
qCritical() << "Rule" << rule
<< "references unknown repository" << repository;
return EXIT_FAILURE;
}
- }
- printf(".");
- fflush(stdout);
-// qDebug() << " " << qPrintable(current) << "rev" << revnum << "->"
-// << qPrintable(repository) << qPrintable(branch) << qPrintable(path);
-
- if (change->change_kind == svn_fs_path_change_delete && current == svnprefix && path.isEmpty()) {
if(ruledebug)
qDebug() << "repository" << repository << "branch" << branch << "deleted";
@@ -724,7 +733,7 @@ int SvnRevision::exportInternal(const char *key, const svn_fs_path_change_t *cha
return repo->deleteBranch(branch, revnum);
}
- QString newreponame = repository + "-r" + QString::number(revnum);
+ QString newreponame = repository + "-r" + QString::number(revnum-1);
if (!repo->rename(newreponame))
return EXIT_FAILURE;
repositories->remove(repository);
@@ -755,6 +764,9 @@ int SvnRevision::exportInternal(const char *key, const svn_fs_path_change_t *cha
// current == svnprefix => we're dealing with the contents of the whole branch here
if (path_from != NULL && current == svnprefix && path.isEmpty()) {
if (previous != prevsvnprefix) {
+ if (!repo && !(repo = autoCreateRepo(change, rule, repository, branch)))
+ return EXIT_FAILURE;
+
// source is not the whole of its branch
qDebug() << qPrintable(current) << "is a partial branch of repository"
<< qPrintable(prevrepository) << "branch"
@@ -766,13 +778,35 @@ int SvnRevision::exportInternal(const char *key, const svn_fs_path_change_t *cha
<< qPrintable(prevrepository) << "branch"
<< qPrintable(prevbranch) << "path"
<< qPrintable(prevpath) << "rev" << rev_from << ")";
+
+ // Have we been copied from elsewhere?
+ QString renamed = prevrepository + "-r" + QString::number(rev_from);
+ if (!repo && "master" == prevbranch && QDir(renamed).exists()) {
+ qWarning() << "Found potential repository rename from" << renamed;
+ repo = repositories->value(renamed, 0);
+ if (!repo) {
+ qCritical() << "Cannot find repository" << renamed;
+ return EXIT_FAILURE;
+ }
+
+ if (!repo->rename(repository))
+ return EXIT_FAILURE;
+ repositories->remove(renamed);
+ repositories->insert(repository, repo);
+ }
} else if (path != prevpath) {
+ if (!repo && !(repo = autoCreateRepo(change, rule, repository, branch)))
+ return EXIT_FAILURE;
+
qDebug() << qPrintable(current)
<< "is a branch copy which renames base directory of all contents"
<< qPrintable(prevpath) << "to" << qPrintable(path);
// FIXME: Handle with fast-import 'file rename' facility
// ??? Might need special handling when path == / or prevpath == /
} else {
+ if (!repo && !(repo = autoCreateRepo(change, rule, repository, branch)))
+ return EXIT_FAILURE;
+
if (prevbranch == branch) {
// same branch and same repository
qDebug() << qPrintable(current) << "rev" << revnum
@@ -813,6 +847,10 @@ int SvnRevision::exportInternal(const char *key, const svn_fs_path_change_t *cha
return EXIT_SUCCESS;
}
}
+
+ if (!repo && !(repo = autoCreateRepo(change, rule, repository, branch)))
+ return EXIT_FAILURE;
+
Repository::Transaction *txn = transactions.value(repository + branch, 0);
if (!txn) {
txn = repo->newTransaction(branch, svnprefix, revnum);