diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/repository.cpp | 26 | ||||
-rw-r--r-- | src/repository.h | 1 | ||||
-rw-r--r-- | src/svn.cpp | 63 |
3 files changed, 67 insertions, 23 deletions
diff --git a/src/repository.cpp b/src/repository.cpp index 5250f71..847771f 100644 --- a/src/repository.cpp +++ b/src/repository.cpp @@ -141,7 +141,7 @@ void Repository::createBranch(const QString &branch, int revnum, branchRef.prepend("refs/heads/"); Branch &br = branches[branch]; - if (br.created && br.created != revnum) { + if (br.created && br.created != revnum && br.marks.last()) { QByteArray backupBranch = branchRef + '_' + QByteArray::number(revnum); qWarning() << branch << "already exists; backing up to" << backupBranch; @@ -193,6 +193,30 @@ void Repository::createBranch(const QString &branch, int revnum, + "\n\n"); } +void Repository::deleteBranch(const QString &branch, int revnum) +{ + QByteArray branchRef = branch.toUtf8(); + if (!branchRef.startsWith("refs/")) + branchRef.prepend("refs/heads/"); + + Branch &br = branches[branch]; + if (br.created && br.created != revnum && br.marks.last()) { + QByteArray backupBranch = branchRef + '_' + QByteArray::number(revnum); + qWarning() << "backing up branch" << branch << "to" << backupBranch; + + fastImport.write("reset " + backupBranch + "\nfrom " + branchRef + "\n\n"); + } + + br.created = revnum; + br.commits.append(revnum); + br.marks.append(0); + + static QByteArray null_sha(40, '0'); + fastImport.write("reset " + branchRef + "\nfrom " + null_sha + "\n\n" + "progress SVN r" + QByteArray::number(revnum) + + " branch " + branch.toUtf8() + " = :0 # delete\n\n"); +} + Repository::Transaction *Repository::newTransaction(const QString &branch, const QString &svnprefix, int revnum) { diff --git a/src/repository.h b/src/repository.h index f30b49f..65802bb 100644 --- a/src/repository.h +++ b/src/repository.h @@ -65,6 +65,7 @@ public: void reloadBranches(); void createBranch(const QString &branch, int revnum, const QString &branchFrom, int revFrom); + void deleteBranch(const QString &branch, int revnum); Transaction *newTransaction(const QString &branch, const QString &svnprefix, int revnum); void createAnnotatedTag(const QString &name, const QString &svnprefix, int revnum, diff --git a/src/svn.cpp b/src/svn.cpp index d29328a..69f91af 100644 --- a/src/svn.cpp +++ b/src/svn.cpp @@ -509,7 +509,6 @@ int SvnRevision::exportEntry(const char *key, const svn_fs_path_change_t *change svn_boolean_t is_dir; SVN_ERR(svn_fs_is_dir(&is_dir, fs_root, key, revpool)); if (is_dir) { - current += '/'; if (change->change_kind == svn_fs_path_change_modify || change->change_kind == svn_fs_path_change_add) { if (path_from == NULL) { @@ -520,8 +519,6 @@ int SvnRevision::exportEntry(const char *key, const svn_fs_path_change_t *change } qDebug() << " " << key << "was copied from" << path_from << "rev" << rev_from; - } else if (change->change_kind == svn_fs_path_change_delete) { - qDebug() << " " << key << "was deleted"; } else if (change->change_kind == svn_fs_path_change_replace) { if (path_from == NULL) qDebug() << " " << key << "was replaced"; @@ -531,11 +528,17 @@ 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 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); } + if (is_dir) + current += '/'; + // find the first rule that matches this pathname MatchRuleList::ConstIterator match = findMatchRule(matchRules, revnum, current); if (match != matchRules.constEnd()) { @@ -546,6 +549,9 @@ int SvnRevision::exportEntry(const char *key, const svn_fs_path_change_t *change if (is_dir && path_from != NULL) { 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); } else if (wasDir(fs, revnum - 1, key, revpool)) { qDebug() << current << "was a directory; ignoring"; } else if (change->change_kind == svn_fs_path_change_delete) { @@ -576,7 +582,14 @@ int SvnRevision::exportDispatch(const char *key, const svn_fs_path_change_t *cha return recurse(key, change, path_from, rev_from, changes, pool); case Rules::Match::Export: - return exportInternal(key, change, path_from, rev_from, current, rule); + 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); } // never reached @@ -590,16 +603,30 @@ int SvnRevision::exportInternal(const char *key, const svn_fs_path_change_t *cha QString svnprefix, repository, branch, path; splitPathName(rule, current, &svnprefix, &repository, &branch, &path); + 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; + } + 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) { + qDebug() << "repository" << repository << "branch" << branch << "deleted"; + repo->deleteBranch(branch, revnum); + return EXIT_SUCCESS; + } + QString previous; QString prevsvnprefix, prevrepository, prevbranch, prevpath; if (path_from != NULL) { - QString previous = QString::fromUtf8(path_from) + '/'; + previous = QString::fromUtf8(path_from) + '/'; MatchRuleList::ConstIterator prevmatch = findMatchRule(matchRules, rev_from, previous, NoIgnoreRule); if (prevmatch != matchRules.constEnd()) @@ -634,12 +661,6 @@ int SvnRevision::exportInternal(const char *key, const svn_fs_path_change_t *cha << qPrintable(branch) << "is branching from" << qPrintable(prevbranch); } - Repository *repo = repositories.value(repository, 0); - if (!repo) { - qCritical() << "Rule" << rule - << "references unknown repository" << repository; - return EXIT_FAILURE; - } repo->createBranch(branch, revnum, prevbranch, rev_from); if (rule.annotate) { @@ -651,16 +672,8 @@ int SvnRevision::exportInternal(const char *key, const svn_fs_path_change_t *cha return EXIT_SUCCESS; } } - Repository::Transaction *txn = transactions.value(repository + branch, 0); if (!txn) { - Repository *repo = repositories.value(repository, 0); - if (!repo) { - qCritical() << "Rule" << rule - << "references unknown repository" << repository; - return EXIT_FAILURE; - } - txn = repo->newTransaction(branch, svnprefix, revnum); if (!txn) return EXIT_FAILURE; @@ -695,6 +708,10 @@ int SvnRevision::recurse(const char *path, const svn_fs_path_change_t *change, const char *path_from, svn_revnum_t rev_from, apr_hash_t *changes, apr_pool_t *pool) { + 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)); + // get the dir listing apr_hash_t *entries; SVN_ERR(svn_fs_dir_entries(&entries, fs_root, path, pool)); @@ -735,9 +752,11 @@ int SvnRevision::recurse(const char *path, const svn_fs_path_change_t *change, rev_from, changes, current, *match, dirpool) == EXIT_FAILURE) return EXIT_FAILURE; } else { - qCritical() << current << "rev" << revnum - << "did not match any rules; cannot continue"; - return EXIT_FAILURE; + 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; } } |