Skip to content

Commit 3c2f294

Browse files
Vampiretnyblom
authored andcommitted
Determine the effective repository in case of forwarding when detecting cross-repository copies and merge points (#10)
1 parent 27c1cbb commit 3c2f294

File tree

3 files changed

+78
-41
lines changed

3 files changed

+78
-41
lines changed

src/repository.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ class FastImportRepository : public Repository
8989
void setBranchNote(const QString& branch, const QByteArray& noteText);
9090

9191
bool hasPrefix() const;
92+
93+
QString getName() const;
94+
Repository *getEffectiveRepository();
9295
private:
9396
struct Branch
9497
{
@@ -140,6 +143,7 @@ class FastImportRepository : public Repository
140143

141144
class ForwardingRepository : public Repository
142145
{
146+
QString name;
143147
Repository *repo;
144148
QString prefix;
145149
public:
@@ -170,7 +174,7 @@ class ForwardingRepository : public Repository
170174
{ return txn->commitNote(noteText, append, commit); }
171175
};
172176

173-
ForwardingRepository(Repository *r, const QString &p) : repo(r), prefix(p) {}
177+
ForwardingRepository(const QString &n, Repository *r, const QString &p) : name(n), repo(r), prefix(p) {}
174178

175179
int setupIncremental(int &) { return 1; }
176180
void restoreLog() {}
@@ -205,6 +209,11 @@ class ForwardingRepository : public Repository
205209

206210
bool hasPrefix() const
207211
{ return !prefix.isEmpty() || repo->hasPrefix(); }
212+
213+
QString getName() const
214+
{ return name; }
215+
Repository *getEffectiveRepository()
216+
{ return repo->getEffectiveRepository(); }
208217
};
209218

210219
class ProcessCache: QLinkedList<FastImportRepository *>
@@ -242,7 +251,7 @@ Repository *createRepository(const Rules::Repository &rule, const QHash<QString,
242251
qCritical() << "no repository with name" << rule.forwardTo << "found at" << rule.info();
243252
return r;
244253
}
245-
return new ForwardingRepository(r, rule.prefix);
254+
return new ForwardingRepository(rule.name, r, rule.prefix);
246255
}
247256

248257
static QString marksFileName(QString name)
@@ -780,6 +789,16 @@ bool FastImportRepository::hasPrefix() const
780789
return !prefix.isEmpty();
781790
}
782791

792+
QString FastImportRepository::getName() const
793+
{
794+
return name;
795+
}
796+
797+
Repository *FastImportRepository::getEffectiveRepository()
798+
{
799+
return this;
800+
}
801+
783802
FastImportRepository::Transaction::~Transaction()
784803
{
785804
repository->forgetTransaction(this);

src/repository.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ class Repository
139139
virtual void setBranchNote(const QString& branch, const QByteArray& noteText) = 0;
140140

141141
virtual bool hasPrefix() const = 0;
142+
143+
virtual QString getName() const = 0;
144+
virtual Repository *getEffectiveRepository() = 0;
142145
};
143146

144147
Repository *createRepository(const Rules::Repository &rule, const QHash<QString, Repository *> &repositories);

src/svn.cpp

Lines changed: 54 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -207,39 +207,6 @@ findMatchRule(const MatchRuleList &matchRules, int revnum, const QString &curren
207207
return end;
208208
}
209209

210-
static void splitPathName(const Rules::Match &rule, const QString &pathName, QString *svnprefix_p,
211-
QString *repository_p, QString *branch_p, QString *path_p)
212-
{
213-
QString svnprefix = pathName;
214-
svnprefix.truncate(rule.rx.matchedLength());
215-
216-
if (svnprefix_p) {
217-
*svnprefix_p = svnprefix;
218-
}
219-
220-
if (repository_p) {
221-
*repository_p = svnprefix;
222-
repository_p->replace(rule.rx, rule.repository);
223-
foreach (Rules::Match::Substitution subst, rule.repo_substs) {
224-
subst.apply(*repository_p);
225-
}
226-
}
227-
228-
if (branch_p) {
229-
*branch_p = svnprefix;
230-
branch_p->replace(rule.rx, rule.branch);
231-
foreach (Rules::Match::Substitution subst, rule.branch_substs) {
232-
subst.apply(*branch_p);
233-
}
234-
}
235-
236-
if (path_p) {
237-
QString prefix = svnprefix;
238-
prefix.replace(rule.rx, rule.prefix);
239-
*path_p = prefix + pathName.mid(svnprefix.length());
240-
}
241-
}
242-
243210
static int pathMode(svn_fs_root_t *fs_root, const char *pathname, apr_pool_t *pool)
244211
{
245212
svn_string_t *propvalue;
@@ -441,6 +408,9 @@ class SvnRevision
441408
int recurse(const char *path, const svn_fs_path_change2_t *change,
442409
const char *path_from, const MatchRuleList &matchRules, svn_revnum_t rev_from,
443410
apr_hash_t *changes, apr_pool_t *pool);
411+
private:
412+
void splitPathName(const Rules::Match &rule, const QString &pathName, QString *svnprefix_p,
413+
QString *repository_p, QString *effectiveRepository_p, QString *branch_p, QString *path_p);
444414
};
445415

