Skip to content

Commit e7bf95a

Browse files
authored
Merge branch 'master' into annotated-tags-with-incremental-runs
2 parents fa63987 + e7548a0 commit e7bf95a

File tree

5 files changed

+94
-29
lines changed

5 files changed

+94
-29
lines changed

src/main.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ int main(int argc, char **argv)
212212

213213
int repo_next = repo->setupIncremental(cutoff);
214214
repo->restoreAnnotatedTags();
215+
repo->restoreBranchNotes();
215216

216217
/*
217218
* cutoff < resume_from => error exit eventually
@@ -283,6 +284,7 @@ int main(int argc, char **argv)
283284

284285
foreach (Repository *repo, repositories) {
285286
repo->finalizeTags();
287+
repo->saveBranchNotes();
286288
delete repo;
287289
}
288290
Stats::instance()->printStats();

src/repository.cpp

Lines changed: 80 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class FastImportRepository : public Repository
6262
inline Transaction() {}
6363
public:
6464
~Transaction();
65-
void commit();
65+
int commit();
6666

6767
void setAuthor(const QByteArray &author);
6868
void setDateTime(uint dt);
@@ -73,12 +73,13 @@ class FastImportRepository : public Repository
7373
void deleteFile(const QString &path);
7474
QIODevice *addFile(const QString &path, int mode, qint64 length);
7575

76-
void commitNote(const QByteArray &noteText, bool append,
76+
bool commitNote(const QByteArray &noteText, bool append,
7777
const QByteArray &commit = QByteArray());
7878
};
7979
FastImportRepository(const Rules::Repository &rule);
8080
int setupIncremental(int &cutoff);
8181
void restoreAnnotatedTags();
82+
void restoreBranchNotes();
8283
void restoreLog();
8384
~FastImportRepository();
8485

@@ -92,6 +93,7 @@ class FastImportRepository : public Repository
9293
const QByteArray &author, uint dt,
9394
const QByteArray &log);
9495
void finalizeTags();
96+
void saveBranchNotes();
9597
void commit();
9698

9799
bool branchExists(const QString& branch) const;
@@ -108,10 +110,10 @@ class FastImportRepository : public Repository
108110
int created;
109111
QVector<int> commits;
110112
QVector<int> marks;
111-
QByteArray note;
112113
};
113114

114115
QHash<QString, Branch> branches;
116+
QHash<QString, QByteArray> branchNotes;
115117
QHash<QString, AnnotatedTag> annotatedTags;
116118
QString name;
117119
QString prefix;
@@ -163,7 +165,7 @@ class ForwardingRepository : public Repository
163165
public:
164166
Transaction(Repository::Transaction *t, const QString &p) : txn(t), prefix(p) {}
165167
~Transaction() { delete txn; }
166-
void commit() { txn->commit(); }
168+
int commit() { return txn->commit(); }
167169

168170
void setAuthor(const QByteArray &author) { txn->setAuthor(author); }
169171
void setDateTime(uint dt) { txn->setDateTime(dt); }
@@ -176,7 +178,7 @@ class ForwardingRepository : public Repository
176178
QIODevice *addFile(const QString &path, int mode, qint64 length)
177179
{ return txn->addFile(prefix + path, mode, length); }
178180

179-
void commitNote(const QByteArray &noteText, bool append,
181+
bool commitNote(const QByteArray &noteText, bool append,
180182
const QByteArray &commit)
181183
{ return txn->commitNote(noteText, append, commit); }
182184
};
@@ -185,6 +187,7 @@ class ForwardingRepository : public Repository
185187

186188
int setupIncremental(int &) { return 1; }
187189
void restoreAnnotatedTags() {}
190+
void restoreBranchNotes() {}
188191
void restoreLog() {}
189192

190193
void reloadBranches() { return repo->reloadBranches(); }
@@ -206,6 +209,7 @@ class ForwardingRepository : public Repository
206209
const QByteArray &log)
207210
{ repo->createAnnotatedTag(name, svnprefix, revnum, author, dt, log); }
208211
void finalizeTags() { /* loop that called this will invoke it on 'repo' too */ }
212+
void saveBranchNotes() { /* loop that called this will invoke it on 'repo' too */ }
209213
void commit() { repo->commit(); }
210214

