diff options
-rw-r--r-- | src/main.cpp | 24 | ||||
-rw-r--r-- | src/repository.cpp | 17 | ||||
-rw-r--r-- | src/ruleparser.cpp | 2 | ||||
-rw-r--r-- | src/svn.cpp | 27 | ||||
-rw-r--r-- | src/svn.h | 1 |
5 files changed, 47 insertions, 24 deletions
diff --git a/src/main.cpp b/src/main.cpp index 60c6bb8..ec969c5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -55,12 +55,18 @@ QHash<QByteArray, QByteArray> loadIdentityMapFile(const QString &fileName) // Support git-svn author files, too // - svn2git native: loginname Joe User <user@example.com> // - git-svn: loginname = Joe User <user@example.com> - int rightspace = space; - if (line.indexOf(" = ") == space) - rightspace += 2; + int rightspace = line.indexOf(" = "); + int leftspace = space; + if (rightspace == -1) { + rightspace = space; + } else { + leftspace = rightspace; + rightspace += 2; + } QByteArray realname = line.mid(rightspace).trimmed(); - line.truncate(space); + line.truncate(leftspace); + result.insert(line, realname); }; file.close(); @@ -121,6 +127,7 @@ QSet<int> loadRevisionsFile( const QString &fileName, Svn &svn ) static const CommandLineOption options[] = { {"--identity-map FILENAME", "provide map between svn username and email"}, + {"--identity-domain DOMAIN", "provide user domain if no map was given"}, {"--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"}, @@ -172,9 +179,9 @@ int main(int argc, char **argv) out << "svn-all-fast-export failed: please specify the rules using the 'rules' argument\n"; return 11; } - if (!args->contains("identity-map")) { + if (!args->contains("identity-map") && !args->contains("identity-domain")) { QTextStream out(stderr); - out << "WARNING; no identity-map specified, all commits will be without email address\n\n"; + out << "WARNING; no identity-map or -domain specified, all commits will use default @localhost email address\n\n"; } QCoreApplication app(argc, argv); @@ -240,6 +247,11 @@ int main(int argc, char **argv) svn.setMatchRules(rulesList.allMatchRules()); svn.setRepositories(repositories); svn.setIdentityMap(loadIdentityMapFile(args->optionArgument("identity-map"))); + // Massage user input a little, no guarantees that input makes sense. + QString domain = args->optionArgument("identity-domain").simplified().remove(QChar('@')); + if (domain.isEmpty()) + domain = QString("localhost"); + svn.setIdentityDomain(domain); if (max_rev < 1) max_rev = svn.youngestRevision(); diff --git a/src/repository.cpp b/src/repository.cpp index beb8caf..4d23cab 100644 --- a/src/repository.cpp +++ b/src/repository.cpp @@ -26,7 +26,7 @@ static const int maxSimultaneousProcesses = 100; -static const int maxMark = (1 << 20) - 1; // some versions of git-fast-import are buggy for larger values of maxMark +static const int maxMark = (1 << 20) - 2; // some versions of git-fast-import are buggy for larger values of maxMark class ProcessCache: QLinkedList<Repository *> { @@ -67,7 +67,7 @@ Repository::Repository(const Rules::Repository &rule) { foreach (Rules::Repository::Branch branchRule, rule.branches) { Branch branch; - branch.created = 0; // not created + branch.created = 1; branches.insert(branchRule.name, branch); } @@ -271,12 +271,15 @@ void Repository::closeFastImport() void Repository::reloadBranches() { + bool reset_notes = false; foreach (QString branch, branches.keys()) { Branch &br = branches[branch]; if (br.marks.isEmpty() || !br.marks.last()) continue; + reset_notes = true; + QByteArray branchRef = branch.toUtf8(); if (!branchRef.startsWith("refs/")) branchRef.prepend("refs/heads/"); @@ -285,6 +288,13 @@ void Repository::reloadBranches() "\nfrom :" + QByteArray::number(br.marks.last()) + "\n\n" "progress Branch " + branchRef + " reloaded\n"); } + + if (reset_notes && + CommandLineParser::instance()->contains("add-metadata-notes")) { + fastImport.write("reset refs/notes/commits\nfrom :" + + QByteArray::number(maxMark + 1) + + "\n"); + } } int Repository::markFrom(const QString &branchFrom, int branchRevNum, QByteArray &branchFromDesc) @@ -674,7 +684,8 @@ void Repository::Transaction::commitNote(const QByteArray ¬eText, bool append QTextStream s(&repository->fastImport); s << "commit refs/notes/commits" << endl - << "committer " << QString::fromUtf8(author) << ' ' << datetime << " -0000" << endl + << "mark :" << QByteArray::number(maxMark + 1) << endl + << "committer " << QString::fromUtf8(author) << ' ' << datetime << " +0000" << endl << "data " << message.length() << endl << message << endl << "N inline " << commitRef << endl diff --git a/src/ruleparser.cpp b/src/ruleparser.cpp index b11ea5b..437f3f8 100644 --- a/src/ruleparser.cpp +++ b/src/ruleparser.cpp @@ -141,7 +141,7 @@ void Rules::load(const QString &filename) QRegExp matchBranchSubstLine("substitute branch\\s+(.+)$", Qt::CaseInsensitive); QRegExp matchRevLine("(min|max) revision (\\d+)", Qt::CaseInsensitive); QRegExp matchAnnotateLine("annotated\\s+(\\S+)", Qt::CaseInsensitive); - QRegExp matchPrefixLine("prefix\\s+(\\S+)", Qt::CaseInsensitive); + QRegExp matchPrefixLine("prefix\\s+(.*)$", Qt::CaseInsensitive); QRegExp declareLine("declare\\s+("+varRegex+")\\s*=\\s*(\\S+)", Qt::CaseInsensitive); QRegExp variableLine("\\$\\{("+varRegex+")(\\|[^}$]*)?\\}", Qt::CaseInsensitive); QRegExp includeLine("include\\s+(.*)", Qt::CaseInsensitive); diff --git a/src/svn.cpp b/src/svn.cpp index 0be77a4..32beb89 100644 --- a/src/svn.cpp +++ b/src/svn.cpp @@ -79,6 +79,7 @@ public: QList<MatchRuleList> allMatchRules; RepositoryHash repositories; IdentityHash identities; + QString userdomain; SvnPrivate(const QString &pathToRepository); ~SvnPrivate(); @@ -130,6 +131,11 @@ void Svn::setIdentityMap(const IdentityHash &identityMap) d->identities = identityMap; } +void Svn::setIdentityDomain(const QString &identityDomain) +{ + d->userdomain = identityDomain; +} + int Svn::youngestRevision() { return d->youngestRevision(); @@ -388,6 +394,7 @@ public: QList<MatchRuleList> allMatchRules; RepositoryHash repositories; IdentityHash identities; + QString userdomain; svn_fs_t *fs; svn_fs_root_t *fs_root; @@ -436,6 +443,7 @@ int SvnPrivate::exportRevision(int revnum) rev.allMatchRules = allMatchRules; rev.repositories = repositories; rev.identities = identities; + rev.userdomain = userdomain; // open this revision: printf("Exporting revision %d ", revnum); @@ -506,8 +514,8 @@ int SvnRevision::fetchRevProps() if (!svnauthor || svn_string_isempty(svnauthor)) authorident = "nobody <nobody@localhost>"; else - authorident = svnauthor->data + QByteArray(" <") + - svnauthor->data + QByteArray("@localhost>"); + authorident = svnauthor->data + QByteArray(" <") + svnauthor->data + + QByteArray("@") + userdomain.toUtf8() + QByteArray(">"); } propsFetched = true; return EXIT_SUCCESS; @@ -771,18 +779,6 @@ int SvnRevision::exportInternal(const char *key, const svn_fs_path_change_t *cha transactions.insert(repository + branch, txn); } - // - // If this path was copied from elsewhere, use it to infer _some_ - // merge points. This heuristic is fairly useful for tracking - // changes across directory re-organizations and wholesale branch - // imports. - // - if (path_from != NULL && prevrepository == repository && prevbranch != branch) { - if(ruledebug) - qDebug() << "copy from branch" << prevbranch << "to branch" << branch << "@rev" << rev_from; - txn->noteCopyFromBranch (prevbranch, rev_from); - } - if (change->change_kind == svn_fs_path_change_replace && path_from == NULL) { if(ruledebug) qDebug() << "replaced with empty path (" << branch << path << ")"; @@ -821,6 +817,9 @@ int SvnRevision::recurse(const char *path, const svn_fs_path_change_t *change, if(kind == svn_node_none) { qWarning() << "WARN: Trying to recurse using a nonexistant path" << path << ", ignoring"; return EXIT_SUCCESS; + } else if(kind != svn_node_dir) { + qWarning() << "WARN: Trying to recurse using a non-directory path" << path << ", ignoring"; + return EXIT_SUCCESS; } SVN_ERR(svn_fs_dir_entries(&entries, fs_root, path, pool)); @@ -36,6 +36,7 @@ public: void setMatchRules(const QList<QList<Rules::Match> > &matchRules); void setRepositories(const QHash<QString, Repository *> &repositories); void setIdentityMap(const QHash<QByteArray, QByteArray> &identityMap); + void setIdentityDomain(const QString &identityDomain); int youngestRevision(); bool exportRevision(int revnum); |