aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main.cpp68
-rw-r--r--src/repository.cpp262
-rw-r--r--src/repository.h12
-rw-r--r--src/svn.cpp179
4 files changed, 282 insertions, 239 deletions
diff --git a/src/main.cpp b/src/main.cpp
index f2b189e..73d2378 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -127,48 +127,48 @@ int main(int argc, char **argv)
retry:
int min_rev = 1;
foreach (Rules::Repository rule, rules.repositories()) {
- Repository *repo = makeRepository(rule, repositories);
- if (!repo)
- return EXIT_FAILURE;
+ Repository *repo = makeRepository(rule, repositories);
+ if (!repo)
+ return EXIT_FAILURE;
repositories.insert(rule.name, repo);
- int repo_next = repo->setupIncremental(cutoff);
-
- /*
- * cutoff < resume_from => error exit eventually
- * repo_next == cutoff => probably truncated log
- */
- if (cutoff < resume_from && repo_next == cutoff)
- /*
- * Restore the log file so we fail the next time
- * svn2git is invoked with the same arguments
- */
- repo->restoreLog();
-
- if (cutoff < min_rev)
- /*
- * We've rewound before the last revision of some
- * repository that we've already seen. Start over
- * from the beginning. (since cutoff is decreasing,
- * we're sure we'll make forward progress eventually)
- */
- goto retry;
-
- if (min_rev < repo_next)
- min_rev = repo_next;
+ int repo_next = repo->setupIncremental(cutoff);
+
+ /*
+ * cutoff < resume_from => error exit eventually
+ * repo_next == cutoff => probably truncated log
+ */
+ if (cutoff < resume_from && repo_next == cutoff)
+ /*
+ * Restore the log file so we fail the next time
+ * svn2git is invoked with the same arguments
+ */
+ repo->restoreLog();
+
+ if (cutoff < min_rev)
+ /*
+ * We've rewound before the last revision of some
+ * repository that we've already seen. Start over
+ * from the beginning. (since cutoff is decreasing,
+ * we're sure we'll make forward progress eventually)
+ */
+ goto retry;
+
+ if (min_rev < repo_next)
+ min_rev = repo_next;
}
if (cutoff < resume_from) {
- qCritical() << "Cannot resume from" << resume_from
- << "as there are errors in revision" << cutoff;
- return EXIT_FAILURE;
+ qCritical() << "Cannot resume from" << resume_from
+ << "as there are errors in revision" << cutoff;
+ return EXIT_FAILURE;
}
if (min_rev < resume_from)
- qDebug() << "skipping revisions" << min_rev << "to" << resume_from - 1 << "as requested";
+ qDebug() << "skipping revisions" << min_rev << "to" << resume_from - 1 << "as requested";
if (resume_from)
- min_rev = resume_from;
+ min_rev = resume_from;
Svn::initialize();
Svn svn(args->arguments().first());
@@ -182,9 +182,9 @@ int main(int argc, char **argv)
bool errors = false;
for (int i = min_rev; i <= max_rev; ++i) {
if (!svn.exportRevision(i)) {
- errors = true;
+ errors = true;
break;
- }
+ }
}
foreach (Repository *repo, repositories) {
diff --git a/src/repository.cpp b/src/repository.cpp
index 5bcd8dd..ab2a7de 100644
--- a/src/repository.cpp
+++ b/src/repository.cpp
@@ -43,7 +43,7 @@ public:
uint datetime;
int revnum;
- QVector<int> merges;
+ QVector<int> merges;
QStringList deletedFiles;
QByteArray modifiedFiles;
@@ -57,7 +57,7 @@ public:
void setDateTime(uint dt);
void setLog(const QByteArray &log);
- void noteCopyFromBranch (const QString &prevbranch, int revFrom);
+ void noteCopyFromBranch (const QString &prevbranch, int revFrom);
void deleteFile(const QString &path);
QIODevice *addFile(const QString &path, int mode, qint64 length);
@@ -69,7 +69,7 @@ public:
void reloadBranches();
int createBranch(const QString &branch, int revnum,
- const QString &branchFrom, int revFrom);
+ const QString &branchFrom, int revFrom);
int deleteBranch(const QString &branch, int revnum);
Repository::Transaction *newTransaction(const QString &branch, const QString &svnprefix, int revnum);
@@ -83,7 +83,7 @@ private:
{
int created;
QVector<int> commits;
- QVector<int> marks;
+ QVector<int> marks;
};
struct AnnotatedTag
{
@@ -132,19 +132,19 @@ public:
{
Q_DISABLE_COPY(Transaction)
- Repository::Transaction *txn;
- QString prefix;
+ Repository::Transaction *txn;
+ QString prefix;
public:
- Transaction(Repository::Transaction *t, const QString &p) : txn(t), prefix(p) {}
- ~Transaction() { delete txn; }
+ Transaction(Repository::Transaction *t, const QString &p) : txn(t), prefix(p) {}
+ ~Transaction() { delete txn; }
void commit() { txn->commit(); }
void setAuthor(const QByteArray &author) { txn->setAuthor(author); }
void setDateTime(uint dt) { txn->setDateTime(dt); }
void setLog(const QByteArray &log) { txn->setLog(log); }
- void noteCopyFromBranch (const QString &prevbranch, int revFrom)
- { txn->noteCopyFromBranch(prevbranch, revFrom); }
+ void noteCopyFromBranch (const QString &prevbranch, int revFrom)
+ { txn->noteCopyFromBranch(prevbranch, revFrom); }
void deleteFile(const QString &path) { txn->deleteFile(prefix + path); }
QIODevice *addFile(const QString &path, int mode, qint64 length)
@@ -157,7 +157,7 @@ public:
void restoreLog() {}
int createBranch(const QString &branch, int revnum,
- const QString &branchFrom, int revFrom)
+ const QString &branchFrom, int revFrom)
{ return repo->createBranch(branch, revnum, branchFrom, revFrom); }
int deleteBranch(const QString &branch, int revnum)
@@ -165,13 +165,13 @@ public:
Repository::Transaction *newTransaction(const QString &branch, const QString &svnprefix, int revnum)
{
- Repository::Transaction *t = repo->newTransaction(branch, svnprefix, revnum);
- return new Transaction(t, prefix);
+ Repository::Transaction *t = repo->newTransaction(branch, svnprefix, revnum);
+ return new Transaction(t, prefix);
}
void createAnnotatedTag(const QString &name, const QString &svnprefix, int revnum,
- const QByteArray &author, uint dt,
- const QByteArray &log)
+ const QByteArray &author, uint dt,
+ const QByteArray &log)
{ repo->createAnnotatedTag(name, svnprefix, revnum, author, dt, log); }
void finalizeTags() { /* loop that called this will invoke it on 'repo' too */ }
};
@@ -205,11 +205,11 @@ static ProcessCache processCache;
Repository *makeRepository(const Rules::Repository &rule, const QHash<QString, Repository *> &repositories)
{
if (rule.forwardTo.isEmpty())
- return new FastImportRepository(rule);
+ return new FastImportRepository(rule);
Repository *r = repositories[rule.forwardTo];
if (!r) {
- qCritical() << "no repository with name" << rule.forwardTo << "found at line" << rule.lineNumber;
- return r;
+ qCritical() << "no repository with name" << rule.forwardTo << "found at line" << rule.lineNumber;
+ return r;
}
return new PrefixingRepository(r, rule.prefix);
}
@@ -243,11 +243,11 @@ FastImportRepository::FastImportRepository(const Rules::Repository &rule)
init.setWorkingDirectory(name);
init.start("git", QStringList() << "--bare" << "init");
init.waitForFinished(-1);
- {
- QFile marks(name + "/" + marksFileName(name));
- marks.open(QIODevice::WriteOnly);
- marks.close();
- }
+ {
+ QFile marks(name + "/" + marksFileName(name));
+ marks.open(QIODevice::WriteOnly);
+ marks.close();
+ }
}
}
}
@@ -263,45 +263,45 @@ static int lastValidMark(QString name)
{
QFile marksfile(name + "/" + marksFileName(name));
if (!marksfile.open(QIODevice::ReadOnly))
- return 0;
+ return 0;
int prev_mark = 0;
int lineno = 0;
while (!marksfile.atEnd()) {
- QString line = marksfile.readLine();
- ++lineno;
- if (line.isEmpty())
- continue;
-
- int mark = 0;
- if (line[0] == ':') {
- int sp = line.indexOf(' ');
- if (sp != -1) {
- QString m = line.mid(1, sp-1);
- mark = m.toInt();
- }
- }
-
- if (!mark) {
- qCritical() << marksfile.fileName() << "line" << lineno << "marks file corrupt?";
- return 0;
- }
-
- if (mark == prev_mark) {
- qCritical() << marksfile.fileName() << "line" << lineno << "marks file has duplicates";
- return 0;
- }
-
- if (mark < prev_mark) {
- qCritical() << marksfile.fileName() << "line" << lineno << "marks file not sorted";
- return 0;
- }
-
- if (mark > prev_mark + 1)
- break;
-
- prev_mark = mark;
+ QString line = marksfile.readLine();
+ ++lineno;
+ if (line.isEmpty())
+ continue;
+
+ int mark = 0;
+ if (line[0] == ':') {
+ int sp = line.indexOf(' ');
+ if (sp != -1) {
+ QString m = line.mid(1, sp-1);
+ mark = m.toInt();
+ }
+ }
+
+ if (!mark) {
+ qCritical() << marksfile.fileName() << "line" << lineno << "marks file corrupt?";
+ return 0;
+ }
+
+ if (mark == prev_mark) {
+ qCritical() << marksfile.fileName() << "line" << lineno << "marks file has duplicates";
+ return 0;
+ }
+
+ if (mark < prev_mark) {
+ qCritical() << marksfile.fileName() << "line" << lineno << "marks file not sorted";
+ return 0;
+ }
+
+ if (mark > prev_mark + 1)
+ break;
+
+ prev_mark = mark;
}
return prev_mark;
@@ -341,26 +341,26 @@ int FastImportRepository::setupIncremental(int &cutoff)
int mark = progress.cap(3).toInt();
if (revnum >= cutoff)
- goto beyond_cutoff;
+ goto beyond_cutoff;
if (revnum < last_revnum)
qWarning() << name << "revision numbers are not monotonic: "
<< "got" << QString::number(last_revnum)
<< "and then" << QString::number(revnum);
- if (mark > last_valid_mark) {
- qWarning() << name << "unknown commit mark found: rewinding -- did you hit Ctrl-C?";
- cutoff = revnum;
- goto beyond_cutoff;
- }
+ if (mark > last_valid_mark) {
+ qWarning() << name << "unknown commit mark found: rewinding -- did you hit Ctrl-C?";
+ cutoff = revnum;
+ goto beyond_cutoff;
+ }
last_revnum = revnum;
- if (last_commit_mark < mark)
- last_commit_mark = mark;
+ if (last_commit_mark < mark)
+ last_commit_mark = mark;
Branch &br = branches[branch];
- if (!br.created || !mark || !br.marks.last())
+ if (!br.created || !mark || br.marks.isEmpty())
br.created = revnum;
br.commits.append(revnum);
br.marks.append(mark);
@@ -368,11 +368,11 @@ int FastImportRepository::setupIncremental(int &cutoff)
retval = last_revnum + 1;
if (retval == cutoff)
- /*
- * If a stale backup file exists already, remove it, so that
- * we don't confuse ourselves in 'restoreLog()'
- */
- QFile::remove(bkup);
+ /*
+ * If a stale backup file exists already, remove it, so that
+ * we don't confuse ourselves in 'restoreLog()'
+ */
+ QFile::remove(bkup);
return retval;
@@ -392,7 +392,7 @@ void FastImportRepository::restoreLog()
QString file = logFileName(name);
QString bkup = file + ".old";
if (!QFile::exists(bkup))
- return;
+ return;
QFile::remove(file);
QFile::rename(bkup, file);
}
@@ -425,15 +425,15 @@ void FastImportRepository::reloadBranches()
Branch &br = branches[branch];
if (!br.marks.count() || !br.marks.last())
- continue;
+ continue;
QByteArray branchRef = branch.toUtf8();
if (!branchRef.startsWith("refs/"))
branchRef.prepend("refs/heads/");
- fastImport.write("reset " + branchRef +
- "\nfrom :" + QByteArray::number(br.marks.last()) + "\n\n"
- "progress Branch " + branchRef + " reloaded\n");
+ fastImport.write("reset " + branchRef +
+ "\nfrom :" + QByteArray::number(br.marks.last()) + "\n\n"
+ "progress Branch " + branchRef + " reloaded\n");
}
}
@@ -441,28 +441,34 @@ int FastImportRepository::markFrom(const QString &branchFrom, int branchRevNum,
{
Branch &brFrom = branches[branchFrom];
if (!brFrom.created)
- return -1;
+ return -1;
- if (branchRevNum == brFrom.commits.last())
- return brFrom.marks.last();
+ if (brFrom.commits.isEmpty()) {
+ return -1;
+ }
+ if (branchRevNum == brFrom.commits.last()) {
+ return brFrom.marks.last();
+ }
QVector<int>::const_iterator it = qUpperBound(brFrom.commits, branchRevNum);
- if (it == brFrom.commits.begin())
- return 0;
+ if (it == brFrom.commits.begin()) {
+ return 0;
+ }
int closestCommit = *--it;
if (!branchFromDesc.isEmpty()) {
- branchFromDesc += " at r" + QByteArray::number(branchRevNum);
- if (closestCommit != branchRevNum)
- branchFromDesc += " => r" + QByteArray::number(closestCommit);
+ branchFromDesc += " at r" + QByteArray::number(branchRevNum);
+ if (closestCommit != branchRevNum) {
+ branchFromDesc += " => r" + QByteArray::number(closestCommit);
+ }
}
return brFrom.marks[it - brFrom.commits.begin()];
}
int FastImportRepository::createBranch(const QString &branch, int revnum,
- const QString &branchFrom, int branchRevNum)
+ const QString &branchFrom, int branchRevNum)
{
startFastImport();
if (!branches.contains(branch)) {
@@ -477,7 +483,7 @@ int FastImportRepository::createBranch(const QString &branch, int revnum,
qCritical() << branch << "in repository" << name
<< "is branching from branch" << branchFrom
<< "but the latter doesn't exist. Can't continue.";
- return EXIT_FAILURE;
+ return EXIT_FAILURE;
}
QByteArray branchFromRef = ":" + QByteArray::number(mark);
@@ -487,9 +493,11 @@ int FastImportRepository::createBranch(const QString &branch, int revnum,
branchFromRef = branchFrom.toUtf8();
if (!branchFromRef.startsWith("refs/"))
branchFromRef.prepend("refs/heads/");
- branchFromDesc += ", deleted/unknown";
+ branchFromDesc += ", deleted/unknown";
}
+ qDebug() << "Creating branch:" << branch << "from" << branchFrom << "(" << branchRevNum << branchFromDesc << ")";
+
return resetBranch(branch, revnum, mark, branchFromRef, branchFromDesc);
}
@@ -505,7 +513,7 @@ int FastImportRepository::resetBranch(const QString &branch, int revnum, int mar
{
QByteArray branchRef = branch.toUtf8();
if (!branchRef.startsWith("refs/"))
- branchRef.prepend("refs/heads/");
+ branchRef.prepend("refs/heads/");
Branch &br = branches[branch];
if (br.created && br.created != revnum && br.marks.last()) {
@@ -520,9 +528,9 @@ int FastImportRepository::resetBranch(const QString &branch, int revnum, int mar
br.marks.append(mark);
fastImport.write("reset " + branchRef + "\nfrom " + resetTo + "\n\n"
- "progress SVN r" + QByteArray::number(revnum)
- + " branch " + branch.toUtf8() + " = :" + QByteArray::number(mark)
- + " # " + comment + "\n\n");
+ "progress SVN r" + QByteArray::number(revnum)
+ + " branch " + branch.toUtf8() + " = :" + QByteArray::number(mark)
+ + " # " + comment + "\n\n");
return EXIT_SUCCESS;
}
@@ -543,9 +551,11 @@ Repository::Transaction *FastImportRepository::newTransaction(const QString &bra
txn->datetime = 0;
txn->revnum = revnum;
- if ((++commitCount % CommandLineParser::instance()->optionArgument(QLatin1String("commit-interval"), QLatin1String("10000")).toInt()) == 0)
+ if ((++commitCount % CommandLineParser::instance()->optionArgument(QLatin1String("commit-interval"), QLatin1String("10000")).toInt()) == 0) {
// write everything to disk every 10000 commits
fastImport.write("checkpoint\n");
+ qDebug() << "checkpoint!, marks file trunkated";
+ }
outstandingTransactions++;
return txn;
}
@@ -675,6 +685,10 @@ void FastImportRepository::Transaction::setLog(const QByteArray &l)
void FastImportRepository::Transaction::noteCopyFromBranch(const QString &branchFrom, int branchRevNum)
{
+ //if(branch == branchFrom) {
+ // qWarning() << "Cannot merge inside a branch";
+ // return;
+ //}
static QByteArray dummy;
int mark = repository->markFrom(branchFrom, branchRevNum, dummy);
Q_ASSERT(dummy.isEmpty());
@@ -683,13 +697,17 @@ void FastImportRepository::Transaction::noteCopyFromBranch(const QString &branch
qWarning() << branch << "is copying from branch" << branchFrom
<< "but the latter doesn't exist. Continuing, assuming the files exist.";
} else if (mark == 0) {
- qWarning() << "Unknown revision r" << QByteArray::number(branchRevNum)
- << ". Continuing, assuming the files exist.";
+ qWarning() << "Unknown revision r" << QByteArray::number(branchRevNum)
+ << ". Continuing, assuming the files exist.";
} else {
- qWarning() << "repository " + repository->name + " branch " + branch + " has some files copied from " + branchFrom + "@" + QByteArray::number(branchRevNum);
+ qWarning() << "repository " + repository->name + " branch " + branch + " has some files copied from " + branchFrom + "@" + QByteArray::number(branchRevNum);
- if (!merges.contains(mark))
- merges.append(mark);
+ if (!merges.contains(mark)) {
+ merges.append(mark);
+ qDebug() << "adding" << branchFrom + "@" + QByteArray::number(branchRevNum) << ":" << mark << "as a merge point";
+ } else {
+ qDebug() << "merge point already recorded";
+ }
}
}
@@ -750,12 +768,12 @@ void FastImportRepository::Transaction::commit()
int parentmark = 0;
Branch &br = repository->branches[branch];
- if (br.created) {
- parentmark = br.marks.last();
+ if (br.created && !br.marks.isEmpty()) {
+ parentmark = br.marks.last();
} else {
- qWarning() << "Branch" << branch << "in repository" << repository->name << "doesn't exist at revision"
- << revnum << "-- did you resume from the wrong revision?";
- br.created = revnum;
+ qWarning() << "Branch" << branch << "in repository" << repository->name << "doesn't exist at revision"
+ << revnum << "-- did you resume from the wrong revision?";
+ br.created = revnum;
}
br.commits.append(revnum);
br.marks.append(mark);
@@ -780,23 +798,25 @@ void FastImportRepository::Transaction::commit()
QByteArray desc = "";
int i = !!parentmark; // if parentmark != 0, there's at least one parent
foreach (int merge, merges) {
- if (merge == parentmark)
- continue;
-
- if (++i > 16) {
- // FIXME: options:
- // (1) ignore the 16 parent limit
- // (2) don't emit more than 16 parents
- // (3) create another commit on branch to soak up additional parents
- // we've chosen option (2) for now, since only artificial commits
- // created by cvs2svn seem to have this issue
- qWarning() << "too many merge parents";
- break;
- }
-
- QByteArray m = " :" + QByteArray::number(merge);
- desc += m;
- repository->fastImport.write("merge" + m + "\n");
+ if (merge == parentmark) {
+ qDebug() << "Skipping marking" << merge << "as a merge point as it matches the parent";
+ continue;
+ }
+
+ if (++i > 16) {
+ // FIXME: options:
+ // (1) ignore the 16 parent limit
+ // (2) don't emit more than 16 parents
+ // (3) create another commit on branch to soak up additional parents
+ // we've chosen option (2) for now, since only artificial commits
+ // created by cvs2svn seem to have this issue
+ qWarning() << "too many merge parents";
+ break;
+ }
+
+ QByteArray m = " :" + QByteArray::number(merge);
+ desc += m;
+ repository->fastImport.write("merge" + m + "\n");
}
// write the file deletions
@@ -811,8 +831,8 @@ void FastImportRepository::Transaction::commit()
repository->fastImport.write("\nprogress SVN r" + QByteArray::number(revnum)
+ " branch " + branch + " = :" + QByteArray::number(mark)
- + (desc.isEmpty() ? "" : " # merge from") + desc
- + "\n\n");
+ + (desc.isEmpty() ? "" : " # merge from") + desc
+ + "\n\n");
printf(" %d modifications from SVN %s to %s/%s",
deletedFiles.count() + modifiedFiles.count(), svnprefix.data(),
qPrintable(repository->name), branch.data());
diff --git a/src/repository.h b/src/repository.h
index e07d184..a4532ab 100644
--- a/src/repository.h
+++ b/src/repository.h
@@ -31,16 +31,16 @@ public:
{
Q_DISABLE_COPY(Transaction)
protected:
- Transaction() {}
+ Transaction() {}
public:
- virtual ~Transaction() {}
+ virtual ~Transaction() {}
virtual void commit() = 0;
virtual void setAuthor(const QByteArray &author) = 0;
virtual void setDateTime(uint dt) = 0;
virtual void setLog(const QByteArray &log) = 0;
- virtual void noteCopyFromBranch (const QString &prevbranch, int revFrom) = 0;
+ virtual void noteCopyFromBranch (const QString &prevbranch, int revFrom) = 0;
virtual void deleteFile(const QString &path) = 0;
virtual QIODevice *addFile(const QString &path, int mode, qint64 length) = 0;
@@ -50,13 +50,13 @@ public:
virtual ~Repository() {}
virtual int createBranch(const QString &branch, int revnum,
- const QString &branchFrom, int revFrom) = 0;
+ const QString &branchFrom, int revFrom) = 0;
virtual int deleteBranch(const QString &branch, int revnum) = 0;
virtual Transaction *newTransaction(const QString &branch, const QString &svnprefix, int revnum) = 0;
virtual void createAnnotatedTag(const QString &name, const QString &svnprefix, int revnum,
- const QByteArray &author, uint dt,
- const QByteArray &log) = 0;
+ const QByteArray &author, uint dt,
+ const QByteArray &log) = 0;
virtual void finalizeTags() = 0;
};
diff --git a/src/svn.cpp b/src/svn.cpp
index 594a750..55b8b50 100644
--- a/src/svn.cpp
+++ b/src/svn.cpp
@@ -382,10 +382,12 @@ public:
QByteArray authorident;
QByteArray log;
uint epoch;
+ bool ruledebug;
SvnRevision(int revision, svn_fs_t *f, apr_pool_t *parent_pool)
: pool(parent_pool), fs(f), fs_root(0), revnum(revision)
{
+ ruledebug = CommandLineParser::instance()->contains( QLatin1String("debug-rules"));
}
int open()
@@ -531,16 +533,16 @@ int SvnRevision::exportEntry(const char *key, const svn_fs_path_change_t *change
qCritical() << " " << key << "was reset, panic!";
return EXIT_FAILURE;
} else {
- // if change_kind == delete, it shouldn't come into this arm of the 'is_dir' test
+ // if change_kind == delete, it shouldn't come into this arm of the 'is_dir' test
qCritical() << " " << key << "has unhandled change kind " << change->change_kind << ", panic!";
return EXIT_FAILURE;
}
} else if (change->change_kind == svn_fs_path_change_delete) {
- is_dir = wasDir(fs, revnum - 1, key, revpool);
+ is_dir = wasDir(fs, revnum - 1, key, revpool);
}
if (is_dir)
- current += '/';
+ current += '/';
// find the first rule that matches this pathname
MatchRuleList::ConstIterator match = findMatchRule(matchRules, revnum, current);
@@ -553,8 +555,8 @@ int SvnRevision::exportEntry(const char *key, const svn_fs_path_change_t *change
qDebug() << current << "is a copy-with-history, auto-recursing";
return recurse(key, change, path_from, rev_from, changes, revpool);
} else if (is_dir && change->change_kind == svn_fs_path_change_delete) {
- qDebug() << current << "deleted, auto-recursing";
- return recurse(key, change, path_from, rev_from, changes, revpool);
+ qDebug() << current << "deleted, auto-recursing";
+ return recurse(key, change, path_from, rev_from, changes, revpool);
} else if (wasDir(fs, revnum - 1, key, revpool)) {
qDebug() << current << "was a directory; ignoring";
} else if (change->change_kind == svn_fs_path_change_delete) {
@@ -572,27 +574,33 @@ int SvnRevision::exportDispatch(const char *key, const svn_fs_path_change_t *cha
apr_hash_t *changes, const QString &current,
const Rules::Match &rule, apr_pool_t *pool)
{
- if(CommandLineParser::instance()->contains( QLatin1String("debug-rules")))
- qDebug() << " " << qPrintable(current) << "matched rule:" << rule.lineNumber << "(" << rule.rx.pattern() << ")";
+ //if(ruledebug)
+ // qDebug() << "rev" << revnum << qPrintable(current) << "matched rule:" << rule.lineNumber << "(" << rule.rx.pattern() << ")";
switch (rule.action) {
case Rules::Match::Ignore:
- // ignore rule
- //qDebug() << " " << qPrintable(current) << "rev" << revnum
- // << "-> ignored (rule" << rule << ")";
+ //if(ruledebug)
+ // qDebug() << " " << "ignoring.";
return EXIT_SUCCESS;
case Rules::Match::Recurse:
+ if(ruledebug)
+ qDebug() << "rev" << revnum << qPrintable(current) << "matched rule:" << rule.lineNumber << "(" << rule.rx.pattern() << ")" << " " << "recursing.";
return recurse(key, change, path_from, rev_from, changes, pool);
case Rules::Match::Export:
+ if(ruledebug)
+ qDebug() << "rev" << revnum << qPrintable(current) << "matched rule:" << rule.lineNumber << "(" << rule.rx.pattern() << ")" << " " << "exporting.";
if (exportInternal(key, change, path_from, rev_from, current, rule) == EXIT_SUCCESS)
- return EXIT_SUCCESS;
- if (change->change_kind != svn_fs_path_change_delete)
- return EXIT_FAILURE;
- // we know that the default action inside recurse is to recurse further or to ignore,
- // either of which is reasonably safe for deletion
- qWarning() << "deleting unknown path" << current << "; auto-recursing";
- return recurse(key, change, path_from, rev_from, changes, pool);
+ return EXIT_SUCCESS;
+ if (change->change_kind != svn_fs_path_change_delete) {
+ if(ruledebug)
+ qDebug() << "rev" << revnum << qPrintable(current) << "matched rule:" << rule.lineNumber << "(" << rule.rx.pattern() << ")" << " " << "Unable to export non path removal.";
+ return EXIT_FAILURE;
+ }
+ // we know that the default action inside recurse is to recurse further or to ignore,
+ // either of which is reasonably safe for deletion
+ qWarning() << "deleting unknown path" << current << "; auto-recursing";
+ return recurse(key, change, path_from, rev_from, changes, pool);
}
// never reached
@@ -608,10 +616,10 @@ int SvnRevision::exportInternal(const char *key, const svn_fs_path_change_t *cha
Repository *repo = repositories.value(repository, 0);
if (!repo) {
- if (change->change_kind != svn_fs_path_change_delete)
- qCritical() << "Rule" << rule
- << "references unknown repository" << repository;
- return EXIT_FAILURE;
+ if (change->change_kind != svn_fs_path_change_delete)
+ qCritical() << "Rule" << rule
+ << "references unknown repository" << repository;
+ return EXIT_FAILURE;
}
printf(".");
@@ -620,69 +628,72 @@ int SvnRevision::exportInternal(const char *key, const svn_fs_path_change_t *cha
// << qPrintable(repository) << qPrintable(branch) << qPrintable(path);
if (change->change_kind == svn_fs_path_change_delete && current == svnprefix) {
- qDebug() << "repository" << repository << "branch" << branch << "deleted";
- return repo->deleteBranch(branch, revnum);
+ if(ruledebug)
+ qDebug() << "repository" << repository << "branch" << branch << "deleted";
+ return repo->deleteBranch(branch, revnum);
}
QString previous;
QString prevsvnprefix, prevrepository, prevbranch, prevpath;
if (path_from != NULL) {
- previous = QString::fromUtf8(path_from) + '/';
+ previous = QString::fromUtf8(path_from) + '/';
MatchRuleList::ConstIterator prevmatch =
findMatchRule(matchRules, rev_from, previous, NoIgnoreRule);
- if (prevmatch != matchRules.constEnd())
+ if (prevmatch != matchRules.constEnd()) {
splitPathName(*prevmatch, previous, &prevsvnprefix, &prevrepository,
&prevbranch, &prevpath);
- else
- path_from = NULL;
+ } else {
+ qWarning() << "SVN reports a \"copy from\" but no matching rules found! Ignoring copy, treating as a modification";
+ path_from = NULL;
+ }
}
// current == svnprefix => we're dealing with the contents of the whole branch here
if (path_from != NULL && current == svnprefix) {
- if (previous != prevsvnprefix) {
- // source is not the whole of its branch
- qDebug() << qPrintable(current) << "is a partial branch of repository"
- << qPrintable(prevrepository) << "branch"
- << qPrintable(prevbranch) << "subdir"
- << qPrintable(prevpath);
- } else if (prevrepository != repository) {
- qWarning() << qPrintable(current) << "rev" << revnum
- << "is a cross-repository copy (from repository"
- << qPrintable(prevrepository) << "branch"
- << qPrintable(prevbranch) << "path"
- << qPrintable(prevpath) << "rev" << rev_from << ")";
- } else if (path != prevpath) {
- 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 (prevbranch == branch) {
- // same branch and same repository
- qDebug() << qPrintable(current) << "rev" << revnum
- << "is reseating branch" << qPrintable(branch)
- << "to an earlier revision"
- << qPrintable(previous) << "rev" << rev_from;
- } else {
- // same repository but not same branch
- // this means this is a plain branch
- qDebug() << qPrintable(repository) << ": branch"
- << qPrintable(branch) << "is branching from"
- << qPrintable(prevbranch);
- }
-
- if (repo->createBranch(branch, revnum, prevbranch, rev_from) == EXIT_FAILURE)
- return EXIT_FAILURE;
- if (rule.annotate) {
- // create an annotated tag
- fetchRevProps();
- repo->createAnnotatedTag(branch, svnprefix, revnum, authorident,
- epoch, log);
- }
- return EXIT_SUCCESS;
- }
+ if (previous != prevsvnprefix) {
+ // source is not the whole of its branch
+ qDebug() << qPrintable(current) << "is a partial branch of repository"
+ << qPrintable(prevrepository) << "branch"
+ << qPrintable(prevbranch) << "subdir"
+ << qPrintable(prevpath);
+ } else if (prevrepository != repository) {
+ qWarning() << qPrintable(current) << "rev" << revnum
+ << "is a cross-repository copy (from repository"
+ << qPrintable(prevrepository) << "branch"
+ << qPrintable(prevbranch) << "path"
+ << qPrintable(prevpath) << "rev" << rev_from << ")";
+ } else if (path != prevpath) {
+ 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 (prevbranch == branch) {
+ // same branch and same repository
+ qDebug() << qPrintable(current) << "rev" << revnum
+ << "is reseating branch" << qPrintable(branch)
+ << "to an earlier revision"
+ << qPrintable(previous) << "rev" << rev_from;
+ } else {
+ // same repository but not same branch
+ // this means this is a plain branch
+ qDebug() << qPrintable(repository) << ": branch"
+ << qPrintable(branch) << "is branching from"
+ << qPrintable(prevbranch);
+ }
+
+ if (repo->createBranch(branch, revnum, prevbranch, rev_from) == EXIT_FAILURE)
+ return EXIT_FAILURE;
+ if (rule.annotate) {
+ // create an annotated tag
+ fetchRevProps();
+ repo->createAnnotatedTag(branch, svnprefix, revnum, authorident,
+ epoch, log);
+ }
+ return EXIT_SUCCESS;
+ }
}
Repository::Transaction *txn = transactions.value(repository + branch, 0);
if (!txn) {
@@ -699,16 +710,28 @@ int SvnRevision::exportInternal(const char *key, const svn_fs_path_change_t *cha
// changes across directory re-organizations and wholesale branch
// imports.
//
- if (path_from != NULL && prevrepository == repository)
- txn->noteCopyFromBranch (prevbranch, rev_from);
+ if (path_from != NULL && prevrepository == repository) {
+ if(ruledebug)
+ qDebug() << "copy from branch" << prevbranch << "rev" << rev_from;
+ txn->noteCopyFromBranch (prevbranch, rev_from);
+ }
- if (change->change_kind == svn_fs_path_change_replace && path_from == NULL)
+ if (change->change_kind == svn_fs_path_change_replace && path_from == NULL) {
+ if(ruledebug)
+ qDebug() << "replaced with empty path";
txn->deleteFile(path);
+ }
if (change->change_kind == svn_fs_path_change_delete) {
+ if(ruledebug)
+ qDebug() << "delete";
txn->deleteFile(path);
} else if (!current.endsWith('/')) {
+ if(ruledebug)
+ qDebug() << "add/change file (" << key << "->" << path << ")";
dumpBlob(txn, fs_root, key, path, pool);
} else {
+ if(ruledebug)
+ qDebug() << "add/change dir (" << key << "->" << path << ")";
txn->deleteFile(path);
recursiveDumpDir(txn, fs_root, key, path, pool);
}
@@ -722,7 +745,7 @@ int SvnRevision::recurse(const char *path, const svn_fs_path_change_t *change,
{
svn_fs_root_t *fs_root = this->fs_root;
if (change->change_kind == svn_fs_path_change_delete)
- SVN_ERR(svn_fs_revision_root(&fs_root, fs, revnum - 1, pool));
+ SVN_ERR(svn_fs_revision_root(&fs_root, fs, revnum - 1, pool));
// get the dir listing
apr_hash_t *entries;
@@ -765,10 +788,10 @@ int SvnRevision::recurse(const char *path, const svn_fs_path_change_t *change,
return EXIT_FAILURE;
} else {
qDebug() << current << "rev" << revnum
- << "did not match any rules; auto-recursing";
- if (recurse(entry, change, entryFrom.isNull() ? 0 : entryFrom.constData(),
- rev_from, changes, dirpool) == EXIT_FAILURE)
- return EXIT_FAILURE;
+ << "did not match any rules; auto-recursing";
+ if (recurse(entry, change, entryFrom.isNull() ? 0 : entryFrom.constData(),
+ rev_from, changes, dirpool) == EXIT_FAILURE)
+ return EXIT_FAILURE;
}
}