446416
int SvnPrivate::exportRevision(int revnum)
@@ -473,6 +443,51 @@ int SvnPrivate::exportRevision(int revnum)
473443
return EXIT_SUCCESS;
474444
}
475445

446+
void SvnRevision::splitPathName(const Rules::Match &rule, const QString &pathName, QString *svnprefix_p,
447+
QString *repository_p, QString *effectiveRepository_p, QString *branch_p, QString *path_p)
448+
{
449+
QString svnprefix = pathName;
450+
svnprefix.truncate(rule.rx.matchedLength());
451+
452+
if (svnprefix_p) {
453+
*svnprefix_p = svnprefix;
454+
}
455+
456+
if (repository_p) {
457+
*repository_p = svnprefix;
458+
repository_p->replace(rule.rx, rule.repository);
459+
foreach (Rules::Match::Substitution subst, rule.repo_substs) {
460+
subst.apply(*repository_p);
461+
}
462+
}
463+
464+
if (effectiveRepository_p) {
465+
*effectiveRepository_p = svnprefix;
466+
effectiveRepository_p->replace(rule.rx, rule.repository);
467+
foreach (Rules::Match::Substitution subst, rule.repo_substs) {
468+
subst.apply(*effectiveRepository_p);
469+
}
470+
Repository *repository = repositories.value(*effectiveRepository_p, 0);
471+
if (repository) {
472+
*effectiveRepository_p = repository->getEffectiveRepository()->getName();
473+
}
474+
}
475+
476+
if (branch_p) {
477+
*branch_p = svnprefix;
478+
branch_p->replace(rule.rx, rule.branch);
479+
foreach (Rules::Match::Substitution subst, rule.branch_substs) {
480+
subst.apply(*branch_p);
481+
}
482+
}
483+
484+
if (path_p) {
485+
QString prefix = svnprefix;
486+
prefix.replace(rule.rx, rule.prefix);
487+
*path_p = prefix + pathName.mid(svnprefix.length());
488+
}
489+
}
490+
476491
int SvnRevision::prepareTransactions()
477492
{
478493
// find out what was changed in this revision:
@@ -690,8 +705,8 @@ int SvnRevision::exportInternal(const char *key, const svn_fs_path_change2_t *ch
690705
const QString &current, const Rules::Match &rule, const MatchRuleList &matchRules)
691706
{
692707
needCommit = true;
693-
QString svnprefix, repository, branch, path;
694-
splitPathName(rule, current, &svnprefix, &repository, &branch, &path);
708+
QString svnprefix, repository, effectiveRepository, branch, path;
709+
splitPathName(rule, current, &svnprefix, &repository, &effectiveRepository, &branch, &path);
695710

696711
Repository *repo = repositories.value(repository, 0);
697712
if (!repo) {
@@ -713,7 +728,7 @@ int SvnRevision::exportInternal(const char *key, const svn_fs_path_change2_t *ch
713728
}
714729

715730
QString previous;
716-
QString prevsvnprefix, prevrepository, prevbranch, prevpath;
731+
QString prevsvnprefix, prevrepository, preveffectiverepository, prevbranch, prevpath;
717732

718733
if (path_from != NULL) {
719734
previous = QString::fromUtf8(path_from);
@@ -724,7 +739,7 @@ int SvnRevision::exportInternal(const char *key, const svn_fs_path_change2_t *ch
724739
findMatchRule(matchRules, rev_from, previous, NoIgnoreRule);
725740
if (prevmatch != matchRules.constEnd()) {
726741
splitPathName(*prevmatch, previous, &prevsvnprefix, &prevrepository,
727-
&prevbranch, &prevpath);
742+
&preveffectiverepository, &prevbranch, &prevpath);
728743

729744
} else {
730745
qWarning() << "WARN: SVN reports a \"copy from\" @" << revnum << "from" << path_from << "@" << rev_from << "but no matching rules found! Ignoring copy, treating as a modification";
@@ -740,7 +755,7 @@ int SvnRevision::exportInternal(const char *key, const svn_fs_path_change2_t *ch
740755
<< qPrintable(prevrepository) << "branch"
741756
<< qPrintable(prevbranch) << "subdir"
742757
<< qPrintable(prevpath);
743-
} else if (prevrepository != repository) {
758+
} else if (preveffectiverepository != effectiveRepository) {
744759
qWarning() << "WARN:" << qPrintable(current) << "rev" << revnum
745760
<< "is a cross-repository copy (from repository"
746761
<< qPrintable(prevrepository) << "branch"
@@ -808,7 +823,7 @@ int SvnRevision::exportInternal(const char *key, const svn_fs_path_change2_t *ch
808823
// changes across directory re-organizations and wholesale branch
809824
// imports.
810825
//
811-
if (path_from != NULL && prevrepository == repository && prevbranch != branch) {
826+
if (path_from != NULL && preveffectiverepository == effectiveRepository && prevbranch != branch) {
812827
if(ruledebug)
813828
qDebug() << "copy from branch" << prevbranch << "to branch" << branch << "@rev" << rev_from;
814829
txn->noteCopyFromBranch (prevbranch, rev_from);

0 commit comments

Comments
 (0)