VCS[git]: Add branch combo to the checkout wizard.

Provide UI with manual refresh button in BaseCheckoutWizardPage.
Change ProcessCheckoutJob to be able to execute several steps.
Implement in git.
This commit is contained in:
Friedemann Kleint
2010-08-12 14:44:57 +02:00
parent 1ae9940b32
commit cb33332311
15 changed files with 274 additions and 49 deletions

View File

@@ -84,8 +84,9 @@ QSharedPointer<VCSBase::AbstractCheckoutJob> CheckoutWizard::createJob(const QLi
args << QLatin1String("checkout") << repository; args << QLatin1String("checkout") << repository;
const QString workingDirectory = cwp->path(); const QString workingDirectory = cwp->path();
*checkoutPath = workingDirectory + QLatin1Char('/') + repository; *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); return QSharedPointer<VCSBase::AbstractCheckoutJob>(job);
} }

View File

@@ -39,6 +39,7 @@ CheckoutWizardPage::CheckoutWizardPage(QWidget *parent) :
setSubTitle(tr("Specify repository and path.")); setSubTitle(tr("Specify repository and path."));
setRepositoryLabel(tr("Repository:")); setRepositoryLabel(tr("Repository:"));
setDirectoryVisible(false); setDirectoryVisible(false);
setBranchSelectorVisible(false);
} }
} // namespace Internal } // namespace Internal

View File

