diff --git a/src/plugins/coreplugin/basefilewizard.cpp b/src/plugins/coreplugin/basefilewizard.cpp index 054e560bd8a3018c0202f633b88e21bd907b3f56..e30f27168e0e72daad614bdb0e514b4810fb27fa 100644 --- a/src/plugins/coreplugin/basefilewizard.cpp +++ b/src/plugins/coreplugin/basefilewizard.cpp @@ -69,12 +69,14 @@ public: QString editorId; bool binary; GeneratedFile::Attributes attributes; + bool writeAccess; }; GeneratedFilePrivate::GeneratedFilePrivate(const QString &p) : path(p), binary(false), - attributes(0) + attributes(0), + writeAccess(true) { } @@ -104,6 +106,11 @@ GeneratedFile::~GeneratedFile() { } +void GeneratedFile::writeAccess(bool access) +{ + m_d->writeAccess = access; +} + QString GeneratedFile::path() const { return m_d->path; @@ -156,6 +163,9 @@ void GeneratedFile::setEditorId(const QString &k) bool GeneratedFile::write(QString *errorMessage) const { + if (!m_d->writeAccess) + return true; + // Ensure the directory const QFileInfo info(m_d->path); const QDir dir = info.absoluteDir(); diff --git a/src/plugins/coreplugin/basefilewizard.h b/src/plugins/coreplugin/basefilewizard.h index 614cabebbd02355c931915fb91bcd22570c316dc..2fcab7e6d2b539ec433927ee98b7e93ee9f49a12 100644 --- a/src/plugins/coreplugin/basefilewizard.h +++ b/src/plugins/coreplugin/basefilewizard.h @@ -101,6 +101,7 @@ public: void setEditorId(const QString &k); bool write(QString *errorMessage) const; + void writeAccess(bool access = true); Attributes attributes() const; void setAttributes(Attributes a); diff --git a/src/plugins/coreplugin/iversioncontrol.h b/src/plugins/coreplugin/iversioncontrol.h index c402c1fb77c8ef3c316fe6bfb8c06acb53e1fe0e..e00be8f69dba27f7ed4c01ec1a9e615a22cea039 100644 --- a/src/plugins/coreplugin/iversioncontrol.h +++ b/src/plugins/coreplugin/iversioncontrol.h @@ -52,7 +52,9 @@ public: AddOperation, DeleteOperation, OpenOperation, MoveOperation, CreateRepositoryOperation, SnapshotOperations, - AnnotateOperation + AnnotateOperation, + CheckoutOperation, + GetRepositoryRootOperation }; explicit IVersionControl(QObject *parent = 0) : QObject(parent) {} @@ -116,6 +118,16 @@ public: */ virtual bool vcsCreateRepository(const QString &directory) = 0; + /*! + * Called to clone/checkout the version control system in a directory. + */ + virtual bool vcsCheckout(const QString &directory,const QByteArray &url) = 0; + + /*! + * Called to get the version control repository root. + */ + virtual QString vcsGetRepositoryURL(const QString &director) = 0; + /*! * Create a snapshot of the current state and return an identifier or * an empty string in case of failure. diff --git a/src/plugins/coreplugin/vcsmanager.cpp b/src/plugins/coreplugin/vcsmanager.cpp index 0221e29c9fa2a4ecf401fe67045da5fd60bcfa1e..ac7e18fb3af61f3392d279041ac0292954877947 100644 --- a/src/plugins/coreplugin/vcsmanager.cpp +++ b/src/plugins/coreplugin/vcsmanager.cpp @@ -167,6 +167,42 @@ bool VCSManager::promptToDelete(const QString &fileName) return true; } +IVersionControl* VCSManager::checkout(const QString &versionControlType, + const QString &directory, + const QByteArray &url) +{ + foreach (IVersionControl * versionControl, allVersionControls()) { + if (versionControl->displayName() == versionControlType && + versionControl->supportsOperation(Core::IVersionControl::CheckoutOperation)) { + if (versionControl->vcsCheckout(directory,url)) { + m_d->m_cachedMatches.insert(directory, versionControl); + return versionControl; + } + return 0; + } + } + return 0; +} + +bool VCSManager::findVersionControl(const QString &versionControlType) +{ + foreach (IVersionControl * versionControl, allVersionControls()) { + if (versionControl->displayName() == versionControlType) { + return true; + } + } + return false; +} + +QString VCSManager::getRepositoryURL(const QString &directory) +{ + IVersionControl *vc = findVersionControlForDirectory(directory); + + if (vc && vc->supportsOperation(Core::IVersionControl::GetRepositoryRootOperation)) + return vc->vcsGetRepositoryURL(directory); + return QString(); +} + bool VCSManager::promptToDelete(IVersionControl *vc, const QString &fileName) { QTC_ASSERT(vc, return true) diff --git a/src/plugins/coreplugin/vcsmanager.h b/src/plugins/coreplugin/vcsmanager.h index 71e9b3e9c34542569e2da6bcd8ac8e01601d149d..6b2e374a8833517babb22f55b7e42dc39d0d49e2 100644 --- a/src/plugins/coreplugin/vcsmanager.h +++ b/src/plugins/coreplugin/vcsmanager.h @@ -68,6 +68,11 @@ public: IVersionControl *findVersionControlForDirectory(const QString &directory, QString *topLevelDirectory = 0); + IVersionControl *checkout(const QString &versionControlType, + const QString &directory, + const QByteArray &url); + bool findVersionControl(const QString &versionControl); + QString getRepositoryURL(const QString &directory); // Shows a confirmation dialog, whether the file should also be deleted // from revision control Calls sccDelete on the file. Returns false diff --git a/src/plugins/cvs/cvscontrol.cpp b/src/plugins/cvs/cvscontrol.cpp index 41268e79f07cddc638050f83b9b73f0ff85f2ad5..7fd757a4f822fa7d9eea395c22f5a26db2dbbd57 100644 --- a/src/plugins/cvs/cvscontrol.cpp +++ b/src/plugins/cvs/cvscontrol.cpp @@ -58,6 +58,8 @@ bool CVSControl::supportsOperation(Operation operation) const case MoveOperation: case CreateRepositoryOperation: case SnapshotOperations: + case CheckoutOperation: + case GetRepositoryRootOperation: rc = false; break; } @@ -94,6 +96,16 @@ bool CVSControl::vcsCreateRepository(const QString &) return false; } +QString CVSControl::vcsGetRepositoryURL(const QString &) +{ + return QString(); +} + +bool CVSControl::vcsCheckout(const QString &/*directory*/, const QByteArray &/*url*/) +{ + return false; +} + QString CVSControl::vcsCreateSnapshot(const QString &) { return QString(); diff --git a/src/plugins/cvs/cvscontrol.h b/src/plugins/cvs/cvscontrol.h index 4fd06c2de72d1be2df14d4c1474048d3a0aece31..b5b882d44255023b67047803b6a84120a057784b 100644 --- a/src/plugins/cvs/cvscontrol.h +++ b/src/plugins/cvs/cvscontrol.h @@ -53,6 +53,8 @@ public: virtual bool vcsDelete(const QString &filename); virtual bool vcsMove(const QString &from, const QString &to); virtual bool vcsCreateRepository(const QString &directory); + virtual bool vcsCheckout(const QString &directory, const QByteArray &url); + virtual QString vcsGetRepositoryURL(const QString &directory); virtual QString vcsCreateSnapshot(const QString &topLevel); virtual QStringList vcsSnapshots(const QString &topLevel); virtual bool vcsRestoreSnapshot(const QString &topLevel, const QString &name); diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 48f5c5a893dc016e69224411ab0643469ca3ad5d..47b74c8e4a325ce04fe668ba1d8b62b8f74e4b09 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -50,6 +50,7 @@ #include <texteditor/itexteditor.h> #include <utils/qtcassert.h> #include <utils/synchronousprocess.h> +#include <utils/environment.h> #include <vcsbase/vcsbaseeditor.h> #include <vcsbase/vcsbaseoutputwindow.h> #include <vcsbase/vcsbaseplugin.h> @@ -1922,6 +1923,61 @@ QString GitClient::readConfigValue(const QString &workingDirectory, const QStrin return readConfig(workingDirectory, QStringList(configVar)).remove(QLatin1Char('\n')); } +bool GitClient::cloneRepository(const QString &directory,const QByteArray &url) +{ + QDir workingDirectory(directory); + const unsigned flags = VCSBase::VCSBasePlugin::SshPasswordPrompt + |VCSBase::VCSBasePlugin::ShowStdOutInLogWindow + |VCSBase::VCSBasePlugin::ShowSuccessMessage; + + if (workingDirectory.exists()) { + if (!synchronousInit(workingDirectory.path())) + return false; + + QStringList arguments(QLatin1String("remote")); + arguments << QLatin1String("add") << QLatin1String("origin") << url; + if (!fullySynchronousGit(workingDirectory.path(),arguments,0,0,true)) + return false; + + arguments.clear(); + arguments << QLatin1String("fetch"); + const Utils::SynchronousProcessResponse resp = synchronousGit(workingDirectory.path(),arguments,flags); + if (resp.result != Utils::SynchronousProcessResponse::Finished) + return false; + + arguments.clear(); + arguments << QLatin1String("config") << QLatin1String("branch.master.remote") << QLatin1String("origin"); + if (!fullySynchronousGit(workingDirectory.path(),arguments,0,0,true)) + return false; + + arguments.clear(); + arguments << QLatin1String("config") << QLatin1String("branch.master.merge") << QLatin1String("refs/heads/master"); + if (!fullySynchronousGit(workingDirectory.path(),arguments,0,0,true)) + return false; + + return true; + } else { + QStringList arguments(QLatin1String("clone")); + arguments << url << workingDirectory.dirName(); + workingDirectory.cdUp(); + const Utils::SynchronousProcessResponse resp = synchronousGit(workingDirectory.path(),arguments,flags); + return resp.result == Utils::SynchronousProcessResponse::Finished; + } +} + +QString GitClient::vcsGetRepositoryURL(const QString &directory) +{ + QStringList arguments(QLatin1String("config")); + QByteArray outputText; + + arguments << QLatin1String("remote.origin.url"); + + if (fullySynchronousGit(directory,arguments,&outputText,0,false)) { + return commandOutputFromLocal8Bit(outputText); + } + return QString(); +} + GitSettings GitClient::settings() const { return m_settings; diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index 9de9844788958d65860cd3a4ce5df06c3e5b3be8..5ece27c93941eed787d18bd2e839caac832d95de 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -158,6 +158,8 @@ public: unsigned gitVersion(bool silent, QString *errorMessage = 0); QString gitVersionString(bool silent, QString *errorMessage = 0); + bool cloneRepository(const QString &directory,const QByteArray &url); + QString vcsGetRepositoryURL(const QString &directory); bool synchronousFetch(const QString &workingDirectory); bool synchronousPull(const QString &workingDirectory); bool synchronousPush(const QString &workingDirectory); diff --git a/src/plugins/git/gitversioncontrol.cpp b/src/plugins/git/gitversioncontrol.cpp index 370e20bb2704a1ab835183519f4e09126f6a290c..862bd04dd01bc7876750f296f5380a3f55dc9fba 100644 --- a/src/plugins/git/gitversioncontrol.cpp +++ b/src/plugins/git/gitversioncontrol.cpp @@ -87,6 +87,10 @@ bool GitVersionControl::supportsOperation(Operation operation) const case AnnotateOperation: rc = true; break; + case CheckoutOperation: + case GetRepositoryRootOperation: + rc = true; + break; } return rc; } @@ -121,6 +125,17 @@ bool GitVersionControl::vcsCreateRepository(const QString &directory) { return gitClient()->synchronousInit(directory); } + +bool GitVersionControl::vcsCheckout(const QString &directory,const QByteArray &url) +{ + return gitClient()->cloneRepository(directory,url); +} + +QString GitVersionControl::vcsGetRepositoryURL(const QString &directory) +{ + return gitClient()->vcsGetRepositoryURL(directory); +} + /* Snapshots are implement using stashes, relying on stash messages for * naming as the actual stash names (stash{n}) are rotated as one adds stashes. * Note that the snapshot interface does not care whether we have an unmodified diff --git a/src/plugins/git/gitversioncontrol.h b/src/plugins/git/gitversioncontrol.h index 35504747a7ca3ecf284cca76ec081b85ee369ca8..0d7276a392df0eb53060c88f3e4937d25f6a9f2e 100644 --- a/src/plugins/git/gitversioncontrol.h +++ b/src/plugins/git/gitversioncontrol.h @@ -54,6 +54,8 @@ public: virtual bool vcsDelete(const QString &filename); virtual bool vcsMove(const QString &from, const QString &to); virtual bool vcsCreateRepository(const QString &directory); + virtual bool vcsCheckout(const QString &directory, const QByteArray &url); + virtual QString vcsGetRepositoryURL(const QString &directory); virtual QString vcsCreateSnapshot(const QString &topLevel); virtual QStringList vcsSnapshots(const QString &topLevel); virtual bool vcsRestoreSnapshot(const QString &topLevel, const QString &name); diff --git a/src/plugins/mercurial/mercurialclient.cpp b/src/plugins/mercurial/mercurialclient.cpp index 3cc71ca7aa0ce15fa50796d5ba85d5c11483ea1b..8f06d4d5531492a88d014759ef29681e8e8d6c2d 100644 --- a/src/plugins/mercurial/mercurialclient.cpp +++ b/src/plugins/mercurial/mercurialclient.cpp @@ -497,6 +497,63 @@ bool MercurialClient::pushSync(const QString &repositoryRoot, const QString &rep return resp.result == Utils::SynchronousProcessResponse::Finished; } +bool MercurialClient::clone(const QString &directory, const QString &url) +{ + QDir workingDirectory(directory); + QByteArray output; + const unsigned flags = VCSBase::VCSBasePlugin::SshPasswordPrompt|VCSBase::VCSBasePlugin::ShowStdOutInLogWindow + |VCSBase::VCSBasePlugin::ShowSuccessMessage; + + if (workingDirectory.exists()) { + // Let's make first init + QStringList arguments(QLatin1String("init")); + if (!executeHgFullySynchronously(workingDirectory.path(), arguments, &output)) { + return false; + } + + // Then pull remote repository + arguments.clear(); + arguments << QLatin1String("pull") << url; + const Utils::SynchronousProcessResponse resp1 = + executeHgSynchronously(workingDirectory.path(), arguments, flags); + if (resp1.result != Utils::SynchronousProcessResponse::Finished) { + return false; + } + + // By now, there is no hgrc file -> create it + QFile hgrc(workingDirectory.path()+"/.hg/hgrc"); + hgrc.open(QIODevice::WriteOnly); + hgrc.write(QString("[paths]\ndefault = %1\n").arg(QString(url)).toUtf8()); + hgrc.close(); + + // And last update repository + arguments.clear(); + arguments << QLatin1String("update"); + const Utils::SynchronousProcessResponse resp2 = + executeHgSynchronously(workingDirectory.path(), arguments, flags); + return resp2.result == Utils::SynchronousProcessResponse::Finished; + } else { + QStringList arguments(QLatin1String("clone")); + arguments << url << workingDirectory.dirName(); + workingDirectory.cdUp(); + const Utils::SynchronousProcessResponse resp = + executeHgSynchronously(workingDirectory.path(), arguments, flags); + return resp.result == Utils::SynchronousProcessResponse::Finished; + } +} + +QString MercurialClient::vcsGetRepositoryURL(const QString &directory) +{ + QByteArray output; + + QStringList arguments(QLatin1String("showconfig")); + arguments << QLatin1String("paths.default"); + + if (executeHgFullySynchronously(directory, arguments, &output)) + return QString::fromLocal8Bit(output);; + return QString(); +} + void MercurialClient::incoming(const QString &repositoryRoot, const QString &repository) { QStringList args; diff --git a/src/plugins/mercurial/mercurialclient.h b/src/plugins/mercurial/mercurialclient.h index f6ea3a3d28b47db515cdd7330bf8e4db5309ed12..8750d0fbb237fb7b5d5a313010c29ac063f227ef 100644 --- a/src/plugins/mercurial/mercurialclient.h +++ b/src/plugins/mercurial/mercurialclient.h @@ -100,6 +100,8 @@ public: const QString &commiterInfo, const QString &commitMessageFile, bool autoAddRemove = false); + bool clone(const QString &directory, const QString &url); + QString vcsGetRepositoryURL(const QString &directory); static QString findTopLevelForFile(const QFileInfo &file); diff --git a/src/plugins/mercurial/mercurialcontrol.cpp b/src/plugins/mercurial/mercurialcontrol.cpp index 61342dc3507b8505d16ff887b6a8c9352c248842..dc84b9919b437c6e44e7f61e6b6412930757d5e4 100644 --- a/src/plugins/mercurial/mercurialcontrol.cpp +++ b/src/plugins/mercurial/mercurialcontrol.cpp @@ -65,6 +65,8 @@ bool MercurialControl::supportsOperation(Operation operation) const case Core::IVersionControl::MoveOperation: case Core::IVersionControl::CreateRepositoryOperation: case Core::IVersionControl::AnnotateOperation: + case Core::IVersionControl::CheckoutOperation: + case Core::IVersionControl::GetRepositoryRootOperation: break; case Core::IVersionControl::OpenOperation: case Core::IVersionControl::SnapshotOperations: @@ -142,6 +144,16 @@ bool MercurialControl::sccManaged(const QString &filename) return mercurialClient->manifestSync(topLevel, topLevelDir.relativeFilePath(filename)); } +bool MercurialControl::vcsCheckout(const QString &directory, const QByteArray &url) +{ + return mercurialClient->clone(directory,url); +} + +QString MercurialControl::vcsGetRepositoryURL(const QString &directory) +{ + return mercurialClient->vcsGetRepositoryURL(directory); +} + void MercurialControl::changed(const QVariant &v) { switch (v.type()) { diff --git a/src/plugins/mercurial/mercurialcontrol.h b/src/plugins/mercurial/mercurialcontrol.h index b74fce99ff8fa4a1e53a7c74d0178d8dd5dacfa9..3f0465d380cb7ff8d4d5498f7dcd40efba7043ea 100644 --- a/src/plugins/mercurial/mercurialcontrol.h +++ b/src/plugins/mercurial/mercurialcontrol.h @@ -57,6 +57,8 @@ public: bool vcsDelete(const QString &filename); bool vcsMove(const QString &from, const QString &to); bool vcsCreateRepository(const QString &directory); + bool vcsCheckout(const QString &directory, const QByteArray &url); + QString vcsGetRepositoryURL(const QString &directory); QString vcsCreateSnapshot(const QString &topLevel); QStringList vcsSnapshots(const QString &topLevel); bool vcsRestoreSnapshot(const QString &topLevel, const QString &name); diff --git a/src/plugins/perforce/perforceversioncontrol.cpp b/src/plugins/perforce/perforceversioncontrol.cpp index 0f0a5e81905b24bd18b217dd8658a239840dbe0f..6ea6fb63466a7681146661c106097ac8b42b8356 100644 --- a/src/plugins/perforce/perforceversioncontrol.cpp +++ b/src/plugins/perforce/perforceversioncontrol.cpp @@ -59,6 +59,8 @@ bool PerforceVersionControl::supportsOperation(Operation operation) const return true; case CreateRepositoryOperation: case SnapshotOperations: + case CheckoutOperation: + case GetRepositoryRootOperation: break; } return false; @@ -128,6 +130,16 @@ bool PerforceVersionControl::vcsAnnotate(const QString &file, int line) return true; } +bool PerforceVersionControl::vcsCheckout(const QString &/*directory*/,const QByteArray&/*url*/) +{ + return false; +} + +QString PerforceVersionControl::vcsGetRepositoryURL(const QString &/*directory*/) +{ + return QString(); +} + bool PerforceVersionControl::managesDirectory(const QString &directory, QString *topLevel) const { const bool rc = m_plugin->managesDirectory(directory, topLevel); diff --git a/src/plugins/perforce/perforceversioncontrol.h b/src/plugins/perforce/perforceversioncontrol.h index b3a01f7a6c0fbcffa4065c2ebacbb35e2610566c..ed688d68503ce34cb799986d6e3afe6a01904966 100644 --- a/src/plugins/perforce/perforceversioncontrol.h +++ b/src/plugins/perforce/perforceversioncontrol.h @@ -55,6 +55,8 @@ public: virtual bool vcsDelete(const QString &filename); virtual bool vcsMove(const QString &from, const QString &to); virtual bool vcsCreateRepository(const QString &directory); + virtual bool vcsCheckout(const QString &directory, const QByteArray &url); + virtual QString vcsGetRepositoryURL(const QString &directory); virtual QString vcsCreateSnapshot(const QString &topLevel); virtual QStringList vcsSnapshots(const QString &topLevel); virtual bool vcsRestoreSnapshot(const QString &topLevel, const QString &name); diff --git a/src/plugins/subversion/subversioncontrol.cpp b/src/plugins/subversion/subversioncontrol.cpp index f25fc3ab6a2b70ab19357c812024ea7d006523c4..e4e1256f9ebbe4989d72f6a1779afcf844403bd7 100644 --- a/src/plugins/subversion/subversioncontrol.cpp +++ b/src/plugins/subversion/subversioncontrol.cpp @@ -54,6 +54,8 @@ bool SubversionControl::supportsOperation(Operation operation) const case DeleteOperation: case MoveOperation: case AnnotateOperation: + case CheckoutOperation: + case GetRepositoryRootOperation: break; case OpenOperation: case CreateRepositoryOperation: @@ -89,6 +91,16 @@ bool SubversionControl::vcsMove(const QString &from, const QString &to) return m_plugin->vcsMove(fromInfo.absolutePath(), fromInfo.absoluteFilePath(), toInfo.absoluteFilePath()); } +bool SubversionControl::vcsCheckout(const QString &directory,const QByteArray &url) +{ + return m_plugin->vcsCheckout(directory,url); +} + +QString SubversionControl::vcsGetRepositoryURL(const QString &directory) +{ + return m_plugin->vcsGetRepositoryURL(directory); +} + bool SubversionControl::vcsCreateRepository(const QString &) { return false; diff --git a/src/plugins/subversion/subversioncontrol.h b/src/plugins/subversion/subversioncontrol.h index 5610059d66168f974686d10817e0a18b8cab03c1..071773b8600ba521564973d616fb2f37b9ce3f83 100644 --- a/src/plugins/subversion/subversioncontrol.h +++ b/src/plugins/subversion/subversioncontrol.h @@ -53,6 +53,8 @@ public: virtual bool vcsDelete(const QString &filename); virtual bool vcsMove(const QString &from, const QString &to); virtual bool vcsCreateRepository(const QString &directory); + virtual bool vcsCheckout(const QString &directory, const QByteArray &url); + virtual QString vcsGetRepositoryURL(const QString &directory); virtual QString vcsCreateSnapshot(const QString &topLevel); virtual QStringList vcsSnapshots(const QString &topLevel); diff --git a/src/plugins/subversion/subversionplugin.cpp b/src/plugins/subversion/subversionplugin.cpp index 332ca5f372433a28fc9abd7419289ae9600195eb..e22933b25eb1449dbd751d64de1ad7aae913b028 100644 --- a/src/plugins/subversion/subversionplugin.cpp +++ b/src/plugins/subversion/subversionplugin.cpp @@ -65,13 +65,14 @@ #include <QtCore/QTextCodec> #include <QtCore/QtPlugin> #include <QtCore/QProcessEnvironment> +#include <QtCore/QUrl> #include <QtGui/QAction> #include <QtGui/QFileDialog> #include <QtGui/QMainWindow> #include <QtGui/QMenu> #include <QtGui/QMessageBox> #include <QtGui/QInputDialog> - +#include <QtXml/QXmlStreamReader> #include <limits.h> using namespace Subversion::Internal; @@ -1224,6 +1225,74 @@ bool SubversionPlugin::vcsMove(const QString &workingDir, const QString &from, c return !response.error; } +bool SubversionPlugin::vcsCheckout(const QString &directory, const QByteArray &url) +{ + QUrl tempUrl; + tempUrl.setEncodedUrl(url); + QString username = tempUrl.userName(); + QString password = tempUrl.password(); + QStringList args = QStringList(QLatin1String("checkout")); + args << QLatin1String(nonInteractiveOptionC) ; + + if(!username.isEmpty() && !password.isEmpty()) + { + // If url contains username and password we have to use separate username and password + // arguments instead of passing those in the url. Otherwise the subversion 'non-interactive' + // authentication will always fail (if the username and password data are not stored locally), + // if for example we are logging into a new host for the first time using svn. There seems to + // be a bug in subversion, so this might get fixed in the future. + tempUrl.setUserInfo(""); + args << tempUrl.toEncoded() << directory; + const SubversionResponse response = runSvn(directory, username, password, args, m_settings.longTimeOutMS(), + VCSBase::VCSBasePlugin::SshPasswordPrompt); + return !response.error; + } else { + args << url << directory; + const SubversionResponse response = runSvn(directory, args, m_settings.longTimeOutMS(), + VCSBase::VCSBasePlugin::SshPasswordPrompt); + return !response.error; + } +} + +QString SubversionPlugin::vcsGetRepositoryURL(const QString &directory) +{ + QXmlStreamReader xml; + QStringList args = QStringList(QLatin1String("info")); + args << QLatin1String("--xml"); + + const SubversionResponse response = runSvn(directory, args, m_settings.longTimeOutMS(), SuppressCommandLogging); + xml.addData(response.stdOut); + + bool repo = false; + bool root = false; + + while(!xml.atEnd() && !xml.hasError()) { + switch(xml.readNext()) { + case QXmlStreamReader::StartDocument: + break; + case QXmlStreamReader::StartElement: + if(xml.name() == QLatin1String("repository")) + repo = true; + else if(repo && xml.name() == QLatin1String("root")) + root = true; + break; + case QXmlStreamReader::EndElement: + if(xml.name() == QLatin1String("repository")) + repo = false; + else if(repo && xml.name() == QLatin1String("root")) + root = false; + break; + case QXmlStreamReader::Characters: + if (repo && root) + return xml.text().toString(); + break; + default: + break; + } + } + return QString(); +} + /* 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". */ diff --git a/src/plugins/subversion/subversionplugin.h b/src/plugins/subversion/subversionplugin.h index 584a196671cec85c349928a703841529156cce11..d79ae144e1087ad4270cb6e2e0e42c7e24294742 100644 --- a/src/plugins/subversion/subversionplugin.h +++ b/src/plugins/subversion/subversionplugin.h @@ -96,6 +96,8 @@ public: bool vcsDelete(const QString &workingDir, const QString &fileName); bool vcsMove(const QString &workingDir, const QString &from, const QString &to); bool managesDirectory(const QString &directory, QString *topLevel = 0) const; + virtual bool vcsCheckout(const QString &directory, const QByteArray &url); + virtual QString vcsGetRepositoryURL(const QString &directory); static SubversionPlugin *subversionPluginInstance();