diff options
-rw-r--r-- | src/main.cpp | 44 | ||||
-rw-r--r-- | src/repository.cpp | 28 | ||||
-rw-r--r-- | src/repository.h | 1 |
3 files changed, 54 insertions, 19 deletions
diff --git a/src/main.cpp b/src/main.cpp index 5d0a1fc..37b8615 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -123,34 +123,50 @@ int main(int argc, char **argv) int cutoff = resume_from ? resume_from : INT_MAX; retry: - int min_rev = 0; + int min_rev = 1; foreach (Rules::Repository rule, rules.repositories()) { Repository *repo = new Repository(rule); repositories.insert(rule.name, repo); if (incremental) { int repo_next = repo->setupIncremental(cutoff); - if (cutoff < min_rev) { - qWarning() << "rewinding; did you hit Ctrl-C?"; + + /* + * 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 (incremental && resume_from) { - if (cutoff < resume_from) { - 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"; - min_rev = resume_from; + if (cutoff < resume_from) { + qCritical() << "Cannot resume from" << resume_from + << "as there are errors in revision" << cutoff; + return EXIT_FAILURE; } - if (min_rev < 1) - min_rev = 1; + if (min_rev < resume_from) + qDebug() << "skipping revisions" << min_rev << "to" << resume_from - 1 << "as requested"; + + if (resume_from) + min_rev = resume_from; Svn::initialize(); Svn svn(args->arguments().first()); diff --git a/src/repository.cpp b/src/repository.cpp index f57cdbb..57db6c7 100644 --- a/src/repository.cpp +++ b/src/repository.cpp @@ -154,6 +154,8 @@ int Repository::setupIncremental(int &cutoff) int last_revnum = 0; qint64 pos = 0; + int retval = 0; + QString bkup = logfile.fileName() + ".old"; while (!logfile.atEnd()) { pos = logfile.pos(); @@ -179,9 +181,8 @@ int Repository::setupIncremental(int &cutoff) << "got" << QString::number(last_revnum) << "and then" << QString::number(revnum); - if (mark > last_valid_mark) { - qWarning() << name << "unknown commit mark found: rewinding"; + qWarning() << name << "unknown commit mark found: rewinding -- did you hit Ctrl-C?"; cutoff = revnum; goto beyond_cutoff; } @@ -198,20 +199,37 @@ int Repository::setupIncremental(int &cutoff) br.marks.append(mark); } - return last_revnum + 1; + 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); + + return retval; beyond_cutoff: // backup file, since we'll truncate - QString bkup = logfile.fileName() + ".old"; QFile::remove(bkup); logfile.copy(bkup); // truncate, so that we ignore the rest of the revisions - qDebug() << name << "truncating history to" << cutoff; + qDebug() << name << "truncating history to revision" << cutoff; logfile.resize(pos); return cutoff; } +void Repository::restoreLog() +{ + QString file = logFileName(name); + QString bkup = file + ".old"; + if (!QFile::exists(bkup)) + return; + QFile::remove(file); + QFile::rename(bkup, file); +} + Repository::~Repository() { Q_ASSERT(outstandingTransactions == 0); diff --git a/src/repository.h b/src/repository.h index 9c2447f..44a6c14 100644 --- a/src/repository.h +++ b/src/repository.h @@ -61,6 +61,7 @@ public: }; Repository(const Rules::Repository &rule); int setupIncremental(int &cutoff); + void restoreLog(); ~Repository(); void reloadBranches(); |