aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);