SVN commit 954165 by wiesel: Avoid calling external executable for checking wether a file is under version control or not. Cache the last successful repository root for speeding up deeply nested directories. M +39 -8 git/gitplugin.cpp M +1 -0 git/gitplugin.h M +11 -2 mercurial/mercurialplugin.cpp M +1 -0 mercurial/mercurialplugin.h --- trunk/KDE/kdevplatform/plugins/git/gitplugin.cpp #954164:954165 @@ -68,17 +68,48 @@ bool GitPlugin::isValidDirectory(const KUrl & dirPath) { - KDevelop::VcsJob* job = gitRevParse(dirPath.toLocalFile(), QStringList(QString("--is-inside-work-tree"))); - if (job) - { + static const QString gitDir(".git"); + const QString initialPath(dirPath.toLocalFile(KUrl::RemoveTrailingSlash)); + + KUrl possibleRepoRoot = m_lastRepoRoot; + if (!m_lastRepoRoot.isValid() || !m_lastRepoRoot.isParentOf(dirPath)) { + const QFileInfo finfo(initialPath); + QDir dir; + if (finfo.isFile()) { + dir = finfo.absoluteDir(); + } else { + dir = QDir(initialPath); + dir.makeAbsolute(); + } + + while (!dir.cd(gitDir) && dir.cdUp()) {} // cdUp, until there is a sub-directory called .git + + if (gitDir != dir.dirName()) { // We didn't find .git, so no need to call git + kDebug() << "Dir:" << dirPath << " is not inside work tree of git \"" << initialPath << '"'; + return false; + } + dir.cdUp(); + possibleRepoRoot.setDirectory(dir.absolutePath()); + } + + // We might have found a valid repository, call git to verify it + KDevelop::VcsJob* job = gitRevParse(possibleRepoRoot.toLocalFile(), QStringList(QString("--is-inside-work-tree"))); + + if (!job) { + kDebug() << "Failed creating job"; + return false; + } + job->exec(); - if (job->status() == KDevelop::VcsJob::JobSucceeded) - { - kDebug() << "Dir:" << dirPath << " is inside work tree of git" ; + if (job->status() == KDevelop::VcsJob::JobSucceeded) { + kDebug() << "Dir:" << dirPath << " is inside work tree of git (" << possibleRepoRoot << ')'; + m_lastRepoRoot = possibleRepoRoot; return true; + } else if (m_lastRepoRoot == possibleRepoRoot) { // Not a repository anymore + m_lastRepoRoot = KUrl(); // Restart from scratch + return isValidDirectory(dirPath); } - } - kDebug() << "Dir:" << dirPath.toLocalFile() << " is not inside work tree of git" ; + return false; } --- trunk/KDE/kdevplatform/plugins/git/gitplugin.h #954164:954165 @@ -123,6 +123,7 @@ static KDevelop::VcsStatusInfo::State lsTagToState(const char ch); QList branchesShas; + KUrl m_lastRepoRoot; }; #endif --- trunk/KDE/kdevplatform/plugins/mercurial/mercurialplugin.cpp #954164:954165 @@ -77,7 +77,11 @@ { // Mercurial uses the same test, so we don't lose any functionality static const QString hgDir(".hg"); - const QString initialPath(directory.toLocalFile()); + + if (m_lastRepoRoot.isParentOf(directory)) + return true; + + const QString initialPath(directory.toLocalFile(KUrl::RemoveTrailingSlash)); const QFileInfo finfo(initialPath); QDir dir; if (finfo.isFile()) { @@ -89,7 +93,12 @@ while (!dir.cd(hgDir) && dir.cdUp()) {} // cdUp, until there is a sub-directory called .hg - return hgDir == dir.dirName(); + if (hgDir != dir.dirName()) + return false; + + dir.cdUp(); // Leave .hg + m_lastRepoRoot.setDirectory(dir.absolutePath()); + return true; } bool MercurialPlugin::isVersionControlled(const KUrl & url) --- trunk/KDE/kdevplatform/plugins/mercurial/mercurialplugin.h #954164:954165 @@ -128,6 +128,7 @@ static KDevelop::VcsStatusInfo::State charToState(const char ch); QStringList getLsFiles(const QString &directory, const QStringList &args = QStringList()); + KUrl m_lastRepoRoot; }; #endif