211215
bool branchExists(const QString& branch) const
@@ -303,6 +307,13 @@ static QString annotatedTagsFileName(QString name)
303307
return name;
304308
}
305309

310+
static QString branchNotesFileName(QString name)
311+
{
312+
name.replace('/', '_');
313+
name.prepend("branchNotes-");
314+
return name;
315+
}
316+
306317
FastImportRepository::FastImportRepository(const Rules::Repository &rule)
307318
: name(rule.name), prefix(rule.forwardTo), fastImport(name), commitCount(0), outstandingTransactions(0),
308319
last_commit_mark(0), next_file_mark(maxMark - 1), processHasStarted(false)
@@ -498,6 +509,17 @@ void FastImportRepository::restoreAnnotatedTags()
498509
annotatedTagsFile.close();
499510
}
500511

512+
void FastImportRepository::restoreBranchNotes()
513+
{
514+
QFile branchNotesFile(name + "/" + branchNotesFileName(name));
515+
if (!branchNotesFile.exists())
516+
return;
517+
branchNotesFile.open(QIODevice::ReadOnly);
518+
QDataStream branchNotesStream(&branchNotesFile);
519+
branchNotesStream >> branchNotes;
520+
branchNotesFile.close();
521+
}
522+
501523
void FastImportRepository::restoreLog()
502524
{
503525
QString file = logFileName(name);
@@ -625,7 +647,7 @@ int FastImportRepository::createBranch(const QString &branch, int revnum,
625647
qDebug() << "Creating branch:" << branch << "from" << branchFrom << "(" << branchRevNum << branchFromDesc << ")";
626648

627649
// Preserve note
628-
branches[branch].note = branches.value(branchFrom).note;
650+
branchNotes[branch] = branchNotes.value(branchFrom);
629651

630652
return resetBranch(branch, revnum, mark, branchFromRef, branchFromDesc);
631653
}
@@ -801,10 +823,10 @@ void FastImportRepository::finalizeTags()
801823
Repository::Transaction *txn = newTransaction(tag.supportingRef, tag.svnprefix, tag.revnum);
802824
txn->setAuthor(tag.author);
803825
txn->setDateTime(tag.dt);
804-
txn->commitNote(formatMetadataMessage(tag.svnprefix, tag.revnum, tagName.toUtf8()), true);
826+
bool written = txn->commitNote(formatMetadataMessage(tag.svnprefix, tag.revnum, tagName.toUtf8()), true);
805827
delete txn;
806828

807-
if (!fastImport.waitForBytesWritten(-1))
829+
if (written && !fastImport.waitForBytesWritten(-1))
808830
qFatal("Failed to write to process: %s", qPrintable(fastImport.errorString()));
809831
}
810832

@@ -818,6 +840,17 @@ void FastImportRepository::finalizeTags()
818840
printf("\n");
819841
}
820842

843+
void FastImportRepository::saveBranchNotes()
844+
{
845+
if (branchNotes.isEmpty())
846+
return;
847+
848+
QFile branchNotesFile(name + "/" + branchNotesFileName(name));
849+
branchNotesFile.open(QIODevice::WriteOnly);
850+
QDataStream branchNotesStream(&branchNotesFile);
851+
branchNotesStream << branchNotes;
852+
branchNotesFile.close();
853+
}
821854

822855
QByteArray
823856
FastImportRepository::msgFilter(QByteArray msg)
@@ -887,13 +920,13 @@ bool FastImportRepository::branchExists(const QString& branch) const
887920

888921
const QByteArray FastImportRepository::branchNote(const QString& branch) const
889922
{
890-
return branches.value(branch).note;
923+
return branchNotes.value(branch);
891924
}
892925

893926
void FastImportRepository::setBranchNote(const QString& branch, const QByteArray& noteText)
894927
{
895928
if (branches.contains(branch))
896-
branches[branch].note = noteText;
929+
branchNotes[branch] = noteText;
897930
}
898931

899932
bool FastImportRepository::hasPrefix() const
@@ -997,20 +1030,37 @@ QIODevice *FastImportRepository::Transaction::addFile(const QString &path, int m
9971030
return &repository->fastImport;
9981031
}
9991032

