diff --git a/src/plugins/cvs/checkoutwizard.cpp b/src/plugins/cvs/checkoutwizard.cpp index 2b1f213d83d9b8a5fea1088e82bc8071a3873e5f..3fc6c0155b624d39a5fc8a6c5f81547a37d5bdd6 100644 --- a/src/plugins/cvs/checkoutwizard.cpp +++ b/src/plugins/cvs/checkoutwizard.cpp @@ -84,8 +84,9 @@ QSharedPointer<VCSBase::AbstractCheckoutJob> CheckoutWizard::createJob(const QLi args << QLatin1String("checkout") << repository; const QString workingDirectory = cwp->path(); *checkoutPath = workingDirectory + QLatin1Char('/') + repository; - VCSBase::AbstractCheckoutJob *job = new VCSBase::ProcessCheckoutJob(binary, settings.addOptions(args), - workingDirectory); + + VCSBase::ProcessCheckoutJob *job = new VCSBase::ProcessCheckoutJob; + job->addStep(binary, settings.addOptions(args), workingDirectory); return QSharedPointer<VCSBase::AbstractCheckoutJob>(job); } diff --git a/src/plugins/cvs/checkoutwizardpage.cpp b/src/plugins/cvs/checkoutwizardpage.cpp index 12fe66d00215ac0c3b140300d925405fafb56ddc..1a7261b2dd7b98c01501395d7f93ac920855d6ca 100644 --- a/src/plugins/cvs/checkoutwizardpage.cpp +++ b/src/plugins/cvs/checkoutwizardpage.cpp @@ -39,6 +39,7 @@ CheckoutWizardPage::CheckoutWizardPage(QWidget *parent) : setSubTitle(tr("Specify repository and path.")); setRepositoryLabel(tr("Repository:")); setDirectoryVisible(false); + setBranchSelectorVisible(false); } } // namespace Internal diff --git a/src/plugins/git/clonewizardpage.cpp b/src/plugins/git/clonewizardpage.cpp index 8c712d14f328bfd17073a32c37ab79d70b1561aa..3c4e8b72cafc1cb7938cc0d0317ae89b96bc5b9b 100644 --- a/src/plugins/git/clonewizardpage.cpp +++ b/src/plugins/git/clonewizardpage.cpp @@ -34,6 +34,8 @@ #include <vcsbase/checkoutjobs.h> #include <utils/qtcassert.h> +#include <QtGui/QCheckBox> + namespace Git { struct CloneWizardPagePrivate { @@ -42,12 +44,14 @@ struct CloneWizardPagePrivate { const QString mainLinePostfix; const QString gitPostFix; const QString protocolDelimiter; + QCheckBox *deleteMasterCheckBox; }; CloneWizardPagePrivate::CloneWizardPagePrivate() : mainLinePostfix(QLatin1String("/mainline.git")), gitPostFix(QLatin1String(".git")), - protocolDelimiter(QLatin1String("://")) + protocolDelimiter(QLatin1String("://")), + deleteMasterCheckBox(0) { } @@ -58,6 +62,9 @@ CloneWizardPage::CloneWizardPage(QWidget *parent) : setTitle(tr("Location")); setSubTitle(tr("Specify repository URL, checkout directory and path.")); setRepositoryLabel(tr("Clone URL:")); + d->deleteMasterCheckBox = new QCheckBox(tr("Delete master branch")); + addControl(d->deleteMasterCheckBox); + setDeleteMasterBranch(true); } CloneWizardPage::~CloneWizardPage() @@ -65,6 +72,16 @@ CloneWizardPage::~CloneWizardPage() delete d; } +bool CloneWizardPage::deleteMasterBranch() const +{ + return d->deleteMasterCheckBox->isChecked(); +} + +void CloneWizardPage::setDeleteMasterBranch(bool v) +{ + d->deleteMasterCheckBox->setChecked(v); +} + QString CloneWizardPage::directoryFromRepository(const QString &urlIn) const { /* Try to figure out a good directory name from something like: @@ -105,17 +122,55 @@ QString CloneWizardPage::directoryFromRepository(const QString &urlIn) const QSharedPointer<VCSBase::AbstractCheckoutJob> CloneWizardPage::createCheckoutJob(QString *checkoutPath) const { const Internal::GitClient *client = Internal::GitPlugin::instance()->gitClient(); - QStringList args = client->binary(); const QString workingDirectory = path(); const QString checkoutDir = directory(); *checkoutPath = workingDirectory + QLatin1Char('/') + checkoutDir; + + QStringList baseArgs = client->binary(); + const QString binary = baseArgs.front(); + baseArgs.pop_front(); + + QStringList args; args << QLatin1String("clone") << repository() << checkoutDir; - const QString binary = args.front(); - args.pop_front(); - VCSBase::AbstractCheckoutJob *job = - new VCSBase::ProcessCheckoutJob(binary, args, workingDirectory, - client->processEnvironment()); + + VCSBase::ProcessCheckoutJob *job = new VCSBase::ProcessCheckoutJob; + const QProcessEnvironment env = client->processEnvironment(); + // 1) Basic checkout step + job->addStep(binary, baseArgs + args, workingDirectory, env); + const QString checkoutBranch = branch(); + + // 2) Checkout branch, change to checkoutDir + const QString masterBranch = QLatin1String("master"); + if (!checkoutBranch.isEmpty() && checkoutBranch != masterBranch) { + // Create branch + args.clear(); + args << QLatin1String("branch") << QLatin1String("--track") + << checkoutBranch << (QLatin1String("origin/") + checkoutBranch); + job->addStep(binary, baseArgs + args, checkoutDir, env); + // Checkout branch + args.clear(); + args << QLatin1String("checkout") << checkoutBranch; + job->addStep(binary, baseArgs + args, checkoutDir, env); + // Delete master if desired + if (deleteMasterBranch()) { + args.clear(); + args << QLatin1String("branch") << QLatin1String("-D") << masterBranch; + job->addStep(binary, baseArgs + args, checkoutDir, env); + } + } + return QSharedPointer<VCSBase::AbstractCheckoutJob>(job); } +QStringList CloneWizardPage::branches(const QString &repository, int *current) +{ + // Run git on remote repository if URL is complete + *current = 0; + if (!repository.endsWith(d->gitPostFix)) + return QStringList(); + const QStringList branches = Internal::GitPlugin::instance()->gitClient()->synchronousRepositoryBranches(repository); + *current = branches.indexOf(QLatin1String("master")); + return branches; +} + } // namespace Git diff --git a/src/plugins/git/clonewizardpage.h b/src/plugins/git/clonewizardpage.h index 1c4e9848b8215662b3f3478a706893b8582b96e5..b7fae35c356acde41e1141bdb0f6b3f31f5c038e 100644 --- a/src/plugins/git/clonewizardpage.h +++ b/src/plugins/git/clonewizardpage.h @@ -46,6 +46,7 @@ struct CloneWizardPagePrivate; class CloneWizardPage : public VCSBase::BaseCheckoutWizardPage { Q_OBJECT + Q_PROPERTY(bool deleteMasterBranch READ deleteMasterBranch WRITE setDeleteMasterBranch) public: explicit CloneWizardPage(QWidget *parent = 0); virtual ~CloneWizardPage(); @@ -54,6 +55,10 @@ public: protected: virtual QString directoryFromRepository(const QString &r) const; + virtual QStringList branches(const QString &repository, int *current); + + bool deleteMasterBranch() const; + void setDeleteMasterBranch(bool v); private: CloneWizardPagePrivate *d; diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index fb8393b5dd6b8f93924159765f3c543b30d081fc..d2293d556685f72068e5ddb90f9877b2bb31bd9e 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -1265,6 +1265,28 @@ GitClient::StatusResult GitClient::gitStatus(const QString &workingDirectory, return StatusChanged; } +// Quietly retrieve branch list of remote repository URL +QStringList GitClient::synchronousRepositoryBranches(const QString &repositoryURL) +{ + QStringList arguments(QLatin1String("ls-remote")); + arguments << QLatin1String("--heads") << repositoryURL; + const unsigned flags = + VCSBase::VCSBasePlugin::SshPasswordPrompt| + VCSBase::VCSBasePlugin::SuppressStdErrInLogWindow| + VCSBase::VCSBasePlugin::SuppressFailMessageInLogWindow; + const Utils::SynchronousProcessResponse resp = synchronousGit(QString(), arguments, flags); + QStringList branches; + if (resp.result == Utils::SynchronousProcessResponse::Finished) { + // split "82bfad2f51d34e98b18982211c82220b8db049b<tab>refs/heads/master" + foreach(const QString &line, resp.stdOut.split(QLatin1Char('\n'))) { + const int slashPos = line.lastIndexOf(QLatin1Char('/')); + if (slashPos != -1) + branches.push_back(line.mid(slashPos + 1)); + } + } + return branches; +} + void GitClient::launchGitK(const QString &workingDirectory) { VCSBase::VCSBaseOutputWindow *outwin = VCSBase::VCSBaseOutputWindow::instance(); diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index db268813ad07d6cb76377de1fd2325da01e2ee6a..ef0ca8dac854e51a8e3a90393c4b4476e7583a97 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -205,6 +205,7 @@ public: bool *onBranch = 0); void launchGitK(const QString &workingDirectory); + QStringList synchronousRepositoryBranches(const QString &repositoryURL); GitSettings settings() const; void setSettings(const GitSettings &s); diff --git a/src/plugins/mercurial/clonewizard.cpp b/src/plugins/mercurial/clonewizard.cpp index 2013d72d34ae580500ea64208cd3afe8e2fcc11b..efadd115d2a62de07448404f72bb0f746f8b02a9 100644 --- a/src/plugins/mercurial/clonewizard.cpp +++ b/src/plugins/mercurial/clonewizard.cpp @@ -86,7 +86,7 @@ QSharedPointer<VCSBase::AbstractCheckoutJob> CloneWizard::createJob(const QList< args << QLatin1String("clone") << page->repository() << directory; *checkoutPath = path + QLatin1Char('/') + directory; - - return QSharedPointer<VCSBase::AbstractCheckoutJob>(new VCSBase::ProcessCheckoutJob(settings.binary(), - args, path)); + VCSBase::ProcessCheckoutJob *job = new VCSBase::ProcessCheckoutJob; + job->addStep(settings.binary(), args, path); + return QSharedPointer<VCSBase::AbstractCheckoutJob>(job); } diff --git a/src/plugins/mercurial/clonewizardpage.cpp b/src/plugins/mercurial/clonewizardpage.cpp index ed8f668736da8535a4a3ea64229d68fbf5b9c072..dc7d2b2a65cc21fd2a5052a325290e6829ed8c1b 100644 --- a/src/plugins/mercurial/clonewizardpage.cpp +++ b/src/plugins/mercurial/clonewizardpage.cpp @@ -37,6 +37,7 @@ CloneWizardPage::CloneWizardPage(QWidget *parent) setTitle(tr("Location")); setSubTitle(tr("Specify repository URL, checkout directory and path.")); setRepositoryLabel(tr("Clone URL:")); + setBranchSelectorVisible(false); } QString CloneWizardPage::directoryFromRepository(const QString &repository) const diff --git a/src/plugins/subversion/checkoutwizard.cpp b/src/plugins/subversion/checkoutwizard.cpp index 89d0f5c3f0a58ba25dab5cb669be99895b76cc34..c72573ecba556df2e71bd6c4921df5a42e3d02f8 100644 --- a/src/plugins/subversion/checkoutwizard.cpp +++ b/src/plugins/subversion/checkoutwizard.cpp @@ -86,8 +86,8 @@ QSharedPointer<VCSBase::AbstractCheckoutJob> CheckoutWizard::createJob(const QLi const QStringList completeArgs = settings.hasAuthentication() ? SubversionPlugin::addAuthenticationOptions(args, settings.user, settings.password) : args; - VCSBase::AbstractCheckoutJob *job = new VCSBase::ProcessCheckoutJob(binary, completeArgs, - workingDirectory); + VCSBase::ProcessCheckoutJob *job = new VCSBase::ProcessCheckoutJob; + job->addStep(binary, completeArgs, workingDirectory); return QSharedPointer<VCSBase::AbstractCheckoutJob>(job); } diff --git a/src/plugins/subversion/checkoutwizardpage.cpp b/src/plugins/subversion/checkoutwizardpage.cpp index a97f826d246e685a3c28f9f42171a60cde221fe9..adc7b21597a48cc0397d29635d09a03b989db307 100644 --- a/src/plugins/subversion/checkoutwizardpage.cpp +++ b/src/plugins/subversion/checkoutwizardpage.cpp @@ -38,6 +38,7 @@ CheckoutWizardPage::CheckoutWizardPage(QWidget *parent) : setTitle(tr("Location")); setSubTitle(tr("Specify repository URL, checkout directory and path.")); setRepositoryLabel(tr("Repository:")); + setBranchSelectorVisible(false); } QString CheckoutWizardPage::directoryFromRepository(const QString &repoIn) const diff --git a/src/plugins/vcsbase/basecheckoutwizardpage.cpp b/src/plugins/vcsbase/basecheckoutwizardpage.cpp index d2488c814c6d1783fa1c25a19a73a6ab409b75c1..111d069fb5c58632527b2ba10016ec1c64c89483 100644 --- a/src/plugins/vcsbase/basecheckoutwizardpage.cpp +++ b/src/plugins/vcsbase/basecheckoutwizardpage.cpp @@ -30,6 +30,8 @@ #include "basecheckoutwizardpage.h" #include "ui_basecheckoutwizardpage.h" +#include <QtGui/QIcon> + namespace VCSBase { struct BaseCheckoutWizardPagePrivate { @@ -54,6 +56,10 @@ BaseCheckoutWizardPage::BaseCheckoutWizardPage(QWidget *parent) : d->ui.pathChooser->setExpectedKind(Utils::PathChooser::Directory); connect(d->ui.pathChooser, SIGNAL(validChanged()), this, SLOT(slotChanged())); + + d->ui.branchComboBox->setEnabled(false); + d->ui.branchRefreshToolButton->setIcon(QIcon(QLatin1String(":/locator/images/reload.png"))); + connect(d->ui.branchRefreshToolButton, SIGNAL(clicked()), this, SLOT(slotRefreshBranches())); } BaseCheckoutWizardPage::~BaseCheckoutWizardPage() @@ -61,6 +67,28 @@ BaseCheckoutWizardPage::~BaseCheckoutWizardPage() delete d; } +void BaseCheckoutWizardPage::addControl(QWidget *w) +{ + d->ui.formLayout->addRow(w); +} + +void BaseCheckoutWizardPage::addControl(QString &description, QWidget *w) +{ + d->ui.formLayout->addRow(description, w); +} + +bool BaseCheckoutWizardPage::isBranchSelectorVisible() const +{ + return d->ui.branchComboBox->isVisible(); +} + +void BaseCheckoutWizardPage::setBranchSelectorVisible(bool v) +{ + d->ui.branchComboBox->setVisible(v); + d->ui.branchRefreshToolButton->setVisible(v); + d->ui.branchLabel->setVisible(v); +} + void BaseCheckoutWizardPage::setRepositoryLabel(const QString &l) { d->ui.repositoryLabel->setText(l); @@ -112,6 +140,35 @@ void BaseCheckoutWizardPage::setRepository(const QString &r) d->ui.repositoryLineEdit->setText(r); } +QString BaseCheckoutWizardPage::branch() const +{ + return d->ui.branchComboBox->currentText(); +} + +void BaseCheckoutWizardPage::setBranch(const QString &b) +{ + const int index = d->ui.branchComboBox->findText(b); + if (index != -1) + d->ui.branchComboBox->setCurrentIndex(index); +} + +void BaseCheckoutWizardPage::slotRefreshBranches() +{ + if (!isBranchSelectorVisible()) + return; + // Refresh branch list on demand. This is hard to make + // automagically since there can be network slowness/timeouts, etc. + int current; + const QStringList branchList = branches(repository(), ¤t); + d->ui.branchComboBox->clear(); + d->ui.branchComboBox->setEnabled(branchList.size() > 1); + if (!branchList.isEmpty()) { + d->ui.branchComboBox->addItems(branchList); + if (current >= 0 && current < branchList.size()) + d->ui.branchComboBox->setCurrentIndex(current); + } +} + void BaseCheckoutWizardPage::slotRepositoryChanged(const QString &repo) { // Derive directory name from repository unless user manually edited it. @@ -125,6 +182,11 @@ QString BaseCheckoutWizardPage::directoryFromRepository(const QString &r) const return r; } +QStringList BaseCheckoutWizardPage::branches(const QString &, int *) +{ + return QStringList(); +} + void BaseCheckoutWizardPage::slotDirectoryEdited() { d->m_directoryEdited = true; diff --git a/src/plugins/vcsbase/basecheckoutwizardpage.h b/src/plugins/vcsbase/basecheckoutwizardpage.h index 7b671325f48933425e72ff08eef3cf1d652ffb46..f4471298a77a746c107ca52bfc6cf785fe933866 100644 --- a/src/plugins/vcsbase/basecheckoutwizardpage.h +++ b/src/plugins/vcsbase/basecheckoutwizardpage.h @@ -49,6 +49,7 @@ struct BaseCheckoutWizardPagePrivate; class VCSBASE_EXPORT BaseCheckoutWizardPage : public QWizardPage { Q_OBJECT + Q_PROPERTY(bool isBranchSelectorVisible READ isBranchSelectorVisible WRITE setBranchSelectorVisible) public: BaseCheckoutWizardPage(QWidget *parent = 0); ~BaseCheckoutWizardPage(); @@ -65,22 +66,36 @@ public: bool isRepositoryReadOnly() const; void setRepositoryReadOnly(bool v); + QString branch() const; + void setBranch(const QString &); + virtual bool isComplete() const; + bool isBranchSelectorVisible() const ; + protected: void changeEvent(QEvent *e); void setRepositoryLabel(const QString &l); void setDirectoryVisible(bool v); + void setBranchSelectorVisible(bool v); /* Determine a checkout directory name from * repository URL, that is, "protocol:/project" -> "project". */ virtual QString directoryFromRepository(const QString &r) const; + /* Return list of branches of that repository, defaults to empty. */ + virtual QStringList branches(const QString &repository, int *current); + + /* Add additional controls */ + void addControl(QWidget *w); + void addControl(QString &description, QWidget *w); + private slots: void slotRepositoryChanged(const QString &url); void slotDirectoryEdited(); void slotChanged(); + void slotRefreshBranches(); private: BaseCheckoutWizardPagePrivate *d; diff --git a/src/plugins/vcsbase/basecheckoutwizardpage.ui b/src/plugins/vcsbase/basecheckoutwizardpage.ui index 6dc045d4985e3a0d73d99f8d02cea1641fa93543..81011403b15d8703bde381197793dfbf143ea20f 100644 --- a/src/plugins/vcsbase/basecheckoutwizardpage.ui +++ b/src/plugins/vcsbase/basecheckoutwizardpage.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>464</width> - <height>302</height> + <width>483</width> + <height>237</height> </rect> </property> <property name="windowTitle"> @@ -40,7 +40,35 @@ </widget> </item> <item row="2" column="1"> - <widget class="Utils::PathChooser" name="pathChooser"/> + <widget class="Utils::PathChooser" name="pathChooser" native="true"/> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="branchLabel"> + <property name="text"> + <string>Branches:</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <layout class="QHBoxLayout" name="branchHorizontalLayout"> + <item> + <widget class="QComboBox" name="branchComboBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item> + <widget class="QToolButton" name="branchRefreshToolButton"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + </layout> </item> </layout> </item> diff --git a/src/plugins/vcsbase/checkoutjobs.cpp b/src/plugins/vcsbase/checkoutjobs.cpp index 293f519be58f6876684384f07627a014a389f14b..20fc58eb98f7742921a97ffacc163681658529ac 100644 --- a/src/plugins/vcsbase/checkoutjobs.cpp +++ b/src/plugins/vcsbase/checkoutjobs.cpp @@ -30,10 +30,13 @@ #include "checkoutjobs.h" #include <vcsbaseplugin.h> +#include <vcsbaseoutputwindow.h> #include <QtCore/QDebug> +#include <QtCore/QQueue> #include <QtCore/QDir> #include <utils/synchronousprocess.h> +#include <utils/qtcassert.h> enum { debug = 0 }; namespace VCSBase { @@ -43,15 +46,27 @@ AbstractCheckoutJob::AbstractCheckoutJob(QObject *parent) : { } +struct ProcessCheckoutJobStep +{ + ProcessCheckoutJobStep() {} + explicit ProcessCheckoutJobStep(const QString &bin, + const QStringList &args, + const QString &workingDir, + QProcessEnvironment env) : + binary(bin), arguments(args), workingDirectory(workingDir), environment(env) {} + + QString binary; + QStringList arguments; + QString workingDirectory; + QProcessEnvironment environment; +}; + struct ProcessCheckoutJobPrivate { - ProcessCheckoutJobPrivate(const QString &binary, - const QStringList &args, - const QString &workingDirectory, - QProcessEnvironment env); + ProcessCheckoutJobPrivate(); QSharedPointer<QProcess> process; - const QString binary; - const QStringList args; + QQueue<ProcessCheckoutJobStep> stepQueue; + QString binary; }; // Use a terminal-less process to suppress SSH prompts. @@ -63,30 +78,15 @@ static inline QSharedPointer<QProcess> createProcess() return Utils::SynchronousProcess::createProcess(flags); } -ProcessCheckoutJobPrivate::ProcessCheckoutJobPrivate(const QString &b, - const QStringList &a, - const QString &workingDirectory, - QProcessEnvironment processEnv) : - process(createProcess()), - binary(b), - args(a) +ProcessCheckoutJobPrivate::ProcessCheckoutJobPrivate() : + process(createProcess()) { - if (!workingDirectory.isEmpty()) - process->setWorkingDirectory(workingDirectory); - VCSBasePlugin::setProcessEnvironment(&processEnv, false); - process->setProcessEnvironment(processEnv); } -ProcessCheckoutJob::ProcessCheckoutJob(const QString &binary, - const QStringList &args, - const QString &workingDirectory, - const QProcessEnvironment &env, - QObject *parent) : +ProcessCheckoutJob::ProcessCheckoutJob(QObject *parent) : AbstractCheckoutJob(parent), - d(new ProcessCheckoutJobPrivate(binary, args, workingDirectory, env)) + d(new ProcessCheckoutJobPrivate) { - if (debug) - qDebug() << "ProcessCheckoutJob" << binary << args << workingDirectory; connect(d->process.data(), SIGNAL(error(QProcess::ProcessError)), this, SLOT(slotError(QProcess::ProcessError))); connect(d->process.data(), SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(slotFinished(int,QProcess::ExitStatus))); connect(d->process.data(), SIGNAL(readyReadStandardOutput()), this, SLOT(slotOutput())); @@ -99,6 +99,16 @@ ProcessCheckoutJob::~ProcessCheckoutJob() delete d; } +void ProcessCheckoutJob::addStep(const QString &binary, + const QStringList &args, + const QString &workingDirectory, + const QProcessEnvironment &env) +{ + if (debug) + qDebug() << "ProcessCheckoutJob::addStep" << binary << args << workingDirectory; + d->stepQueue.enqueue(ProcessCheckoutJobStep(binary, args, workingDirectory, env)); +} + void ProcessCheckoutJob::slotOutput() { const QByteArray data = d->process->readAllStandardOutput(); @@ -130,7 +140,7 @@ void ProcessCheckoutJob::slotFinished (int exitCode, QProcess::ExitStatus exitSt case QProcess::NormalExit: emit output(tr("The process terminated with exit code %1.").arg(exitCode)); if (exitCode == 0) { - emit succeeded(); + slotNext(); } else { emit failed(tr("The process returned exit code %1.").arg(exitCode)); } @@ -143,7 +153,28 @@ void ProcessCheckoutJob::slotFinished (int exitCode, QProcess::ExitStatus exitSt void ProcessCheckoutJob::start() { - d->process->start(d->binary, d->args); + QTC_ASSERT(!d->stepQueue.empty(), return) + slotNext(); +} + +void ProcessCheckoutJob::slotNext() +{ + if (d->stepQueue.isEmpty()) { + emit succeeded(); + return; + } + // Launch next + const ProcessCheckoutJobStep step = d->stepQueue.dequeue(); + d->process->setWorkingDirectory(step.workingDirectory); + + // Set up SSH correctly. + QProcessEnvironment processEnv = step.environment; + VCSBasePlugin::setProcessEnvironment(&processEnv, false); + d->process->setProcessEnvironment(processEnv); + + d->binary = step.binary; + emit output(VCSBaseOutputWindow::msgExecutionLogEntry(step.workingDirectory, d->binary, step.arguments)); + d->process->start(d->binary, step.arguments); } void ProcessCheckoutJob::cancel() diff --git a/src/plugins/vcsbase/checkoutjobs.h b/src/plugins/vcsbase/checkoutjobs.h index 9c467ff4f3f2af05b6c53defb9cb6e88c8be17ab..da9da558d0924c3ce0d0503f3a8722f912bf6cf2 100644 --- a/src/plugins/vcsbase/checkoutjobs.h +++ b/src/plugins/vcsbase/checkoutjobs.h @@ -72,13 +72,14 @@ class VCSBASE_EXPORT ProcessCheckoutJob : public AbstractCheckoutJob { Q_OBJECT public: - explicit ProcessCheckoutJob(const QString &binary, - const QStringList &args, - const QString &workingDirectory = QString(), - const QProcessEnvironment &env = QProcessEnvironment::systemEnvironment(), - QObject *parent = 0); + explicit ProcessCheckoutJob(QObject *parent = 0); virtual ~ProcessCheckoutJob(); + void addStep(const QString &binary, + const QStringList &args, + const QString &workingDirectory = QString(), + const QProcessEnvironment &env = QProcessEnvironment::systemEnvironment()); + virtual void start(); virtual void cancel(); @@ -86,6 +87,7 @@ private slots: void slotError(QProcess::ProcessError error); void slotFinished (int exitCode, QProcess::ExitStatus exitStatus); void slotOutput(); + void slotNext(); private: ProcessCheckoutJobPrivate *d;