# # # patch "src/model/GetContentChanged.cpp" # from [f3b84782ab44fdf363e2af70d5bee4b961afeefe] # to [ea013a6d430552f30584884170c6fb4af03119e4] # # patch "src/model/GetContentChanged.h" # from [441bbf74054ad6b6c8d316db82096d3b62fcedb1] # to [2caf1a98c245f56c89c7036aaf0814338b7327f7] # ============================================================ --- src/model/GetContentChanged.cpp f3b84782ab44fdf363e2af70d5bee4b961afeefe +++ src/model/GetContentChanged.cpp ea013a6d430552f30584884170c6fb4af03119e4 @@ -31,7 +31,12 @@ GetContentChanged::~GetContentChanged() GetContentChanged::~GetContentChanged() { + Q_ASSERT(commandStack.size() == 0); + Q_ASSERT(revsForPathStack.size() == 0); + revisions.clear(); + pathInRevision.clear(); + delete mtnDelegate; } @@ -47,39 +52,36 @@ GetContentChanged::~GetContentChanged() // |---------------> [ get content changed ] // | | // | V -// | [ add the rev(s) to the set ] +// | [ add the marked rev(s) to the list ] // | | // | V -// |------ < ------ [ get parents of rev(s) ] -> stop if no parents +// | [ get corresponding path for each marked rev ] // | | // | V -// | [ get corresponding path in the parent ] -> stop if no path +// |---- < ---- [ get parents of each marked rev ] -> stop if no parents // | | -// -------------- < ------------- +// | V +// |--- < --- [ get corresponding path for each parent ] -> stop if no path // bool GetContentChanged::readChanges(const QString & path) { - // clear current attributes list - revisions.clear(); + revisions.clear(); + pathInRevision.clear(); + // reset the view reset(); // find a starting point // FIXME: we assume that the given path is part of this revision! - QString startRev = MonotoneDelegate::getBaseWorkspaceRevision(this); + startRev = MonotoneDelegate::getBaseWorkspaceRevision(this); Q_ASSERT(!startRev.isNull()); - D(QString("Starting with %1").arg(startRev)); - - pathInRevision.insert(startRev, path); startPath = path; - return queryContentChanged(startRev, path); + return queryContentChanged(startRev, startPath); } bool GetContentChanged::queryContentChanged(const QString & rev, const QString & path) { - D(QString("get_content_changed for %1 starting from %2").arg(path).arg(rev)); - commandStack.enqueue(ContentChanged); QStringList cmd; @@ -89,26 +91,17 @@ bool GetContentChanged::queryParents(con bool GetContentChanged::queryParents(const QString & rev) { - D(QString("parents for %1").arg(rev)); - commandStack.enqueue(Parents); - revisionStack.enqueue(rev); QStringList cmd; cmd << "parents" << rev; return mtnDelegate->triggerCommand(cmd); } -bool GetContentChanged::queryCorrespondingPath(const QString & par) +bool GetContentChanged::queryCorrespondingPath(const QString & rev, const QString & path, const QString & par) { commandStack.enqueue(CorrespondingPath); - Q_ASSERT(!revisionStack.isEmpty()); - QString rev = revisionStack.dequeue(); - Q_ASSERT(pathInRevision.contains(rev)); - QString path = pathInRevision.value(rev); - D(QString("get_corresponding_path for %1, base %1, parent %2").arg(path).arg(rev).arg(par)); - QStringList cmd; cmd << "get_corresponding_path" << rev << path << par; return mtnDelegate->triggerCommand(cmd); @@ -127,15 +120,8 @@ void GetContentChanged::parseOutput() { if (AutomateCommand::data.isEmpty()) { - D("No parents found"); - - // no more commands in the queue? we're finished! - if (commandStack.size() == 0) - { - D("Finished"); - reset(); - emit changesRead(); - } + reset(); + emit rootReached(); return; } @@ -143,12 +129,10 @@ void GetContentChanged::parseOutput() '\n', QString::SkipEmptyParts ); - D(QString("Found parents %1").arg(parents.join(","))); - foreach (QString par, parents) { - parentStack.enqueue(par); - Q_ASSERT(queryCorrespondingPath(par)); + revsForPathStack.enqueue(par); + Q_ASSERT(queryCorrespondingPath(startRev, startPath, par)); } return; } @@ -167,28 +151,17 @@ void GetContentChanged::parseOutput() QString rev = st.at(0).hash; Q_ASSERT(!rev.isNull()); - D(QString("Next rev with content mark %1").arg(rev)); - if (!revisions.contains(rev)) { - // ensure that the current revision is also in the - // set of known revisions for this file - if (revisions.size() > 0) - { - QString lastMarkedRev = revisions.last(); - Q_ASSERT(pathInRevision.contains(lastMarkedRev)); - QString lastPath = pathInRevision.value(lastMarkedRev); - pathInRevision.insert(rev, lastPath); - } - else - { - // apparently this is the first marked revision we - // encounter, assign the startPath to it - pathInRevision.insert(rev, startPath); - } + // append the revision to the ordered list + revisions.append(rev); - // now append the revision itself in the ordered list - revisions.append(rev); + // add the revision to the stack of revs which need + // to get a valid path queried + revsForPathStack.enqueue(rev); + + // query for the corresponding path + Q_ASSERT(queryCorrespondingPath(startRev, startPath, rev)); } Q_ASSERT(queryParents(rev)); } @@ -197,19 +170,23 @@ void GetContentChanged::parseOutput() if (current == CorrespondingPath) { - // check if the file exists in the current revision, - // if not, stop here + Q_ASSERT(revsForPathStack.size() > 0); + QString rev = revsForPathStack.dequeue(); + D(AutomateCommand::data); if (AutomateCommand::data.isEmpty()) { - D("No corresponding path"); - - // no more commands in the queue? we're finished! - if (commandStack.size() == 0) + // check if this is a marked node, if so, + // we have a serious problem (node is changed in this rev, + // but has no corresponding path) + if (revisions.contains(rev)) { - D("Finished"); - reset(); - emit changesRead(); + Q_ASSERT(false); } + + // apparently this is another, not interesting (parent) node + // note that this can happen + reset(); + emit endOfLineReached(); return; } @@ -223,10 +200,10 @@ void GetContentChanged::parseOutput() Q_ASSERT(en.sym == "file" && en.vals.size() == 1); QString path = en.vals.at(0); - D(QString("Found path %1").arg(path)); + pathInRevision.insert(rev, path); - Q_ASSERT(!parentStack.isEmpty()); - Q_ASSERT(queryContentChanged(parentStack.dequeue(), path)); + // try to get the next marked node + Q_ASSERT(queryContentChanged(rev, path)); return; } ============================================================ --- src/model/GetContentChanged.h 441bbf74054ad6b6c8d316db82096d3b62fcedb1 +++ src/model/GetContentChanged.h 2caf1a98c245f56c89c7036aaf0814338b7327f7 @@ -50,12 +50,17 @@ signals: bool readChanges(const QString &); signals: - void changesRead(); + // is emitted each time the algorithm reaches the end of a + // particular development line for a specific file + void endOfLineReached(); + // is emitted if the root revision has been reached, + // which has per se no parent revisions + void rootReached(); private: bool queryContentChanged(const QString &, const QString &); bool queryParents(const QString &); - bool queryCorrespondingPath(const QString &); + bool queryCorrespondingPath(const QString &, const QString &, const QString &); void parseOutput(); bool handleError(int); @@ -66,10 +71,11 @@ private: enum Command { ContentChanged, CorrespondingPath, Parents }; QQueue commandStack; - QQueue revisionStack; - QQueue parentStack; + QQueue revsForPathStack; QMap pathInRevision; + + QString startRev; QString startPath; };