1000-
void FastImportRepository::Transaction::commitNote(const QByteArray &noteText, bool append, const QByteArray &commit)
1033+
bool FastImportRepository::Transaction::commitNote(const QByteArray &noteText, bool append, const QByteArray &commit)
10011034
{
10021035
QByteArray branchRef = branch;
10031036
if (!branchRef.startsWith("refs/"))
1037+
{
10041038
branchRef.prepend("refs/heads/");
1039+
}
10051040
const QByteArray &commitRef = commit.isNull() ? branchRef : commit;
10061041
QByteArray message = "Adding Git note for current " + commitRef + "\n";
10071042
QByteArray text = noteText;
1043+
if (noteText[noteText.size() - 1] != '\n')
1044+
{
1045+
text += '\n';
1046+
}
10081047

1048+
QByteArray branchNote = repository->branchNote(branch);
1049+
if (!branchNote.isEmpty() && (branchNote[branchNote.size() - 1] != '\n'))
1050+
{
1051+
branchNote += '\n';
1052+
}
10091053
if (append && commit.isNull() &&
10101054
repository->branchExists(branch) &&
1011-
!repository->branchNote(branch).isEmpty())
1055+
!branchNote.isEmpty())
10121056
{
1013-
text = repository->branchNote(branch) + text;
1057+
int i = branchNote.indexOf(text);
1058+
if ((i == 0) || ((i != -1) && (branchNote[i - 1] == '\n')))
1059+
{
1060+
// note is already present at the start or somewhere within following a newline
1061+
return false;
1062+
}
1063+
text = branchNote + text;
10141064
message = "Appending Git note for current " + commitRef + "\n";
10151065
}
10161066

@@ -1026,17 +1076,29 @@ void FastImportRepository::Transaction::commitNote(const QByteArray &noteText, b
10261076
repository->startFastImport();
10271077
repository->fastImport.write(s);
10281078

1029-
if (commit.isNull()) {
1079+
if (commit.isNull())
1080+
{
10301081
repository->setBranchNote(QString::fromUtf8(branch), text);
10311082
}
1083+
1084+
return true;
10321085
}
10331086

1034-
void FastImportRepository::Transaction::commit()
1087+
int FastImportRepository::Transaction::commit()
10351088
{
1089+
foreach (QString branchName, repository->branches.keys())
1090+
{
1091+
if (branchName.toUtf8().startsWith(branch + "/") || branch.startsWith((branchName + "/").toUtf8()))
1092+
{
1093+
qCritical() << "Branch" << branch << "conflicts with already existing branch" << branchName;
1094+
return EXIT_FAILURE;
1095+
}
1096+
}
1097+
10361098
repository->startFastImport();
10371099

10381100
// We might be tempted to use the SVN revision number as the fast-import commit mark.
1039-
// However, a single SVN revision can modify multple branches, and thus lead to multiple
1101+
// However, a single SVN revision can modify multiple branches, and thus lead to multiple
10401102
// commits in the same repo. So, we need to maintain a separate commit mark counter.
10411103
mark_t mark = ++repository->last_commit_mark;
10421104

@@ -1135,4 +1197,6 @@ void FastImportRepository::Transaction::commit()
11351197
while (repository->fastImport.bytesToWrite())
11361198
if (!repository->fastImport.waitForBytesWritten(-1))
11371199
qFatal("Failed to write to process: %s for repository %s", qPrintable(repository->fastImport.errorString()), qPrintable(repository->name));
1200+
1201+
return EXIT_SUCCESS;
11381202
}

src/repository.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ class Repository
101101
Transaction() {}
102102
public:
103103
virtual ~Transaction() {}
104-
virtual void commit() = 0;
104+
virtual int commit() = 0;
105105

106106
virtual void setAuthor(const QByteArray &author) = 0;
107107
virtual void setDateTime(uint dt) = 0;
@@ -112,11 +112,12 @@ class Repository
112112
virtual void deleteFile(const QString &path) = 0;
113113
virtual QIODevice *addFile(const QString &path, int mode, qint64 length) = 0;
114114

115-
virtual void commitNote(const QByteArray &noteText, bool append,
115+
virtual bool commitNote(const QByteArray &noteText, bool append,
116116
const QByteArray &commit = QByteArray()) = 0;
117117
};
118118
virtual int setupIncremental(int &cutoff) = 0;
119119
virtual void restoreAnnotatedTags() = 0;
120+
virtual void restoreBranchNotes() = 0;
120121
virtual void restoreLog() = 0;
121122
virtual ~Repository() {}
122123

@@ -130,6 +131,7 @@ class Repository
130131
const QByteArray &author, uint dt,
131132
const QByteArray &log) = 0;
132133
virtual void finalizeTags() = 0;
134+
virtual void saveBranchNotes() = 0;
133135
virtual void commit() = 0;
134136