@@ -34,6 +34,8 @@
#include <vcsbase/checkoutjobs.h> #include <vcsbase/checkoutjobs.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <QtGui/QCheckBox>
namespace Git { namespace Git {
struct CloneWizardPagePrivate { struct CloneWizardPagePrivate {
@@ -42,12 +44,14 @@ struct CloneWizardPagePrivate {
const QString mainLinePostfix; const QString mainLinePostfix;
const QString gitPostFix; const QString gitPostFix;
const QString protocolDelimiter; const QString protocolDelimiter;
QCheckBox *deleteMasterCheckBox;
}; };
CloneWizardPagePrivate::CloneWizardPagePrivate() : CloneWizardPagePrivate::CloneWizardPagePrivate() :
mainLinePostfix(QLatin1String("/mainline.git")), mainLinePostfix(QLatin1String("/mainline.git")),
gitPostFix(QLatin1String(".git")), gitPostFix(QLatin1String(".git")),
protocolDelimiter(QLatin1String("://")) protocolDelimiter(QLatin1String("://")),
deleteMasterCheckBox(0)
{ {
} }
@@ -58,6 +62,9 @@ CloneWizardPage::CloneWizardPage(QWidget *parent) :
setTitle(tr("Location")); setTitle(tr("Location"));
setSubTitle(tr("Specify repository URL, checkout directory and path.")); setSubTitle(tr("Specify repository URL, checkout directory and path."));
setRepositoryLabel(tr("Clone URL:")); setRepositoryLabel(tr("Clone URL:"));
d->deleteMasterCheckBox = new QCheckBox(tr("Delete master branch"));
addControl(d->deleteMasterCheckBox);
setDeleteMasterBranch(true);
} }
CloneWizardPage::~CloneWizardPage() CloneWizardPage::~CloneWizardPage()
@@ -65,6 +72,16 @@ CloneWizardPage::~CloneWizardPage()
delete d; 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 QString CloneWizardPage::directoryFromRepository(const QString &urlIn) const
{ {
/* Try to figure out a good directory name from something like: /* 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 QSharedPointer<VCSBase::AbstractCheckoutJob> CloneWizardPage::createCheckoutJob(QString *checkoutPath) const
{ {
const Internal::GitClient *client = Internal::GitPlugin::instance()->gitClient(); const Internal::GitClient *client = Internal::GitPlugin::instance()->gitClient();
QStringList args = client->binary();
const QString workingDirectory = path(); const QString workingDirectory = path();
const QString checkoutDir = directory(); const QString checkoutDir = directory();
*checkoutPath = workingDirectory + QLatin1Char('/') + checkoutDir; *checkoutPath = workingDirectory + QLatin1Char('/') + checkoutDir;
QStringList baseArgs = client->binary();
const QString binary = baseArgs.front();
baseArgs.pop_front();
QStringList args;
args << QLatin1String("clone") << repository() << checkoutDir; args << QLatin1String("clone") << repository() << checkoutDir;
const QString binary = args.front();
args.pop_front(); VCSBase::ProcessCheckoutJob *job = new VCSBase::ProcessCheckoutJob;
VCSBase::AbstractCheckoutJob *job = const QProcessEnvironment env = client->processEnvironment();
new VCSBase::ProcessCheckoutJob(binary, args, workingDirectory, // 1) Basic checkout step
client->processEnvironment()); 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); 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 } // namespace Git

View File

@@ -46,6 +46,7 @@ struct CloneWizardPagePrivate;
class CloneWizardPage : public VCSBase::BaseCheckoutWizardPage class CloneWizardPage : public VCSBase::BaseCheckoutWizardPage
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool deleteMasterBranch READ deleteMasterBranch WRITE setDeleteMasterBranch)
public: public:
explicit CloneWizardPage(QWidget *parent = 0); explicit CloneWizardPage(QWidget *parent = 0);
virtual ~CloneWizardPage(); virtual ~CloneWizardPage();
@@ -54,6 +55,10 @@ public:
protected: protected:
virtual QString directoryFromRepository(const QString &r) const; virtual QString directoryFromRepository(const QString &r) const;
virtual QStringList branches(const QString &repository, int *current);
bool deleteMasterBranch() const;
void setDeleteMasterBranch(bool v);
private: private:
CloneWizardPagePrivate *d; CloneWizardPagePrivate *d;

View File

@@ -1265,6 +1265,28 @@ GitClient::StatusResult GitClient::gitStatus(const QString &workingDirectory,
return StatusChanged; 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) void GitClient::launchGitK(const QString &workingDirectory)
{ {
VCSBase::VCSBaseOutputWindow *outwin = VCSBase::VCSBaseOutputWindow::instance(); VCSBase::VCSBaseOutputWindow *outwin = VCSBase::VCSBaseOutputWindow::instance();

View File

@@ -205,6 +205,7 @@ public:
bool *onBranch = 0); bool *onBranch = 0);
void launchGitK(const QString &workingDirectory); void launchGitK(const QString &workingDirectory);
QStringList synchronousRepositoryBranches(const QString &repositoryURL);
GitSettings settings() const; GitSettings settings() const;
void setSettings(const GitSettings &s); void setSettings(const GitSettings &s);

View File

@@ -86,7 +86,7 @@ QSharedPointer<VCSBase::AbstractCheckoutJob> CloneWizard::createJob(const QList<
args << QLatin1String("clone") << page->repository() << directory; args << QLatin1String("clone") << page->repository() << directory;
*checkoutPath = path + QLatin1Char('/') + directory; *checkoutPath = path + QLatin1Char('/') + directory;
VCSBase::ProcessCheckoutJob *job = new VCSBase::ProcessCheckoutJob;
return QSharedPointer<VCSBase::AbstractCheckoutJob>(new VCSBase::ProcessCheckoutJob(settings.binary(), job->addStep(settings.binary(), args, path);
args, path)); return QSharedPointer<VCSBase::AbstractCheckoutJob>(job);
} }

View File

@@ -37,6 +37,7 @@ CloneWizardPage::CloneWizardPage(QWidget *parent)
setTitle(tr("Location")); setTitle(tr("Location"));
setSubTitle(tr("Specify repository URL, checkout directory and path.")); setSubTitle(tr("Specify repository URL, checkout directory and path."));
setRepositoryLabel(tr("Clone URL:")); setRepositoryLabel(tr("Clone URL:"));
setBranchSelectorVisible(false);
} }
QString CloneWizardPage::directoryFromRepository(const QString &repository) const QString CloneWizardPage::directoryFromRepository(const QString &repository) const

View File

@@ -86,8 +86,8 @@ QSharedPointer<VCSBase::AbstractCheckoutJob> CheckoutWizard::createJob(const QLi
const QStringList completeArgs = settings.hasAuthentication() ? const QStringList completeArgs = settings.hasAuthentication() ?
SubversionPlugin::addAuthenticationOptions(args, settings.user, settings.password) : SubversionPlugin::addAuthenticationOptions(args, settings.user, settings.password) :
args; args;
VCSBase::AbstractCheckoutJob *job = new VCSBase::ProcessCheckoutJob(binary, completeArgs, VCSBase::ProcessCheckoutJob *job = new VCSBase::ProcessCheckoutJob;
workingDirectory); job->addStep(binary, completeArgs, workingDirectory);
return QSharedPointer<VCSBase::AbstractCheckoutJob>(job); return QSharedPointer<VCSBase::AbstractCheckoutJob>(job);
} }

View File

@@ -38,6 +38,7 @@ CheckoutWizardPage::CheckoutWizardPage(QWidget *parent) :
setTitle(tr("Location")); setTitle(tr("Location"));
setSubTitle(tr("Specify repository URL, checkout directory and path.")); setSubTitle(tr("Specify repository URL, checkout directory and path."));
setRepositoryLabel(tr("Repository:")); setRepositoryLabel(tr("Repository:"));
setBranchSelectorVisible(false);
} }
QString CheckoutWizardPage::directoryFromRepository(const QString &repoIn) const QString CheckoutWizardPage::directoryFromRepository(const QString &repoIn) const

View File

@@ -30,6 +30,8 @@
#include "basecheckoutwizardpage.h" #include "basecheckoutwizardpage.h"
#include "ui_basecheckoutwizardpage.h" #include "ui_basecheckoutwizardpage.h"
#include <QtGui/QIcon>
namespace VCSBase { namespace VCSBase {
struct BaseCheckoutWizardPagePrivate { struct BaseCheckoutWizardPagePrivate {
@@ -54,6 +56,10 @@ BaseCheckoutWizardPage::BaseCheckoutWizardPage(QWidget *parent) :
d->ui.pathChooser->setExpectedKind(Utils::PathChooser::Directory); d->ui.pathChooser->setExpectedKind(Utils::PathChooser::Directory);
connect(d->ui.pathChooser, SIGNAL(validChanged()), this, SLOT(slotChanged())); 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() BaseCheckoutWizardPage::~BaseCheckoutWizardPage()
@@ -61,6 +67,28 @@ BaseCheckoutWizardPage::~BaseCheckoutWizardPage()
delete d; 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) void BaseCheckoutWizardPage::setRepositoryLabel(const QString &l)
{ {
d->ui.repositoryLabel->setText(l); d->ui.repositoryLabel->setText(l);
@@ -112,6 +140,35 @@ void BaseCheckoutWizardPage::setRepository(const QString &r)
d->ui.repositoryLineEdit->setText(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(), &current);
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) void BaseCheckoutWizardPage::slotRepositoryChanged(const QString &repo)
{ {
// Derive directory name from repository unless user manually edited it. // Derive directory name from repository unless user manually edited it.
@@ -125,6 +182,11 @@ QString BaseCheckoutWizardPage::directoryFromRepository(const QString &r) const
return r; return r;
} }
QStringList BaseCheckoutWizardPage::branches(const QString &, int *)
{
return QStringList();
}
void BaseCheckoutWizardPage::slotDirectoryEdited() void BaseCheckoutWizardPage::slotDirectoryEdited()
{ {
d->m_directoryEdited = true; d->m_directoryEdited = true;

View File

@@ -49,6 +49,7 @@ struct BaseCheckoutWizardPagePrivate;
class VCSBASE_EXPORT BaseCheckoutWizardPage : public QWizardPage { class VCSBASE_EXPORT BaseCheckoutWizardPage : public QWizardPage {
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool isBranchSelectorVisible READ isBranchSelectorVisible WRITE setBranchSelectorVisible)
public: public:
BaseCheckoutWizardPage(QWidget *parent = 0); BaseCheckoutWizardPage(QWidget *parent = 0);
~BaseCheckoutWizardPage(); ~BaseCheckoutWizardPage();
@@ -65,22 +66,36 @@ public:
bool isRepositoryReadOnly() const; bool isRepositoryReadOnly() const;
void setRepositoryReadOnly(bool v); void setRepositoryReadOnly(bool v);
QString branch() const;
void setBranch(const QString &);
virtual bool isComplete() const; virtual bool isComplete() const;
bool isBranchSelectorVisible() const ;
protected: protected:
void changeEvent(QEvent *e); void changeEvent(QEvent *e);
void setRepositoryLabel(const QString &l); void setRepositoryLabel(const QString &l);
void setDirectoryVisible(bool v); void setDirectoryVisible(bool v);
void setBranchSelectorVisible(bool v);
/* Determine a checkout directory name from /* Determine a checkout directory name from
* repository URL, that is, "protocol:/project" -> "project". */ * repository URL, that is, "protocol:/project" -> "project". */
virtual QString directoryFromRepository(const QString &r) const; 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: private slots:
void slotRepositoryChanged(const QString &url); void slotRepositoryChanged(const QString &url);
void slotDirectoryEdited(); void slotDirectoryEdited();
void slotChanged(); void slotChanged();
void slotRefreshBranches();
private: private:
BaseCheckoutWizardPagePrivate *d; BaseCheckoutWizardPagePrivate *d;

View File

@@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>464</width> <width>483</width>
<height>302</height> <height>237</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@@ -40,7 +40,35 @@
</widget> </widget>
</item> </item>
<item row="2" column="1"> <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> </item>
</layout> </layout>
</item> </item>

View File

@@ -30,10 +30,13 @@
#include "checkoutjobs.h" #include "checkoutjobs.h"
#include <vcsbaseplugin.h> #include <vcsbaseplugin.h>
#include <vcsbaseoutputwindow.h>
#include <QtCore/QDebug> #include <QtCore/QDebug>
#include <QtCore/QQueue>
#include <QtCore/QDir> #include <QtCore/QDir>
#include <utils/synchronousprocess.h> #include <utils/synchronousprocess.h>
#include <utils/qtcassert.h>
enum { debug = 0 }; enum { debug = 0 };
namespace VCSBase { 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 { struct ProcessCheckoutJobPrivate {
ProcessCheckoutJobPrivate(const QString &binary, ProcessCheckoutJobPrivate();
const QStringList &args,
const QString &workingDirectory,
QProcessEnvironment env);
QSharedPointer<QProcess> process; QSharedPointer<QProcess> process;
const QString binary; QQueue<ProcessCheckoutJobStep> stepQueue;
const QStringList args; QString binary;
}; };
// Use a terminal-less process to suppress SSH prompts. // Use a terminal-less process to suppress SSH prompts.
@@ -63,30 +78,15 @@ static inline QSharedPointer<QProcess> createProcess()
return Utils::SynchronousProcess::createProcess(flags); return Utils::SynchronousProcess::createProcess(flags);
} }
ProcessCheckoutJobPrivate::ProcessCheckoutJobPrivate(const QString &b, ProcessCheckoutJobPrivate::ProcessCheckoutJobPrivate() :
const QStringList &a, process(createProcess())
const QString &workingDirectory,
QProcessEnvironment processEnv) :
process(createProcess()),
binary(b),
args(a)
{ {
if (!workingDirectory.isEmpty())
process->setWorkingDirectory(workingDirectory);
VCSBasePlugin::setProcessEnvironment(&processEnv, false);
process->setProcessEnvironment(processEnv);
} }
ProcessCheckoutJob::ProcessCheckoutJob(const QString &binary, ProcessCheckoutJob::ProcessCheckoutJob(QObject *parent) :
const QStringList &args,
const QString &workingDirectory,
const QProcessEnvironment &env,
QObject *parent) :
AbstractCheckoutJob(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(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(finished(int,QProcess::ExitStatus)), this, SLOT(slotFinished(int,QProcess::ExitStatus)));
connect(d->process.data(), SIGNAL(readyReadStandardOutput()), this, SLOT(slotOutput())); connect(d->process.data(), SIGNAL(readyReadStandardOutput()), this, SLOT(slotOutput()));
@@ -99,6 +99,16 @@ ProcessCheckoutJob::~ProcessCheckoutJob()
delete d; 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() void ProcessCheckoutJob::slotOutput()
{ {
const QByteArray data = d->process->readAllStandardOutput(); const QByteArray data = d->process->readAllStandardOutput();
@@ -130,7 +140,7 @@ void ProcessCheckoutJob::slotFinished (int exitCode, QProcess::ExitStatus exitSt
case QProcess::NormalExit: case QProcess::NormalExit:
emit output(tr("The process terminated with exit code %1.").arg(exitCode)); emit output(tr("The process terminated with exit code %1.").arg(exitCode));
if (exitCode == 0) { if (exitCode == 0) {
emit succeeded(); slotNext();
} else { } else {
emit failed(tr("The process returned exit code %1.").arg(exitCode)); 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() 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() void ProcessCheckoutJob::cancel()

View File

@@ -72,13 +72,14 @@ class VCSBASE_EXPORT ProcessCheckoutJob : public AbstractCheckoutJob
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit ProcessCheckoutJob(const QString &binary, explicit ProcessCheckoutJob(QObject *parent = 0);
const QStringList &args,
const QString &workingDirectory = QString(),
const QProcessEnvironment &env = QProcessEnvironment::systemEnvironment(),
QObject *parent = 0);
virtual ~ProcessCheckoutJob(); virtual ~ProcessCheckoutJob();
void addStep(const QString &binary,
const QStringList &args,
const QString &workingDirectory = QString(),
const QProcessEnvironment &env = QProcessEnvironment::systemEnvironment());
virtual void start(); virtual void start();
virtual void cancel(); virtual void cancel();
@@ -86,6 +87,7 @@ private slots:
void slotError(QProcess::ProcessError error); void slotError(QProcess::ProcessError error);
void slotFinished (int exitCode, QProcess::ExitStatus exitStatus); void slotFinished (int exitCode, QProcess::ExitStatus exitStatus);
void slotOutput(); void slotOutput();
void slotNext();
private: private:
ProcessCheckoutJobPrivate *d; ProcessCheckoutJobPrivate *d;