From b4b177fa27a084eef4e77df299987f9c90daab88 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint <Friedemann.Kleint@nokia.com> Date: Wed, 19 May 2010 17:41:14 +0200 Subject: [PATCH] VCS[git/hg]: Prevent search for repository from creating folders ... when autofs is involved. Check for files instead of folders and stop checking/recursing up at '/' or $HOME. Further fixup will follow. Task-number: QTCREATORBUG-1361 Task-number: QTBUG-10495 --- src/plugins/git/gitclient.cpp | 11 +++---- src/plugins/git/gitclient.h | 3 -- src/plugins/mercurial/mercurialclient.cpp | 13 +++----- src/plugins/vcsbase/vcsbaseplugin.cpp | 36 ++++++++++++++++++++++- src/plugins/vcsbase/vcsbaseplugin.h | 6 ++++ 5 files changed, 49 insertions(+), 20 deletions(-) diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 8248d18d0d6..d613a604c8e 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -52,6 +52,7 @@ #include <utils/synchronousprocess.h> #include <vcsbase/vcsbaseeditor.h> #include <vcsbase/vcsbaseoutputwindow.h> +#include <vcsbase/vcsbaseplugin.h> #include <projectexplorer/environment.h> @@ -155,13 +156,9 @@ const char *GitClient::noColorOption = "--no-color"; QString GitClient::findRepositoryForDirectory(const QString &dir) { - const QString gitDirectory = QLatin1String(kGitDirectoryC); - QDir directory(dir); - do { - if (QFileInfo(directory, gitDirectory).isDir()) - return directory.absolutePath(); - } while (directory.cdUp()); - return QString(); + // Check for ".git/config" + const QString checkFile = QLatin1String(kGitDirectoryC) + QLatin1String("/config"); + return VCSBase::VCSBasePlugin::findRepositoryForDirectory(dir, checkFile); } /* Create an editor associated to VCS output of a source file/directory diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index 3f0d0dede7e..26423fce1d5 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -72,9 +72,6 @@ public: explicit GitClient(GitPlugin *plugin); ~GitClient(); - bool managesDirectory(const QString &) const { return false; } - QString findTopLevelForDirectory(const QString &) const { return QString(); } - static QString findRepositoryForDirectory(const QString &dir); void diff(const QString &workingDirectory, const QStringList &diffArgs, const QString &fileName); diff --git a/src/plugins/mercurial/mercurialclient.cpp b/src/plugins/mercurial/mercurialclient.cpp index 9a4bbabb856..ff78f0dc4bb 100644 --- a/src/plugins/mercurial/mercurialclient.cpp +++ b/src/plugins/mercurial/mercurialclient.cpp @@ -556,15 +556,10 @@ void MercurialClient::commit(const QString &repositoryRoot, const QStringList &f QString MercurialClient::findTopLevelForFile(const QFileInfo &file) { - const QString repositoryTopDir = QLatin1String(Constants::MECURIALREPO); - QDir dir = file.isDir() ? QDir(file.absoluteFilePath()) : QDir(file.absolutePath()); - - do { - if (QFileInfo(dir, repositoryTopDir).exists()) - return dir.absolutePath(); - } while (dir.cdUp()); - - return QString(); + const QString repositoryCheckFile = QLatin1String(Constants::MECURIALREPO) + QLatin1String("/requires"); + return file.isDir() ? + VCSBase::VCSBasePlugin::findRepositoryForDirectory(file.absoluteFilePath(), repositoryCheckFile) : + VCSBase::VCSBasePlugin::findRepositoryForDirectory(file.absolutePath(), repositoryCheckFile); } void MercurialClient::settingsChanged() diff --git a/src/plugins/vcsbase/vcsbaseplugin.cpp b/src/plugins/vcsbase/vcsbaseplugin.cpp index 8cc60f0cfeb..7b1c3f40c1c 100644 --- a/src/plugins/vcsbase/vcsbaseplugin.cpp +++ b/src/plugins/vcsbase/vcsbaseplugin.cpp @@ -54,7 +54,7 @@ #include <QtGui/QFileDialog> #include <QtGui/QMainWindow> -enum { debug = 0 }; +enum { debug = 0, debugRepositorySearch = 0 }; namespace VCSBase { @@ -636,6 +636,40 @@ void VCSBasePlugin::slotTestRemoveSnapshot() d->m_testLastSnapshot.clear(); } +// Find top level for version controls like git/Mercurial that have +// a directory at the top of the repository. +// Note that checking for the existence of files is preferred over directories +// since checking for directories can cause them to be created when +// AutoFS is used (due its automatically creating mountpoints when querying +// a directory). In addition, bail out when reaching the home directory +// of the user or root (generally avoid '/', where mountpoints are created). +QString VCSBasePlugin::findRepositoryForDirectory(const QString &dirS, + const QString &checkFile) +{ + if (debugRepositorySearch) + qDebug() << ">VCSBasePlugin::findRepositoryForDirectory" << dirS << checkFile; + QTC_ASSERT(!dirS.isEmpty() && !checkFile.isEmpty(), return QString()); + + const QString root = QDir::rootPath(); + const QString home = QDir::homePath(); + + QDir directory(dirS); + do { + const QString absDirPath = directory.absolutePath(); + if (absDirPath == root || absDirPath == home) + break; + + if (QFileInfo(directory, checkFile).isFile()) { + if (debugRepositorySearch) + qDebug() << "<VCSBasePlugin::findRepositoryForDirectory> " << absDirPath; + return absDirPath; + } + } while (directory.cdUp()); + if (debugRepositorySearch) + qDebug() << "<VCSBasePlugin::findRepositoryForDirectory bailing out at " << directory.absolutePath(); + return QString(); +} + } // namespace VCSBase #include "vcsbaseplugin.moc" diff --git a/src/plugins/vcsbase/vcsbaseplugin.h b/src/plugins/vcsbase/vcsbaseplugin.h index 9574ee71b83..5d697fa3af9 100644 --- a/src/plugins/vcsbase/vcsbaseplugin.h +++ b/src/plugins/vcsbase/vcsbaseplugin.h @@ -163,6 +163,12 @@ public: // For internal tests: Create actions driving IVersionControl's snapshot interface. QList<QAction*> createSnapShotTestActions(); + // Convenience that searches for the repository specifically for version control + // systems that do not have directories like "CVS" in each managed subdirectory + // but have a directory at the top of the repository like ".git" containing + // a well known file. See implementation for gory details. + static QString findRepositoryForDirectory(const QString &dir, const QString &checkFile); + public slots: // Convenience slot for "Delete current file" action. Prompts to // delete the file via VCSManager. -- GitLab