135137
static QByteArray formatMetadataMessage(const QByteArray &svnprefix, int revnum,

src/src.pro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ DEPENDPATH += .
2828
QT = core
2929

3030
INCLUDEPATH += . $$SVN_INCLUDE $$APR_INCLUDE
31-
!isEmpty($$SVN_LIBDIR): LIBS += -L$$SVN_LIBDIR
31+
!isEmpty(SVN_LIBDIR): LIBS += -L$$SVN_LIBDIR
3232
LIBS += -lsvn_fs-1 -lsvn_repos-1 -lapr-1 -lsvn_subr-1
3333

3434
# Input

src/svn.cpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,8 @@ int SvnRevision::commit()
602602
txn->setDateTime(epoch);
603603
txn->setLog(log);
604604

605-
txn->commit();
605+
if (txn->commit() != EXIT_SUCCESS)
606+
return EXIT_FAILURE;
606607
delete txn;
607608
}
608609

@@ -640,7 +641,7 @@ int SvnRevision::exportEntry(const char *key, const svn_fs_path_change2_t *chang
640641
//qDebug() << "Adding directory:" << key;
641642
}
642643
// svn:ignore-properties
643-
else if (is_dir && (change->change_kind == svn_fs_path_change_add || change->change_kind == svn_fs_path_change_modify)
644+
else if (is_dir && (change->change_kind == svn_fs_path_change_add || change->change_kind == svn_fs_path_change_modify || change->change_kind == svn_fs_path_change_replace)
644645
&& path_from == NULL && CommandLineParser::instance()->contains("svn-ignore")) {
645646
needCommit = true;
646647
}
@@ -897,17 +898,18 @@ int SvnRevision::exportInternal(const char *key, const svn_fs_path_change2_t *ch
897898
qDebug() << "add/change dir (" << key << "->" << branch << path << ")";
898899

899900
// Check unknown svn-properties
900-
if (((path_from == NULL && change->prop_mod==1) || (path_from != NULL && change->change_kind == svn_fs_path_change_add))
901+
if (((path_from == NULL && change->prop_mod==1) || (path_from != NULL && (change->change_kind == svn_fs_path_change_add || change->change_kind == svn_fs_path_change_replace)))
901902
&& CommandLineParser::instance()->contains("propcheck")) {
902903
if (fetchUnknownProps(pool, key, fs_root) != EXIT_SUCCESS) {
903904
qWarning() << "Error checking svn-properties (" << key << ")";
904905
}
905906
}
906907

907-
int ignoreSet = false;
908+
txn->deleteFile(path);
908909

909910
// Add GitIgnore with svn:ignore
910-
if (((path_from == NULL && change->prop_mod==1) || (path_from != NULL && change->change_kind == svn_fs_path_change_add))
911+
int ignoreSet = false;
912+
if (((path_from == NULL && change->prop_mod==1) || (path_from != NULL && (change->change_kind == svn_fs_path_change_add || change->change_kind == svn_fs_path_change_replace)))
911913
&& CommandLineParser::instance()->contains("svn-ignore")) {
912914
QString svnignore;
913915
// TODO: Check if svn:ignore or other property was changed, but always set on copy/rename (path_from != NULL)
@@ -923,14 +925,9 @@ int SvnRevision::exportInternal(const char *key, const svn_fs_path_change2_t *ch
923925
if (CommandLineParser::instance()->contains("empty-dirs") && ignoreSet == false) {
924926
if (addGitIgnore(pool, key, path, fs_root, txn) == EXIT_SUCCESS) {
925927
return EXIT_SUCCESS;
926-
} else {
927-
ignoreSet = true;
928928
}
929929
}
930930

931-
if (ignoreSet == false) {
932-
txn->deleteFile(path);
933-
}
934931
recursiveDumpDir(txn, fs, fs_root, key, path, pool, revnum, rule, matchRules, ruledebug);
935932
}
936933

0 commit comments

Comments
 (0)