diff options
author | Raja R Harinath <harinath@hurrynot.org> | 2010-07-11 19:08:53 +0530 |
---|---|---|
committer | Raja R Harinath <harinath@hurrynot.org> | 2010-07-11 21:01:22 +0530 |
commit | 2a7a37ff0f62f5dc06acf95d8084cd0521d6a651 (patch) | |
tree | d81e5473c68ec6945574a240d0f2ca7d0d168a43 /src | |
parent | c0bc64179f96b5d2e13a905f1f6867cce3ac9558 (diff) | |
download | svn2git-2a7a37ff0f62f5dc06acf95d8084cd0521d6a651.tar svn2git-2a7a37ff0f62f5dc06acf95d8084cd0521d6a651.tar.gz svn2git-2a7a37ff0f62f5dc06acf95d8084cd0521d6a651.tar.bz2 svn2git-2a7a37ff0f62f5dc06acf95d8084cd0521d6a651.tar.xz svn2git-2a7a37ff0f62f5dc06acf95d8084cd0521d6a651.zip |
Make error handling of --incremental and --resume-from idempotent
When --resume-from failed in incremental mode, the log files that detected
the error condition were truncated. So, if the same command line was executed
again, the invocation would go through.
We now restore the log files from backup when we detect we're going to fail.
The restored log files may not all be the same as we originally started with,
but we only truncate information that would anyway be truncated on the
next successful run.
Diffstat (limited to 'src')
-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(); |