Skip to content

Commit 22f5339

Browse files
committed
Add support for adding svn commit info metadata as git notes.
The patch add --add-metadata-notes command line option which is similar to --add-metadata except rather embedding svn commit info into the commit message, it is added as a note for the respective commit.
1 parent 197979b commit 22f5339

File tree

3 files changed

+90
-3
lines changed

3 files changed

+90
-3
lines changed

src/main.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ static const CommandLineOption options[] = {
124124
{"--revisions-file FILENAME", "provide a file with revision number that should be processed"},
125125
{"--rules FILENAME[,FILENAME]", "the rules file(s) that determines what goes where"},
126126
{"--add-metadata", "if passed, each git commit will have svn commit info"},
127+
{"--add-metadata-notes", "if passed, each git commit will have notes with svn commit info"},
127128
{"--resume-from revision", "start importing at svn revision number"},
128129
{"--max-rev revision", "stop importing at svn revision number"},
129130
{"--dry-run", "don't actually write anything"},

src/repository.cpp

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,9 @@ int Repository::createBranch(const QString &branch, int revnum,
333333

334334
qDebug() << "Creating branch:" << branch << "from" << branchFrom << "(" << branchRevNum << branchFromDesc << ")";
335335

336+
// Preserve note
337+
branches[branch].note = branches.value(branchFrom).note;
338+
336339
return resetBranch(branch, revnum, mark, branchFromRef, branchFromDesc);
337340
}
338341

@@ -460,7 +463,7 @@ void Repository::finalizeTags()
460463
if (!message.endsWith('\n'))
461464
message += '\n';
462465
if (CommandLineParser::instance()->contains("add-metadata"))
463-
message += "\nsvn path=" + tag.svnprefix + "; revision=" + QByteArray::number(tag.revnum) + "\n";
466+
message += "\n" + formatMetadataMessage(tag.svnprefix, tag.revnum, tagName.toUtf8());
464467

465468
{
466469
QByteArray branchRef = tag.supportingRef.toUtf8();
@@ -480,6 +483,19 @@ void Repository::finalizeTags()
480483
if (!fastImport.waitForBytesWritten(-1))
481484
qFatal("Failed to write to process: %s", qPrintable(fastImport.errorString()));
482485

486+
// Append note to the tip commit of the supporting ref. There is no
487+
// easy way to attach a note to the tag itself with fast-import.
488+
if (CommandLineParser::instance()->contains("add-metadata-notes")) {
489+
Repository::Transaction *txn = newTransaction(tag.supportingRef, tag.svnprefix, tag.revnum);
490+
txn->setAuthor(tag.author);
491+
txn->setDateTime(tag.dt);
492+
txn->commitNote(formatMetadataMessage(tag.svnprefix, tag.revnum, tagName.toUtf8()), true);
493+
delete txn;
494+
495+
if (!fastImport.waitForBytesWritten(-1))
496+
qFatal("Failed to write to process: %s", qPrintable(fastImport.errorString()));
497+
}
498+
483499
printf(" %s", qPrintable(tagName));
484500
fflush(stdout);
485501
}
@@ -520,6 +536,31 @@ void Repository::startFastImport()
520536
}
521537
}
522538

