diff options
-rw-r--r-- | src/main.cpp | 1 | ||||
-rw-r--r-- | src/repository.cpp | 81 | ||||
-rw-r--r-- | src/repository.h | 11 |
3 files changed, 90 insertions, 3 deletions
diff --git a/src/main.cpp b/src/main.cpp index 6125171..60c6bb8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -124,6 +124,7 @@ static const CommandLineOption options[] = { {"--revisions-file FILENAME", "provide a file with revision number that should be processed"}, {"--rules FILENAME[,FILENAME]", "the rules file(s) that determines what goes where"}, {"--add-metadata", "if passed, each git commit will have svn commit info"}, + {"--add-metadata-notes", "if passed, each git commit will have notes with svn commit info"}, {"--resume-from revision", "start importing at svn revision number"}, {"--max-rev revision", "stop importing at svn revision number"}, {"--dry-run", "don't actually write anything"}, diff --git a/src/repository.cpp b/src/repository.cpp index e6ea81c..796604a 100644 --- a/src/repository.cpp +++ b/src/repository.cpp @@ -333,6 +333,9 @@ int Repository::createBranch(const QString &branch, int revnum, qDebug() << "Creating branch:" << branch << "from" << branchFrom << "(" << branchRevNum << branchFromDesc << ")"; + // Preserve note + branches[branch].note = branches.value(branchFrom).note; + return resetBranch(branch, revnum, mark, branchFromRef, branchFromDesc); } @@ -460,7 +463,7 @@ void Repository::finalizeTags() if (!message.endsWith('\n')) message += '\n'; if (CommandLineParser::instance()->contains("add-metadata")) - message += "\nsvn path=" + tag.svnprefix + "; revision=" + QByteArray::number(tag.revnum) + "\n"; + message += "\n" + formatMetadataMessage(tag.svnprefix, tag.revnum, tagName.toUtf8()); { QByteArray branchRef = tag.supportingRef.toUtf8(); @@ -480,6 +483,19 @@ void Repository::finalizeTags() if (!fastImport.waitForBytesWritten(-1)) qFatal("Failed to write to process: %s", qPrintable(fastImport.errorString())); + // Append note to the tip commit of the supporting ref. There is no + // easy way to attach a note to the tag itself with fast-import. + if (CommandLineParser::instance()->contains("add-metadata-notes")) { + Repository::Transaction *txn = newTransaction(tag.supportingRef, tag.svnprefix, tag.revnum); + txn->setAuthor(tag.author); + txn->setDateTime(tag.dt); + txn->commitNote(formatMetadataMessage(tag.svnprefix, tag.revnum, tagName.toUtf8()), true); + delete txn; + + if (!fastImport.waitForBytesWritten(-1)) + qFatal("Failed to write to process: %s", qPrintable(fastImport.errorString())); + } + printf(" %s", qPrintable(tagName)); fflush(stdout); } @@ -520,6 +536,31 @@ void Repository::startFastImport() } } +QByteArray Repository::formatMetadataMessage(const QByteArray &svnprefix, int revnum, const QByteArray &tag) +{ + QByteArray msg = "svn path=" + svnprefix + "; revision=" + QByteArray::number(revnum); + if (!tag.isEmpty()) + msg += "; tag=" + tag; + msg += "\n"; + return msg; +} + +bool Repository::branchExists(const QString& branch) const\ +{ + return branches.contains(branch); +} + +const QByteArray Repository::branchNote(const QString& branch) const +{ + return branches.value(branch).note; +} + +void Repository::setBranchNote(const QString& branch, const QByteArray& noteText) +{ + if (branches.contains(branch)) + branches[branch].note = noteText; +} + Repository::Transaction::~Transaction() { repository->forgetTransaction(this); @@ -605,6 +646,37 @@ QIODevice *Repository::Transaction::addFile(const QString &path, int mode, qint6 return &repository->fastImport; } +void Repository::Transaction::commitNote(const QByteArray ¬eText, bool append, const QByteArray &commit) +{ + QByteArray branchRef = branch; + if (!branchRef.startsWith("refs/")) + branchRef.prepend("refs/heads/"); + const QByteArray &commitRef = commit.isNull() ? branchRef : commit; + QByteArray message = "Adding Git note for current " + commitRef + "\n"; + QByteArray text = noteText; + + if (append && commit.isNull() && + repository->branchExists(branch) && + !repository->branchNote(branch).isEmpty()) + { + text = repository->branchNote(branch) + text; + message = "Appending Git note for current " + commitRef + "\n"; + } + + QTextStream s(&repository->fastImport); + s << "commit refs/notes/commits" << endl + << "committer " << QString::fromUtf8(author) << ' ' << datetime << " -0000" << endl + << "data " << message.length() << endl + << message << endl + << "N inline " << commitRef << endl + << "data " << text.length() << endl + << text << endl; + + if (commit.isNull()) { + repository->setBranchNote(QString::fromUtf8(branch), text); + } +} + void Repository::Transaction::commit() { repository->startFastImport(); @@ -622,7 +694,7 @@ void Repository::Transaction::commit() if (!message.endsWith('\n')) message += '\n'; if (CommandLineParser::instance()->contains("add-metadata")) - message += "\nsvn path=" + svnprefix + "; revision=" + QByteArray::number(revnum) + "\n"; + message += "\n" + Repository::formatMetadataMessage(svnprefix, revnum); int parentmark = 0; Branch &br = repository->branches[branch]; @@ -640,7 +712,6 @@ void Repository::Transaction::commit() QByteArray branchRef = branch; if (!branchRef.startsWith("refs/")) branchRef.prepend("refs/heads/"); - QTextStream s(&repository->fastImport); s.setCodec("UTF-8"); s << "commit " << branchRef << endl; @@ -704,6 +775,10 @@ void Repository::Transaction::commit() deletedFiles.count() + modifiedFiles.count('\n'), svnprefix.data(), qPrintable(repository->name), branch.data()); + // Commit metadata note if requested + if (CommandLineParser::instance()->contains("add-metadata-notes")) + commitNote(Repository::formatMetadataMessage(svnprefix, revnum), false); + while (repository->fastImport.bytesToWrite()) if (!repository->fastImport.waitForBytesWritten(-1)) qFatal("Failed to write to process: %s for repository %s", qPrintable(repository->fastImport.errorString()), qPrintable(repository->name)); diff --git a/src/repository.h b/src/repository.h index 349cf97..4716ced 100644 --- a/src/repository.h +++ b/src/repository.h @@ -126,6 +126,9 @@ public: void deleteFile(const QString &path); QIODevice *addFile(const QString &path, int mode, qint64 length); + + void commitNote(const QByteArray ¬eText, bool append, + const QByteArray &commit = QByteArray()); }; Repository(const Rules::Repository &rule); int setupIncremental(int &cutoff); @@ -144,12 +147,20 @@ public: void finalizeTags(); void commit(); + static QByteArray formatMetadataMessage(const QByteArray &svnprefix, int revnum, + const QByteArray &tag = QByteArray()); + + bool branchExists(const QString& branch) const; + const QByteArray branchNote(const QString& branch) const; + void setBranchNote(const QString& branch, const QByteArray& noteText); + private: struct Branch { int created; QVector<int> commits; QVector<int> marks; + QByteArray note; }; struct AnnotatedTag { |