diff options
author | Friedemann Kleint <Friedemann.Kleint@nokia.com> | 2010-05-20 16:24:39 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@nokia.com> | 2010-05-20 16:24:56 +0200 |
commit | 7003b82e2ba68f24c9e5c27107aacd82898ba9cf (patch) | |
tree | 9b18d005e0b5f34089e82e9092ce852806d5a471 /src/plugins | |
parent | 58a5da63a8b698de6f7faae95afa9e783569353c (diff) | |
download | qt-creator-7003b82e2ba68f24c9e5c27107aacd82898ba9cf.tar.gz |
Version control: Improve detection.
Merge managesDirectory() and findTopLevelForDirectory()
into one giving managesDirectory() an optional topLevel
parameter. This removes the need to go up the directory
hierarchy twice when checking for Merurial or git and also
saves some checks for CVS/Subversion.
VCSManager: Check cache in reverse order starting out with
the full path first to improve handling of nested repositories.
Rubber-stamped-by: con
Acked-by: dt
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/coreplugin/iversioncontrol.h | 17 | ||||
-rw-r--r-- | src/plugins/coreplugin/vcsmanager.cpp | 40 | ||||
-rw-r--r-- | src/plugins/cvs/cvscontrol.cpp | 9 | ||||
-rw-r--r-- | src/plugins/cvs/cvscontrol.h | 3 | ||||
-rw-r--r-- | src/plugins/cvs/cvsplugin.cpp | 65 | ||||
-rw-r--r-- | src/plugins/cvs/cvsplugin.h | 5 | ||||
-rw-r--r-- | src/plugins/git/gitversioncontrol.cpp | 12 | ||||
-rw-r--r-- | src/plugins/git/gitversioncontrol.h | 3 | ||||
-rw-r--r-- | src/plugins/mercurial/mercurialcontrol.cpp | 18 | ||||
-rw-r--r-- | src/plugins/mercurial/mercurialcontrol.h | 3 | ||||
-rw-r--r-- | src/plugins/perforce/perforceplugin.cpp | 22 | ||||
-rw-r--r-- | src/plugins/perforce/perforceplugin.h | 4 | ||||
-rw-r--r-- | src/plugins/perforce/perforceversioncontrol.cpp | 22 | ||||
-rw-r--r-- | src/plugins/perforce/perforceversioncontrol.h | 4 | ||||
-rw-r--r-- | src/plugins/subversion/subversioncontrol.cpp | 9 | ||||
-rw-r--r-- | src/plugins/subversion/subversioncontrol.h | 3 | ||||
-rw-r--r-- | src/plugins/subversion/subversionplugin.cpp | 67 | ||||
-rw-r--r-- | src/plugins/subversion/subversionplugin.h | 6 | ||||
-rw-r--r-- | src/plugins/vcsbase/vcsbaseeditor.cpp | 4 |
19 files changed, 158 insertions, 158 deletions
diff --git a/src/plugins/coreplugin/iversioncontrol.h b/src/plugins/coreplugin/iversioncontrol.h index 8fe0bc038e..0cd29f9438 100644 --- a/src/plugins/coreplugin/iversioncontrol.h +++ b/src/plugins/coreplugin/iversioncontrol.h @@ -56,21 +56,12 @@ public: /*! * Returns whether files in this directory should be managed with this * version control. + * If \a topLevel is non-null, it should return the topmost directory, + * for which this IVersionControl should be used. The VCSManager assumes + * that all files in the returned directory are managed by the same IVersionControl. */ - virtual bool managesDirectory(const QString &filename) const = 0; - /*! - * This function should return the topmost directory, for which this - * IVersionControl should be used. The VCSManager assumes that all files in - * the returned directory are managed by the same IVersionControl. - * - * Note that this is used as an optimization, so that the VCSManager - * doesn't need to call managesDirectory(..) for each directory. - * - * This function is called after finding out that the directory is managed - * by a specific version control. - */ - virtual QString findTopLevelForDirectory(const QString &directory) const = 0; + virtual bool managesDirectory(const QString &filename, QString *topLevel = 0) const = 0; /*! * Called to query whether a VCS supports the respective operations. diff --git a/src/plugins/coreplugin/vcsmanager.cpp b/src/plugins/coreplugin/vcsmanager.cpp index 35d5b2f064..0221e29c9f 100644 --- a/src/plugins/coreplugin/vcsmanager.cpp +++ b/src/plugins/coreplugin/vcsmanager.cpp @@ -90,6 +90,18 @@ IVersionControl* VCSManager::findVersionControlForDirectory(const QString &direc QString *topLevelDirectory) { typedef VersionControlCache::const_iterator VersionControlCacheConstIterator; + + if (debug) { + qDebug(">findVersionControlForDirectory %s topLevelPtr %d", + qPrintable(directory), (topLevelDirectory != 0)); + if (debug > 1) { + const VersionControlCacheConstIterator cend = m_d->m_cachedMatches.constEnd(); + for (VersionControlCacheConstIterator it = m_d->m_cachedMatches.constBegin(); it != cend; ++it) + qDebug("Cache %s -> '%s'", qPrintable(it.key()), qPrintable(it.value()->displayName())); + } + } + QTC_ASSERT(!directory.isEmpty(), return 0); + const VersionControlCacheConstIterator cacheEnd = m_d->m_cachedMatches.constEnd(); if (topLevelDirectory) @@ -100,37 +112,51 @@ IVersionControl* VCSManager::findVersionControlForDirectory(const QString &direc if (fullPathIt != cacheEnd) { if (topLevelDirectory) *topLevelDirectory = directory; + if (debug) + qDebug("<findVersionControlForDirectory: full cache match for VCS '%s'", qPrintable(fullPathIt.value()->displayName())); return fullPathIt.value(); } - // Split the path, starting from top, try to find the matching repository - int pos = 0; + // Split the path, trying to find the matching repository. We start from the reverse + // in order to detected nested repositories correctly (say, a git checkout under SVN). + // Note that detection of a nested version control will still fail if the + // above-located version control is detected and entered into the cache first. + // The nested one can then no longer be found due to the splitting of the paths. + int pos = directory.size() - 1; const QChar slash = QLatin1Char('/'); while (true) { - const int index = directory.indexOf(slash, pos); - if (index == -1) + const int index = directory.lastIndexOf(slash, pos); + if (index <= 0) // Stop at '/' or not found break; const QString directoryPart = directory.left(index); const VersionControlCacheConstIterator it = m_d->m_cachedMatches.constFind(directoryPart); if (it != cacheEnd) { if (topLevelDirectory) *topLevelDirectory = it.key(); + if (debug) + qDebug("<findVersionControlForDirectory: cache match for VCS '%s', topLevel: %s", + qPrintable(it.value()->displayName()), qPrintable(it.key())); return it.value(); } - pos = index + 1; + pos = index - 1; } // Nothing: ask the IVersionControls directly, insert the toplevel into the cache. const VersionControlList versionControls = allVersionControls(); foreach (IVersionControl * versionControl, versionControls) { - if (versionControl->managesDirectory(directory)) { - const QString topLevel = versionControl->findTopLevelForDirectory(directory); + QString topLevel; + if (versionControl->managesDirectory(directory, &topLevel)) { m_d->m_cachedMatches.insert(topLevel, versionControl); if (topLevelDirectory) *topLevelDirectory = topLevel; + if (debug) + qDebug("<findVersionControlForDirectory: invocation of '%s' matches: %s", + qPrintable(versionControl->displayName()), qPrintable(topLevel)); return versionControl; } } + if (debug) + qDebug("<findVersionControlForDirectory: No match for %s", qPrintable(directory)); return 0; } diff --git a/src/plugins/cvs/cvscontrol.cpp b/src/plugins/cvs/cvscontrol.cpp index 42462006df..dbf8adf4b7 100644 --- a/src/plugins/cvs/cvscontrol.cpp +++ b/src/plugins/cvs/cvscontrol.cpp @@ -120,14 +120,9 @@ bool CVSControl::vcsAnnotate(const QString &file, int line) return true; } -bool CVSControl::managesDirectory(const QString &directory) const +bool CVSControl::managesDirectory(const QString &directory, QString *topLevel) const { - return m_plugin->managesDirectory(directory); -} - -QString CVSControl::findTopLevelForDirectory(const QString &directory) const -{ - return m_plugin->findTopLevelForDirectory(directory); + return m_plugin->managesDirectory(directory, topLevel); } void CVSControl::emitRepositoryChanged(const QString &s) diff --git a/src/plugins/cvs/cvscontrol.h b/src/plugins/cvs/cvscontrol.h index 38a8ccfe8e..4fd06c2de7 100644 --- a/src/plugins/cvs/cvscontrol.h +++ b/src/plugins/cvs/cvscontrol.h @@ -45,8 +45,7 @@ public: explicit CVSControl(CVSPlugin *plugin); virtual QString displayName() const; - virtual bool managesDirectory(const QString &directory) const; - virtual QString findTopLevelForDirectory(const QString &directory) const; + virtual bool managesDirectory(const QString &directory, QString *topLevel = 0) const; virtual bool supportsOperation(Operation operation) const; virtual bool vcsOpen(const QString &fileName); diff --git a/src/plugins/cvs/cvsplugin.cpp b/src/plugins/cvs/cvsplugin.cpp index 1f7e646fe1..1bdb606be6 100644 --- a/src/plugins/cvs/cvsplugin.cpp +++ b/src/plugins/cvs/cvsplugin.cpp @@ -827,8 +827,10 @@ void CVSPlugin::slotDescribe(const QString &source, const QString &changeNr) bool CVSPlugin::describe(const QString &file, const QString &changeNr, QString *errorMessage) { - const QString toplevel = findTopLevelForDirectory(QFileInfo(file).absolutePath()); - if (toplevel.isEmpty()) { + + QString toplevel; + const bool manages = managesDirectory(QFileInfo(file).absolutePath(), &toplevel); + if (!manages || toplevel.isEmpty()) { *errorMessage = msgCannotFindTopLevel(file); return false; } @@ -1122,45 +1124,44 @@ bool CVSPlugin::vcsDelete(const QString &workingDir, const QString &rawFileName) /* CVS has a "CVS" directory in each directory it manages. The top level * is the first directory under the directory that does not have it. */ -bool CVSPlugin::managesDirectory(const QString &directory) const +bool CVSPlugin::managesDirectory(const QString &directory, QString *topLevel /* = 0 */) const { + if (topLevel) + topLevel->clear(); + bool manages = false; const QDir dir(directory); - const bool rc = dir.exists() && managesDirectory(dir); - if (CVS::Constants::debug) - qDebug() << "CVSPlugin::managesDirectory" << directory << rc; - return rc; + do { + if (!dir.exists() || !checkCVSDirectory(dir)) + break; + manages = true; + if (!topLevel) + break; + /* Recursing up, the top level is a child of the first directory that does + * not have a "CVS" directory. The starting directory must be a managed + * one. Go up and try to find the first unmanaged parent dir. */ + QDir lastDirectory = dir; + for (QDir parentDir = lastDirectory; parentDir.cdUp() ; lastDirectory = parentDir) { + if (!checkCVSDirectory(parentDir)) { + *topLevel = lastDirectory.absolutePath(); + break; + } + } + } while (false); + if (CVS::Constants::debug) { + QDebug nsp = qDebug().nospace(); + nsp << "CVSPlugin::managesDirectory" << directory << manages; + if (topLevel) + nsp << *topLevel; + } + return manages; } -bool CVSPlugin::managesDirectory(const QDir &directory) const +bool CVSPlugin::checkCVSDirectory(const QDir &directory) const { const QString cvsDir = directory.absoluteFilePath(QLatin1String("CVS")); return QFileInfo(cvsDir).isDir(); } -QString CVSPlugin::findTopLevelForDirectory(const QString &directory) const -{ - // Debug wrapper - const QString rc = findTopLevelForDirectoryI(directory); - if (CVS::Constants::debug) - qDebug() << "CVSPlugin::findTopLevelForDirectory" << directory << rc; - return rc; -} - -QString CVSPlugin::findTopLevelForDirectoryI(const QString &directory) const -{ - /* Recursing up, the top level is a child of the first directory that does - * not have a "CVS" directory. The starting directory must be a managed - * one. Go up and try to find the first unmanaged parent dir. */ - QDir lastDirectory = QDir(directory); - if (!lastDirectory.exists() || !managesDirectory(lastDirectory)) - return QString(); - for (QDir parentDir = lastDirectory; parentDir.cdUp() ; lastDirectory = parentDir) { - if (!managesDirectory(parentDir)) - return lastDirectory.absolutePath(); - } - return QString(); -} - CVSControl *CVSPlugin::cvsVersionControl() const { return static_cast<CVSControl *>(versionControl()); diff --git a/src/plugins/cvs/cvsplugin.h b/src/plugins/cvs/cvsplugin.h index 1548729dff..c95cb8369f 100644 --- a/src/plugins/cvs/cvsplugin.h +++ b/src/plugins/cvs/cvsplugin.h @@ -95,8 +95,7 @@ public: // IVersionControl bool vcsAdd(const QString &workingDir, const QString &fileName); bool vcsDelete(const QString &workingDir, const QString &fileName); - bool managesDirectory(const QString &directory) const; - QString findTopLevelForDirectory(const QString &directory) const; + bool managesDirectory(const QString &directory, QString *topLevel = 0) const; static CVSPlugin *cvsPluginInstance(); @@ -145,7 +144,7 @@ private: void filelog(const QString &workingDir, const QStringList &files = QStringList(), bool enableAnnotationContextMenu = false); - bool managesDirectory(const QDir &directory) const; + bool checkCVSDirectory(const QDir &directory) const; QString findTopLevelForDirectoryI(const QString &directory) const; void startCommit(const QString &workingDir, const QStringList &files = QStringList()); bool commit(const QString &messageFile, const QStringList &subVersionFileList); diff --git a/src/plugins/git/gitversioncontrol.cpp b/src/plugins/git/gitversioncontrol.cpp index 65a46e492e..370e20bb27 100644 --- a/src/plugins/git/gitversioncontrol.cpp +++ b/src/plugins/git/gitversioncontrol.cpp @@ -206,14 +206,12 @@ bool GitVersionControl::vcsRemoveSnapshot(const QString &topLevel, const QString && gitClient()->synchronousStashRemove(topLevel, stashName); } -bool GitVersionControl::managesDirectory(const QString &directory) const +bool GitVersionControl::managesDirectory(const QString &directory, QString *topLevel) const { - return !GitClient::findRepositoryForDirectory(directory).isEmpty(); -} - -QString GitVersionControl::findTopLevelForDirectory(const QString &directory) const -{ - return GitClient::findRepositoryForDirectory(directory); + const QString topLevelFound = GitClient::findRepositoryForDirectory(directory); + if (topLevel) + *topLevel = topLevelFound; + return !topLevelFound.isEmpty(); } bool GitVersionControl::vcsAnnotate(const QString &file, int line) diff --git a/src/plugins/git/gitversioncontrol.h b/src/plugins/git/gitversioncontrol.h index 098d8bef52..35504747a7 100644 --- a/src/plugins/git/gitversioncontrol.h +++ b/src/plugins/git/gitversioncontrol.h @@ -46,8 +46,7 @@ public: virtual QString displayName() const; - bool managesDirectory(const QString &directory) const; - virtual QString findTopLevelForDirectory(const QString &directory) const; + virtual bool managesDirectory(const QString &directory, QString *topLevel) const; virtual bool supportsOperation(Operation operation) const; virtual bool vcsOpen(const QString &fileName); diff --git a/src/plugins/mercurial/mercurialcontrol.cpp b/src/plugins/mercurial/mercurialcontrol.cpp index e8cf97e1fb..61342dc350 100644 --- a/src/plugins/mercurial/mercurialcontrol.cpp +++ b/src/plugins/mercurial/mercurialcontrol.cpp @@ -47,16 +47,13 @@ QString MercurialControl::displayName() const return tr("Mercurial"); } -bool MercurialControl::managesDirectory(const QString &directory) const +bool MercurialControl::managesDirectory(const QString &directory, QString *topLevel) const { QFileInfo dir(directory); - return !mercurialClient->findTopLevelForFile(dir).isEmpty(); -} - -QString MercurialControl::findTopLevelForDirectory(const QString &directory) const -{ - QFileInfo dir(directory); - return mercurialClient->findTopLevelForFile(dir); + const QString topLevelFound = mercurialClient->findTopLevelForFile(dir); + if (topLevel) + *topLevel = topLevelFound; + return !topLevelFound.isEmpty(); } bool MercurialControl::supportsOperation(Operation operation) const @@ -137,8 +134,9 @@ bool MercurialControl::vcsAnnotate(const QString &file, int line) bool MercurialControl::sccManaged(const QString &filename) { const QFileInfo fi(filename); - const QString topLevel = findTopLevelForDirectory(fi.absolutePath()); - if (topLevel.isEmpty()) + QString topLevel; + const bool managed = managesDirectory(fi.absolutePath(), &topLevel); + if (!managed || topLevel.isEmpty()) return false; const QDir topLevelDir(topLevel); return mercurialClient->manifestSync(topLevel, topLevelDir.relativeFilePath(filename)); diff --git a/src/plugins/mercurial/mercurialcontrol.h b/src/plugins/mercurial/mercurialcontrol.h index 02be0951bb..b74fce99ff 100644 --- a/src/plugins/mercurial/mercurialcontrol.h +++ b/src/plugins/mercurial/mercurialcontrol.h @@ -50,8 +50,7 @@ public: explicit MercurialControl(MercurialClient *mercurialClient); QString displayName() const; - bool managesDirectory(const QString &filename) const; - QString findTopLevelForDirectory(const QString &directory) const; + bool managesDirectory(const QString &filename, QString *topLevel = 0) const; bool supportsOperation(Operation operation) const; bool vcsOpen(const QString &fileName); bool vcsAdd(const QString &filename); diff --git a/src/plugins/perforce/perforceplugin.cpp b/src/plugins/perforce/perforceplugin.cpp index fefa63b675..4a44dc43a5 100644 --- a/src/plugins/perforce/perforceplugin.cpp +++ b/src/plugins/perforce/perforceplugin.cpp @@ -848,7 +848,20 @@ void PerforcePlugin::updateActions(VCSBase::VCSBasePlugin::ActionState as) m_updateAllAction->setEnabled(true); } -bool PerforcePlugin::managesDirectory(const QString &directory) +bool PerforcePlugin::managesDirectory(const QString &directory, QString *topLevel /* = 0 */) +{ + const bool rc = managesDirectoryFstat(directory); + if (topLevel) { + if (rc) { + *topLevel = m_settings.topLevelSymLinkTarget(); + } else { + topLevel->clear(); + } + } + return rc; +} + +bool PerforcePlugin::managesDirectoryFstat(const QString &directory) { if (!m_settings.isValid()) return false; @@ -875,13 +888,6 @@ bool PerforcePlugin::managesDirectory(const QString &directory) return managed; } -QString PerforcePlugin::findTopLevelForDirectory(const QString &dir) -{ - if (!m_settings.isValid()) - return QString(); - return managesDirectory(dir) ? m_settings.topLevelSymLinkTarget() : QString(); -} - bool PerforcePlugin::vcsOpen(const QString &workingDir, const QString &fileName) { if (Perforce::Constants::debug) diff --git a/src/plugins/perforce/perforceplugin.h b/src/plugins/perforce/perforceplugin.h index feddd2bcf6..1e9cceb3ab 100644 --- a/src/plugins/perforce/perforceplugin.h +++ b/src/plugins/perforce/perforceplugin.h @@ -84,8 +84,7 @@ public: bool initialize(const QStringList &arguments, QString *error_message); void extensionsInitialized(); - bool managesDirectory(const QString &directory); - QString findTopLevelForDirectory(const QString &directory); + bool managesDirectory(const QString &directory, QString *topLevel = 0); bool vcsOpen(const QString &workingDir, const QString &fileName); bool vcsAdd(const QString &workingDir, const QString &fileName); bool vcsDelete(const QString &workingDir, const QString &filename); @@ -194,6 +193,7 @@ private: void updateCheckout(const QString &workingDir = QString(), const QStringList &dirs = QStringList()); bool revertProject(const QString &workingDir, const QStringList &args, bool unchangedOnly); + bool managesDirectoryFstat(const QString &directory); inline PerforceVersionControl *perforceVersionControl() const; diff --git a/src/plugins/perforce/perforceversioncontrol.cpp b/src/plugins/perforce/perforceversioncontrol.cpp index e715fa7ec8..2dc414f59c 100644 --- a/src/plugins/perforce/perforceversioncontrol.cpp +++ b/src/plugins/perforce/perforceversioncontrol.cpp @@ -120,19 +120,15 @@ bool PerforceVersionControl::vcsAnnotate(const QString &file, int line) return true; } -bool PerforceVersionControl::managesDirectory(const QString &directory) const -{ - const bool rc = m_plugin->managesDirectory(directory); - if (Perforce::Constants::debug) - qDebug() << "managesDirectory" << directory << rc; - return rc; -} - -QString PerforceVersionControl::findTopLevelForDirectory(const QString &directory) const -{ - const QString rc = m_plugin->findTopLevelForDirectory(directory); - if (Perforce::Constants::debug) - qDebug() << "findTopLevelForDirectory" << directory << rc; +bool PerforceVersionControl::managesDirectory(const QString &directory, QString *topLevel) const +{ + const bool rc = m_plugin->managesDirectory(directory, topLevel); + if (Perforce::Constants::debug) { + QDebug nsp = qDebug().nospace(); + nsp << "managesDirectory" << directory << rc; + if (topLevel) + nsp << topLevel; + } return rc; } diff --git a/src/plugins/perforce/perforceversioncontrol.h b/src/plugins/perforce/perforceversioncontrol.h index 9fe43af676..1e14cd2810 100644 --- a/src/plugins/perforce/perforceversioncontrol.h +++ b/src/plugins/perforce/perforceversioncontrol.h @@ -45,8 +45,8 @@ public: virtual QString displayName() const; - bool managesDirectory(const QString &directory) const; - virtual QString findTopLevelForDirectory(const QString &directory) const; + virtual bool managesDirectory(const QString &directory, QString *topLevel = 0) const; + virtual bool supportsOperation(Operation operation) const; virtual bool vcsOpen(const QString &fileName); diff --git a/src/plugins/subversion/subversioncontrol.cpp b/src/plugins/subversion/subversioncontrol.cpp index f7b4648dcb..f25fc3ab6a 100644 --- a/src/plugins/subversion/subversioncontrol.cpp +++ b/src/plugins/subversion/subversioncontrol.cpp @@ -114,14 +114,9 @@ bool SubversionControl::vcsRemoveSnapshot(const QString &, const QString &) return false; } -bool SubversionControl::managesDirectory(const QString &directory) const +bool SubversionControl::managesDirectory(const QString &directory, QString *topLevel) const { - return m_plugin->managesDirectory(directory); -} - -QString SubversionControl::findTopLevelForDirectory(const QString &directory) const -{ - return m_plugin->findTopLevelForDirectory(directory); + return m_plugin->managesDirectory(directory, topLevel); } bool SubversionControl::vcsAnnotate(const QString &file, int line) diff --git a/src/plugins/subversion/subversioncontrol.h b/src/plugins/subversion/subversioncontrol.h index 8389f82249..5610059d66 100644 --- a/src/plugins/subversion/subversioncontrol.h +++ b/src/plugins/subversion/subversioncontrol.h @@ -45,8 +45,7 @@ public: explicit SubversionControl(SubversionPlugin *plugin); virtual QString displayName() const; - virtual bool managesDirectory(const QString &directory) const; - virtual QString findTopLevelForDirectory(const QString &directory) const; + virtual bool managesDirectory(const QString &directory, QString *topLevel = 0) const; virtual bool supportsOperation(Operation operation) const; virtual bool vcsOpen(const QString &fileName); diff --git a/src/plugins/subversion/subversionplugin.cpp b/src/plugins/subversion/subversionplugin.cpp index 857bad4731..ff299b1912 100644 --- a/src/plugins/subversion/subversionplugin.cpp +++ b/src/plugins/subversion/subversionplugin.cpp @@ -940,8 +940,9 @@ void SubversionPlugin::describe(const QString &source, const QString &changeNr) // To describe a complete change, find the top level and then do //svn diff -r 472958:472959 <top level> const QFileInfo fi(source); - const QString topLevel = findTopLevelForDirectory(fi.isDir() ? source : fi.absolutePath()); - if (topLevel.isEmpty()) + QString topLevel; + const bool manages = managesDirectory(fi.isDir() ? source : fi.absolutePath(), &topLevel); + if (!manages || topLevel.isEmpty()) return; if (Subversion::Constants::debug) qDebug() << Q_FUNC_INFO << source << topLevel << changeNr; @@ -1184,7 +1185,7 @@ bool SubversionPlugin::vcsAdd14(const QString &workingDir, const QString &rawFil if (!path.isEmpty()) path += slash; path += relativePath.at(p); - if (!managesDirectory(QDir(path))) { + if (!checkSVNSubDir(QDir(path))) { QStringList addDirArgs; addDirArgs << QLatin1String("add") << QLatin1String("--non-recursive") << QDir::toNativeSeparators(path); const SubversionResponse addDirResponse = runSvn(workingDir, addDirArgs, m_settings.timeOutMS(), true); @@ -1224,16 +1225,40 @@ bool SubversionPlugin::vcsMove(const QString &workingDir, const QString &from, c /* Subversion has ".svn" directory in each directory * it manages. The top level is the first directory * under the directory that does not have a ".svn". */ -bool SubversionPlugin::managesDirectory(const QString &directory) const +bool SubversionPlugin::managesDirectory(const QString &directory, QString *topLevel /* = 0 */) const { const QDir dir(directory); - const bool rc = dir.exists() && managesDirectory(dir); - if (Subversion::Constants::debug) - qDebug() << "SubversionPlugin::managesDirectory" << directory << rc; - return rc; + if (topLevel) + topLevel->clear(); + bool manages = false; + do { + if (!dir.exists() || !checkSVNSubDir(dir)) + break; + manages = true; + if (!topLevel) + break; + /* Recursing up, the top level is a child of the first directory that does + * not have a ".svn" directory. The starting directory must be a managed + * one. Go up and try to find the first unmanaged parent dir. */ + QDir lastDirectory = dir; + for (QDir parentDir = lastDirectory; parentDir.cdUp() ; lastDirectory = parentDir) { + if (!checkSVNSubDir(parentDir)) { + *topLevel = lastDirectory.absolutePath(); + break; + } + } + } while (false); + if (Subversion::Constants::debug) { + QDebug nsp = qDebug().nospace(); + nsp << "SubversionPlugin::managesDirectory" << directory << manages; + if (topLevel) + nsp << *topLevel; + } + return manages; } -bool SubversionPlugin::managesDirectory(const QDir &directory) const +// Check whether SVN management subdirs exist. +bool SubversionPlugin::checkSVNSubDir(const QDir &directory) const { const int dirCount = m_svnDirectories.size(); for (int i = 0; i < dirCount; i++) { @@ -1244,30 +1269,6 @@ bool SubversionPlugin::managesDirectory(const QDir &directory) const return false; } -QString SubversionPlugin::findTopLevelForDirectory(const QString &directory) const -{ - // Debug wrapper - const QString rc = findTopLevelForDirectoryI(directory); - if (Subversion::Constants::debug) - qDebug() << "SubversionPlugin::findTopLevelForDirectory" << directory << rc; - return rc; -} - -QString SubversionPlugin::findTopLevelForDirectoryI(const QString &directory) const -{ - /* Recursing up, the top level is a child of the first directory that does - * not have a ".svn" directory. The starting directory must be a managed - * one. Go up and try to find the first unmanaged parent dir. */ - QDir lastDirectory = QDir(directory); - if (!lastDirectory.exists() || !managesDirectory(lastDirectory)) - return QString(); - for (QDir parentDir = lastDirectory; parentDir.cdUp() ; lastDirectory = parentDir) { - if (!managesDirectory(parentDir)) - return lastDirectory.absolutePath(); - } - return QString(); -} - SubversionControl *SubversionPlugin::subVersionControl() const { return static_cast<SubversionControl *>(versionControl()); diff --git a/src/plugins/subversion/subversionplugin.h b/src/plugins/subversion/subversionplugin.h index a7bb187c56..278cb2d303 100644 --- a/src/plugins/subversion/subversionplugin.h +++ b/src/plugins/subversion/subversionplugin.h @@ -95,8 +95,7 @@ public: bool vcsAdd15(const QString &workingDir, const QString &fileName); bool vcsDelete(const QString &workingDir, const QString &fileName); bool vcsMove(const QString &workingDir, const QString &from, const QString &to); - bool managesDirectory(const QString &directory) const; - QString findTopLevelForDirectory(const QString &directory) const; + bool managesDirectory(const QString &directory, QString *topLevel = 0) const; static SubversionPlugin *subversionPluginInstance(); @@ -145,8 +144,7 @@ private: bool enableAnnotationContextMenu = false); void svnStatus(const QString &workingDir, const QStringList &relativePath = QStringList()); void svnUpdate(const QString &workingDir, const QStringList &relativePaths = QStringList()); - bool managesDirectory(const QDir &directory) const; - QString findTopLevelForDirectoryI(const QString &directory) const; + bool checkSVNSubDir(const QDir &directory) const; void startCommit(const QString &workingDir, const QStringList &files = QStringList()); bool commit(const QString &messageFile, const QStringList &subVersionFileList); void cleanCommitMessageFile(); diff --git a/src/plugins/vcsbase/vcsbaseeditor.cpp b/src/plugins/vcsbase/vcsbaseeditor.cpp index 67b3e80901..815a062247 100644 --- a/src/plugins/vcsbase/vcsbaseeditor.cpp +++ b/src/plugins/vcsbase/vcsbaseeditor.cpp @@ -821,8 +821,8 @@ QString VCSBaseEditor::findDiffFile(const QString &f, Core::IVersionControl *con // Try to locate via repository. if (!control) return QString(); - const QString topLevel = control->findTopLevelForDirectory(sourceDir); - if (topLevel.isEmpty()) + QString topLevel; + if (!control->managesDirectory(sourceDir, &topLevel)) return QString(); const QFileInfo topLevelFileInfo(topLevel + slash + f); if (topLevelFileInfo.isFile()) |