diff options
author | Raja R Harinath <harinath@hurrynot.org> | 2010-07-22 18:32:21 +0530 |
---|---|---|
committer | Raja R Harinath <harinath@hurrynot.org> | 2010-07-22 18:32:21 +0530 |
commit | 008b28e0f4c48de8d740c51c053020d1a36315bf (patch) | |
tree | 6acd61c923518b0f9af289f1ad81e8bf6deeb463 /src | |
parent | f0b31cfe9d31421b83507316d1274d191336a1f7 (diff) | |
download | svn2git-008b28e0f4c48de8d740c51c053020d1a36315bf.tar svn2git-008b28e0f4c48de8d740c51c053020d1a36315bf.tar.gz svn2git-008b28e0f4c48de8d740c51c053020d1a36315bf.tar.bz2 svn2git-008b28e0f4c48de8d740c51c053020d1a36315bf.tar.xz svn2git-008b28e0f4c48de8d740c51c053020d1a36315bf.zip |
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/".
Diffstat (limited to 'src')
-rw-r--r-- | src/main.cpp | 2 | ||||
-rw-r--r-- | src/repository.cpp | 62 | ||||
-rw-r--r-- | src/repository.h | 1 | ||||
-rw-r--r-- | src/ruleparser.cpp | 8 | ||||
-rw-r--r-- | src/ruleparser.h | 3 |
5 files changed, 73 insertions, 3 deletions
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<FastImportRepository *> { public: @@ -151,7 +204,14 @@ static ProcessCache processCache; Repository *makeRepository(const Rules::Repository &rule, const QHash<QString, Repository *> &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<Branch> branches; int lineNumber; + QString forwardTo; + QString prefix; + Repository() : lineNumber(0) { } }; |