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(), &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)
 {
     // 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;