diff --git a/src/plugins/vcsbase/checkoutprogresswizardpage.cpp b/src/plugins/vcsbase/checkoutprogresswizardpage.cpp
index 1de7d3737615e8ec881351494229e76dac10dc3f..d427a01f7fa6eb217c473bdcbb4a3fe573f3945c 100644
--- a/src/plugins/vcsbase/checkoutprogresswizardpage.cpp
+++ b/src/plugins/vcsbase/checkoutprogresswizardpage.cpp
@@ -132,7 +132,7 @@ void CheckoutProgressWizardPage::slotError(const QString &text)
 void CheckoutProgressWizardPage::terminate()
 {
     if (m_command)
-        m_command->terminate();
+        m_command->cancel();
 }
 
 bool CheckoutProgressWizardPage::isComplete() const
diff --git a/src/plugins/vcsbase/command.cpp b/src/plugins/vcsbase/command.cpp
index 85148aee10acfdbd4a2b8cadc65db1113256b776..27d62ea81faad2c7b51459df240052902d298226 100644
--- a/src/plugins/vcsbase/command.cpp
+++ b/src/plugins/vcsbase/command.cpp
@@ -42,6 +42,7 @@
 #include <QProcess>
 #include <QProcessEnvironment>
 #include <QFuture>
+#include <QFutureWatcher>
 #include <QtConcurrentRun>
 #include <QFileInfo>
 #include <QCoreApplication>
@@ -101,6 +102,8 @@ public:
     ProgressParser *m_progressParser;
     VcsBase::VcsBaseOutputWindow *m_outputWindow;
     bool m_progressiveOutput;
+    bool m_hadOutput;
+    QFutureWatcher<void> m_watcher;
 
     QList<Job> m_jobs;
 
@@ -121,6 +124,7 @@ CommandPrivate::CommandPrivate(const QString &binary,
     m_progressParser(0),
     m_outputWindow(VcsBase::VcsBaseOutputWindow::instance()),
     m_progressiveOutput(false),
+    m_hadOutput(false),
     m_lastExecSuccess(false),
     m_lastExecExitCode(-1)
 {
@@ -210,6 +214,8 @@ void Command::execute()
 
     // For some reason QtConcurrent::run() only works on this
     QFuture<void> task = QtConcurrent::run(&Command::run, this);
+    d->m_watcher.setFuture(task);
+    connect(&d->m_watcher, SIGNAL(canceled()), this, SLOT(cancel()));
     QString binary = QFileInfo(d->m_binaryPath).baseName();
     if (!binary.isEmpty())
         binary = binary.replace(0, 1, binary[0].toUpper()); // Upper the first letter
@@ -219,9 +225,9 @@ void Command::execute()
         Core::Id::fromString(binary + QLatin1String(".action")));
 }
 
-void Command::terminate()
+void Command::cancel()
 {
-    emit doTerminate();
+    emit terminate();
 }
 
 bool Command::lastExecutionSuccess() const
@@ -247,6 +253,8 @@ void Command::run(QFutureInterface<void> &future)
 
     if (d->m_progressParser)
         d->m_progressParser->setFuture(&future);
+    else
+        future.setProgressRange(0, 1);
     const int count = d->m_jobs.size();
     d->m_lastExecExitCode = -1;
     d->m_lastExecSuccess = true;
@@ -265,18 +273,24 @@ void Command::run(QFutureInterface<void> &future)
             break;
     }
 
-    if (!future.isCanceled()) {
-        if (!d->m_progressiveOutput) {
+    const QString canceledMessage = tr("Canceled");
+    if (d->m_progressiveOutput) {
+        if (!d->m_hadOutput && future.isCanceled())
+            emit output(canceledMessage);
+    } else {
+        if (stdOut.isEmpty() && future.isCanceled())
+            emit output(canceledMessage);
+        else
             emit output(stdOut);
-            if (!stdErr.isEmpty())
-                emit errorText(stdErr);
-        }
-
-        emit finished(d->m_lastExecSuccess, d->m_lastExecExitCode, cookie());
-        if (d->m_lastExecSuccess)
-            emit success(cookie());
+        if (!stdErr.isEmpty())
+            emit errorText(stdErr);
     }
 
+    emit finished(d->m_lastExecSuccess, d->m_lastExecExitCode, cookie());
+    if (d->m_lastExecSuccess)
+        emit success(cookie());
+    future.setProgressValue(future.progressMaximum());
+
     if (d->m_progressParser)
         d->m_progressParser->setFuture(0);
     // As it is used asynchronously, we need to delete ourselves
@@ -362,7 +376,7 @@ Utils::SynchronousProcessResponse Command::runVcs(const QStringList &arguments,
     } else {
         Utils::SynchronousProcess process;
         process.setExitCodeInterpreter(interpreter);
-        connect(this, SIGNAL(doTerminate()), &process, SLOT(terminate()));
+        connect(this, SIGNAL(terminate()), &process, SLOT(terminate()));
         if (!d->m_workingDirectory.isEmpty())
             process.setWorkingDirectory(d->m_workingDirectory);
 
@@ -535,8 +549,10 @@ void Command::bufferedOutput(const QString &text)
         d->m_progressParser->parseProgress(text);
     if (d->m_flags & VcsBasePlugin::ShowStdOutInLogWindow)
         d->m_outputWindow->append(text);
-    if (d->m_progressiveOutput)
+    if (d->m_progressiveOutput) {
         emit output(text);
+        d->m_hadOutput = true;
+    }
 }
 
 void Command::bufferedError(const QString &text)
diff --git a/src/plugins/vcsbase/command.h b/src/plugins/vcsbase/command.h
index bf4006187b3b5de3baa2d52946dde392b04aacb1..821db128e01cbaaabc7758379ad81a601601d96e 100644
--- a/src/plugins/vcsbase/command.h
+++ b/src/plugins/vcsbase/command.h
@@ -80,7 +80,6 @@ public:
     void addJob(const QStringList &arguments, Utils::ExitCodeInterpreter *interpreter = 0);
     void addJob(const QStringList &arguments, int timeout, Utils::ExitCodeInterpreter *interpreter = 0);
     void execute();
-    void terminate();
     bool lastExecutionSuccess() const;
     int lastExecutionExitCode() const;
 
@@ -114,16 +113,21 @@ private:
     Utils::SynchronousProcessResponse runSynchronous(const QStringList &arguments, int timeoutMS,
                                                      Utils::ExitCodeInterpreter *interpreter = 0);
 
-private slots:
-    void bufferedOutput(const QString &text);
-    void bufferedError(const QString &text);
+public slots:
+    void cancel();
 
 signals:
     void output(const QString &);
     void errorText(const QString &);
     void finished(bool ok, int exitCode, const QVariant &cookie);
     void success(const QVariant &cookie);
-    void doTerminate();
+
+private slots:
+    void bufferedOutput(const QString &text);
+    void bufferedError(const QString &text);
+
+signals:
+    void terminate(); // Internal
 
 private:
     class Internal::CommandPrivate *const d;