539+
QByteArray Repository::formatMetadataMessage(const QByteArray &svnprefix, int revnum, const QByteArray &tag)
540+
{
541+
QByteArray msg = "svn path=" + svnprefix + "; revision=" + QByteArray::number(revnum);
542+
if (!tag.isEmpty())
543+
msg += "; tag=" + tag;
544+
msg += "\n";
545+
return msg;
546+
}
547+
548+
bool Repository::branchExists(const QString& branch) const\
549+
{
550+
return branches.contains(branch);
551+
}
552+
553+
const QByteArray Repository::branchNote(const QString& branch) const
554+
{
555+
return branches.value(branch).note;
556+
}
557+
558+
void Repository::setBranchNote(const QString& branch, const QByteArray& noteText)
559+
{
560+
if (branches.contains(branch))
561+
branches[branch].note = noteText;
562+
}
563+
523564
Repository::Transaction::~Transaction()
524565
{
525566
repository->forgetTransaction(this);
@@ -605,6 +646,37 @@ QIODevice *Repository::Transaction::addFile(const QString &path, int mode, qint6
605646
return &repository->fastImport;
606647
}
607648

649+
void Repository::Transaction::commitNote(const QByteArray &noteText, bool append, const QByteArray &commit)
650+
{
651+
QByteArray branchRef = branch;
652+
if (!branchRef.startsWith("refs/"))
653+
branchRef.prepend("refs/heads/");
654+
const QByteArray &commitRef = commit.isNull() ? branchRef : commit;
655+
QByteArray message = "Adding Git note for current " + commitRef + "\n";
656+
QByteArray text = noteText;
657+
658+
if (append && commit.isNull() &&
659+
repository->branchExists(branch) &&
660+
!repository->branchNote(branch).isEmpty())
661+
{
662+
text = repository->branchNote(branch) + text;
663+
message = "Appending Git note for current " + commitRef + "\n";
664+
}
665+
666+
QTextStream s(&repository->fastImport);
667+
s << "commit refs/notes/commits" << endl
668+
<< "committer " << QString::fromUtf8(author) << ' ' << datetime << " -0000" << endl
669+
<< "data " << message.length() << endl
670+
<< message << endl
671+
<< "N inline " << commitRef << endl
672+
<< "data " << text.length() << endl
673+
<< text << endl;
674+
675+
if (commit.isNull()) {
676+
repository->setBranchNote(QString::fromUtf8(branch), text);
677+
}
678+
}
679+
608680
void Repository::Transaction::commit()
609681
{
610682
repository->startFastImport();
@@ -622,7 +694,7 @@ void Repository::Transaction::commit()
622694
if (!message.endsWith('\n'))
623695
message += '\n';
624696
if (CommandLineParser::instance()->contains("add-metadata"))
625-
message += "\nsvn path=" + svnprefix + "; revision=" + QByteArray::number(revnum) + "\n";
697+
message += "\n" + Repository::formatMetadataMessage(svnprefix, revnum);
626698

627699
int parentmark = 0;
628700
Branch &br = repository->branches[branch];
@@ -640,7 +712,6 @@ void Repository::Transaction::commit()
640712
QByteArray branchRef = branch;
641713
if (!branchRef.startsWith("refs/"))
642714
branchRef.prepend("refs/heads/");
643-
644715
QTextStream s(&repository->fastImport);
645716
s.setCodec("UTF-8");
646717
s << "commit " << branchRef << endl;
@@ -704,6 +775,10 @@ void Repository::Transaction::commit()
704775
deletedFiles.count() + modifiedFiles.count('\n'), svnprefix.data(),
705776
qPrintable(repository->name), branch.data());
706777

778+
// Commit metadata note if requested
779+
if (CommandLineParser::instance()->contains("add-metadata-notes"))
780+
commitNote(Repository::formatMetadataMessage(svnprefix, revnum), false);
781+
707782
while (repository->fastImport.bytesToWrite())
708783
if (!repository->fastImport.waitForBytesWritten(-1))
709784
qFatal("Failed to write to process: %s for repository %s", qPrintable(repository->fastImport.errorString()), qPrintable(repository->name));

src/repository.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ class Repository
126126

127127
void deleteFile(const QString &path);
128128
QIODevice *addFile(const QString &path, int mode, qint64 length);
129+
130+
void commitNote(const QByteArray &noteText, bool append,
131+
const QByteArray &commit = QByteArray());
129132
};
130133
Repository(const Rules::Repository &rule);
131134
int setupIncremental(int &cutoff);
@@ -144,12 +147,20 @@ class Repository
144147
void finalizeTags();
145148
void commit();
146149

150+
static QByteArray formatMetadataMessage(const QByteArray &svnprefix, int revnum,
151+
const QByteArray &tag = QByteArray());
152+
153+
bool branchExists(const QString& branch) const;
154+
const QByteArray branchNote(const QString& branch) const;
155+
void setBranchNote(const QString& branch, const QByteArray& noteText);
156+
147157
private:
148158
struct Branch
149159
{
150160
int created;
151161
QVector<int> commits;
152162
QVector<int> marks;
163+
QByteArray note;
153164
};
154165
struct AnnotatedTag
155166
{

0 commit comments

Comments
 (0)