From 008b28e0f4c48de8d740c51c053020d1a36315bf Mon Sep 17 00:00:00 2001 From: Raja R Harinath Date: Thu, 22 Jul 2010 18:32:21 +0530 Subject: Provide a way to merge repositories Suppose you have multiple repositories in SVN that you want to merge into a single one in GIT, it can get very messy to handle all the special-case rules. Instead, we introduce a new "forwarding repository" concept, which looks like repository subordinate repository unified prefix foo/ end repository This forwards all commits on the "subordinate" SVN tree to the "unified" GIT tree, with each file prefixed with "foo/". --- src/main.cpp | 2 ++ src/repository.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++- src/repository.h | 1 - src/ruleparser.cpp | 8 ++++++- src/ruleparser.h | 3 +++ 5 files changed, 73 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp index ff11255..3feb3cf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -124,6 +124,8 @@ int main(int argc, char **argv) int min_rev = 1; foreach (Rules::Repository rule, rules.repositories()) { Repository *repo = makeRepository(rule, repositories); + if (!repo) + return EXIT_FAILURE; repositories.insert(rule.name, repo); int repo_next = repo->setupIncremental(cutoff); diff --git a/src/repository.cpp b/src/repository.cpp index f5b7a50..760fc1a 100644 --- a/src/repository.cpp +++ b/src/repository.cpp @@ -123,6 +123,59 @@ private: Q_DISABLE_COPY(FastImportRepository) }; +class PrefixingRepository : public Repository +{ + Repository *repo; + QString prefix; +public: + class Transaction : public Repository::Transaction + { + Q_DISABLE_COPY(Transaction) + + Repository::Transaction *txn; + QString prefix; + public: + 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 deleteFile(const QString &path) { txn->deleteFile(prefix + path); } + QIODevice *addFile(const QString &path, int mode, qint64 length) + { return txn->addFile(prefix + path, mode, length); } + }; + + PrefixingRepository(Repository *r, const QString &p) : repo(r), prefix(p) {} + + int setupIncremental(int &) { return 1; } + void restoreLog() {} + + int createBranch(const QString &branch, int revnum, + const QString &branchFrom, int revFrom) + { return repo->createBranch(branch, revnum, branchFrom, revFrom); } + + int deleteBranch(const QString &branch, int revnum) + { return repo->deleteBranch(branch, revnum); } + + Repository::Transaction *newTransaction(const QString &branch, const QString &svnprefix, int revnum) + { + 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) + { repo->createAnnotatedTag(name, svnprefix, revnum, author, dt, log); } + void finalizeTags() { /* loop that called this will invoke it on 'repo' too */ } +}; + class ProcessCache: QLinkedList { public: @@ -151,7 +204,14 @@ static ProcessCache processCache; Repository *makeRepository(const Rules::Repository &rule, const QHash &repositories) { - return new FastImportRepository(rule); + if (rule.forwardTo.isEmpty()) + 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; + } + return new PrefixingRepository(r, rule.prefix); } FastImportRepository::FastImportRepository(const Rules::Repository &rule) diff --git a/src/repository.h b/src/repository.h index 590ef0e..e07d184 100644 --- a/src/repository.h +++ b/src/repository.h @@ -49,7 +49,6 @@ public: virtual void restoreLog() = 0; virtual ~Repository() {} - virtual void reloadBranches() = 0; virtual int createBranch(const QString &branch, int revnum, const QString &branchFrom, int revFrom) = 0; virtual int deleteBranch(const QString &branch, int revnum) = 0; diff --git a/src/ruleparser.cpp b/src/ruleparser.cpp index 42334b7..d1f5cd4 100644 --- a/src/ruleparser.cpp +++ b/src/ruleparser.cpp @@ -81,7 +81,13 @@ void Rules::load() repo.branches += branch; continue; - } else if (line == "end repository") { + } else if (matchRepoLine.exactMatch(line)) { + repo.forwardTo = matchRepoLine.cap(1); + continue; + } else if (matchPrefixLine.exactMatch(line)) { + repo.prefix = matchPrefixLine.cap(1); + continue; + } else if (line == "end repository") { m_repositories += repo; { // clear out 'repo' diff --git a/src/ruleparser.h b/src/ruleparser.h index 8d0fcb2..95a508f 100644 --- a/src/ruleparser.h +++ b/src/ruleparser.h @@ -36,6 +36,9 @@ public: QList branches; int lineNumber; + QString forwardTo; + QString prefix; + Repository() : lineNumber(0) { } }; -- cgit v1.2.1