X-Git-Url: http://andersk.mit.edu/gitweb/svn-all-fast-export.git/blobdiff_plain/5a7327f691416d3b061318da00fbd85a341f710a..b6ba9639a3c908aedb76954a575641c56a76714c:/src/repository.cpp diff --git a/src/repository.cpp b/src/repository.cpp index c3174b8..8a5f4f0 100644 --- a/src/repository.cpp +++ b/src/repository.cpp @@ -16,8 +16,11 @@ */ #include "repository.h" +#include +#include Repository::Repository(const Rules::Repository &rule) + : name(rule.name) { foreach (Rules::Repository::Branch branchRule, rule.branches) { Branch branch; @@ -27,6 +30,140 @@ Repository::Repository(const Rules::Repository &rule) branches.insert(branchRule.name, branch); } + // create the default branch + branches["master"].isCreated = true; + fastImport.setWorkingDirectory(rule.name); fastImport.setProcessChannelMode(QProcess::ForwardedChannels); } + +Repository::~Repository() +{ + if (fastImport.state() == QProcess::Running) { + fastImport.closeWriteChannel(); + fastImport.waitForFinished(); + } +} + +Repository::Transaction *Repository::newTransaction(const QString &branch, const QString &svnprefix, + int revnum) +{ + if (!branches.contains(branch)) { + qCritical() << branch << "is not known in repository" << name; + return 0; + } + + Transaction *txn = new Transaction; + txn->repository = this; + txn->branch = branch.toUtf8(); + txn->svnprefix = svnprefix.toUtf8(); + txn->datetime = 0; + txn->revnum = revnum; + txn->lastmark = revnum; + + if (fastImport.state() == QProcess::NotRunning) { + // start the process +#ifndef DRY_RUN + fastImport.start("git-fast-import", QStringList()); +#else + fastImport.start("/bin/cat", QStringList()); +#endif + } + + return txn; +} + +Repository::Transaction::~Transaction() +{ +} + +void Repository::Transaction::setAuthor(const QByteArray &a) +{ + author = a; +} + +void Repository::Transaction::setDateTime(uint dt) +{ + datetime = dt; +} + +void Repository::Transaction::setLog(const QByteArray &l) +{ + log = l; +} + +void Repository::Transaction::deleteFile(const QString &path) +{ + deletedFiles.append(path); +} + +QIODevice *Repository::Transaction::addFile(const QString &path, int mode, qint64 length) +{ + FileProperties fp; + fp.mode = mode; + fp.mark = ++lastmark; + +#ifndef DRY_RUN + repository->fastImport.write("blob\nmark :"); + repository->fastImport.write(QByteArray::number(fp.mark)); + repository->fastImport.write("\ndata "); + repository->fastImport.write(QByteArray::number(length)); + repository->fastImport.write("\n", 1); + repository->fastImport.waitForBytesWritten(0); +#endif + + modifiedFiles.insert(path, fp); + return &repository->fastImport; +} + +void Repository::Transaction::commit() +{ + // create the commit message + QByteArray message = log; + if (!message.endsWith('\n')) + message += '\n'; + message += "\nsvn=" + svnprefix + "; revision=" + QByteArray::number(revnum) + "\n"; + + { + QByteArray branchRef = branch; + if (!branchRef.startsWith("refs/heads/")) + branchRef.prepend("refs/heads/"); + + QTextStream s(&repository->fastImport); + s << "commit " << branchRef << endl; + s << "mark :" << revnum << endl; + s << "committer " << author << ' ' << datetime << " -0000" << endl; + + Branch &br = repository->branches[branch]; + if (!br.isCreated) { + br.isCreated = true; + s << "from " << br.branchFrom << endl; + } + + s << "data " << message.length() << endl; + } + + repository->fastImport.write(message); + + // write the file deletions + foreach (QString df, deletedFiles) + repository->fastImport.write("D " + df.toUtf8() + "\n"); + + // write the file modifications + QHash::ConstIterator it = modifiedFiles.constBegin(); + for ( ; it != modifiedFiles.constEnd(); ++it) { + repository->fastImport.write("M ", 2); + repository->fastImport.write(QByteArray::number(it->mode, 8)); + repository->fastImport.write(" :", 2); + repository->fastImport.write(QByteArray::number(it->mark)); + repository->fastImport.write(" ", 1); + repository->fastImport.write(it.key().toUtf8()); + repository->fastImport.write("\n", 1); + } + + repository->fastImport.write("\n"); + + while (repository->fastImport.bytesToWrite() && repository->fastImport.waitForBytesWritten()) { + // nothing + } +}