diff --git a/src/libs/utils/synchronousprocess.cpp b/src/libs/utils/synchronousprocess.cpp
index 0cf0caaf1da353540766a92d86ad1ae0397deda9..58b59f4c67a0d2c01e5cb293a039cfcf629adb9b 100644
--- a/src/libs/utils/synchronousprocess.cpp
+++ b/src/libs/utils/synchronousprocess.cpp
@@ -149,6 +149,12 @@ QTCREATOR_UTILS_EXPORT QDebug operator<<(QDebug str, const SynchronousProcessRes
     return str;
 }
 
+SynchronousProcessResponse::Result ExitCodeInterpreter::interpretExitCode(int code) const
+{
+    return code ? SynchronousProcessResponse::FinishedError
+                : SynchronousProcessResponse::Finished;
+}
+
 // Data for one channel buffer (stderr/stdout)
 struct ChannelBuffer {
     ChannelBuffer();
@@ -197,6 +203,7 @@ struct SynchronousProcessPrivate {
     void clearForRun();
 
     QTextCodec *m_codec;
+    ExitCodeInterpreter *m_exitCodeInterpreter;
     QTextCodec::ConverterState m_stdOutState;
     QTextCodec::ConverterState m_stdErrState;
     TerminalControllingProcess m_process;
@@ -216,6 +223,7 @@ struct SynchronousProcessPrivate {
 
 SynchronousProcessPrivate::SynchronousProcessPrivate() :
     m_codec(QTextCodec::codecForLocale()),
+    m_exitCodeInterpreter(0),
     m_hangTimerCount(0),
     m_maxHangTimerCount(defaultMaxHangTimerCount),
     m_startFailure(false),
@@ -339,6 +347,16 @@ void SynchronousProcess::setFlags(unsigned tc)
     d->m_process.setFlags(tc);
 }
 
+void SynchronousProcess::setExitCodeInterpreter(ExitCodeInterpreter *interpreter)
+{
+    d->m_exitCodeInterpreter = interpreter;
+}
+
+ExitCodeInterpreter *SynchronousProcess::exitCodeInterpreter() const
+{
+    return d->m_exitCodeInterpreter;
+}
+
 void SynchronousProcess::setWorkingDirectory(const QString &workingDirectory)
 {
     d->m_process.setWorkingDirectory(workingDirectory);
@@ -451,9 +469,14 @@ void SynchronousProcess::finished(int exitCode, QProcess::ExitStatus e)
     if (debug)
         qDebug() << Q_FUNC_INFO << exitCode << e;
     d->m_hangTimerCount = 0;
+
+    ExitCodeInterpreter defaultInterpreter(this);
+    ExitCodeInterpreter *currentInterpreter = d->m_exitCodeInterpreter
+            ? d->m_exitCodeInterpreter : &defaultInterpreter;
+
     switch (e) {
     case QProcess::NormalExit:
-        d->m_result.result = exitCode ? SynchronousProcessResponse::FinishedError : SynchronousProcessResponse::Finished;
+        d->m_result.result = currentInterpreter->interpretExitCode(exitCode);
         d->m_result.exitCode = exitCode;
         break;
     case QProcess::CrashExit:
diff --git a/src/libs/utils/synchronousprocess.h b/src/libs/utils/synchronousprocess.h
index 5aa1183d7596203af59e7fd0219bb179a1c1f3da..8cb224f00aaf5374af72467848a172f686d5c3fd 100644
--- a/src/libs/utils/synchronousprocess.h
+++ b/src/libs/utils/synchronousprocess.h
@@ -71,6 +71,14 @@ struct QTCREATOR_UTILS_EXPORT SynchronousProcessResponse
 
 QTCREATOR_UTILS_EXPORT QDebug operator<<(QDebug str, const SynchronousProcessResponse &);
 
+class QTCREATOR_UTILS_EXPORT ExitCodeInterpreter : public QObject
+{
+    Q_OBJECT
+public:
+    ExitCodeInterpreter(QObject *parent) : QObject(parent) {}
+    virtual SynchronousProcessResponse::Result interpretExitCode(int code) const;
+};
+
 class QTCREATOR_UTILS_EXPORT SynchronousProcess : public QObject
 {
     Q_OBJECT
@@ -115,6 +123,9 @@ public:
     unsigned flags() const;
     void setFlags(unsigned);
 
+    void setExitCodeInterpreter(ExitCodeInterpreter *interpreter);
+    ExitCodeInterpreter *exitCodeInterpreter() const;
+
     SynchronousProcessResponse run(const QString &binary, const QStringList &args);
 
     // Create a (derived) processes with flags applied.
diff --git a/src/plugins/bazaar/bazaarclient.cpp b/src/plugins/bazaar/bazaarclient.cpp
index 18d5415f83f6bfb0905c1a36a77e7634cad91f94..ceb56b5ca65bc1c437cfdc9d73b14feccd71c776 100644
--- a/src/plugins/bazaar/bazaarclient.cpp
+++ b/src/plugins/bazaar/bazaarclient.cpp
@@ -31,6 +31,7 @@
 
 #include <vcsbase/vcsbaseplugin.h>
 #include <vcsbase/vcsbaseeditorparameterwidget.h>
+#include <utils/synchronousprocess.h>
 
 #include <QDir>
 #include <QFileInfo>
@@ -40,6 +41,22 @@
 namespace Bazaar {
 namespace Internal {
 
+class BazaarDiffExitCodeInterpreter : public Utils::ExitCodeInterpreter
+{
+    Q_OBJECT
+public:
+    BazaarDiffExitCodeInterpreter(QObject *parent) : Utils::ExitCodeInterpreter(parent) {}
+    Utils::SynchronousProcessResponse::Result interpretExitCode(int code) const;
+
+};
+
+Utils::SynchronousProcessResponse::Result BazaarDiffExitCodeInterpreter::interpretExitCode(int code) const
+{
+    if (code < 0 || code > 2)
+        return Utils::SynchronousProcessResponse::FinishedError;
+    return Utils::SynchronousProcessResponse::Finished;
+}
+
 BazaarClient::BazaarClient(BazaarSettings *settings) :
     VcsBase::VcsBaseClient(settings)
 {
@@ -142,6 +159,16 @@ QString BazaarClient::vcsCommandString(VcsCommand cmd) const
     }
 }
 
+Utils::ExitCodeInterpreter *BazaarClient::exitCodeInterpreter(VcsCommand cmd, QObject *parent) const
+{
+    switch (cmd) {
+    case DiffCommand:
+        return new BazaarDiffExitCodeInterpreter(parent);
+    default:
+        return 0;
+    }
+}
+
 QStringList BazaarClient::revisionSpec(const QString &revision) const
 {
     QStringList args;
diff --git a/src/plugins/bazaar/bazaarclient.h b/src/plugins/bazaar/bazaarclient.h
index 0bc49c230612a435240c50eeda38279f6b72357d..d0b1f4a216f04ec5870e36c2bfceef434829b875 100644
--- a/src/plugins/bazaar/bazaarclient.h
+++ b/src/plugins/bazaar/bazaarclient.h
@@ -61,6 +61,7 @@ public:
 protected:
     Core::Id vcsEditorKind(VcsCommand cmd) const;
     QString vcsCommandString(VcsCommand cmd) const;
+    Utils::ExitCodeInterpreter *exitCodeInterpreter(VcsCommand cmd, QObject *parent) const;
     QStringList revisionSpec(const QString &revision) const;
     VcsBase::VcsBaseEditorParameterWidget *createDiffEditor(const QString &workingDir,
                                                             const QStringList &files,
diff --git a/src/plugins/vcsbase/command.cpp b/src/plugins/vcsbase/command.cpp
index 8aa3d1fdf6df1395ce50c06279b970f8bb1ac660..85148aee10acfdbd4a2b8cadc65db1113256b776 100644
--- a/src/plugins/vcsbase/command.cpp
+++ b/src/plugins/vcsbase/command.cpp
@@ -78,10 +78,11 @@ class CommandPrivate
 {
 public:
     struct Job {
-        explicit Job(const QStringList &a, int t);
+        explicit Job(const QStringList &a, int t, Utils::ExitCodeInterpreter *interpreter = 0);
 
         QStringList arguments;
         int timeout;
+        Utils::ExitCodeInterpreter *exitCodeInterpreter;
     };
 
     CommandPrivate(const QString &binary,
@@ -130,9 +131,10 @@ CommandPrivate::~CommandPrivate()
     delete m_progressParser;
 }
 
-CommandPrivate::Job::Job(const QStringList &a, int t) :
+CommandPrivate::Job::Job(const QStringList &a, int t, Utils::ExitCodeInterpreter *interpreter) :
     arguments(a),
-    timeout(t)
+    timeout(t),
+    exitCodeInterpreter(interpreter)
 {
     // Finished cookie is emitted via queued slot, needs metatype
     static const int qvMetaId = qRegisterMetaType<QVariant>();
@@ -188,14 +190,14 @@ void Command::addFlags(unsigned f)
     d->m_flags |= f;
 }
 
-void Command::addJob(const QStringList &arguments)
+void Command::addJob(const QStringList &arguments, Utils::ExitCodeInterpreter *interpreter)
 {
-    addJob(arguments, defaultTimeout());
+    addJob(arguments, defaultTimeout(), interpreter);
 }
 
-void Command::addJob(const QStringList &arguments, int timeout)
+void Command::addJob(const QStringList &arguments, int timeout, Utils::ExitCodeInterpreter *interpreter)
 {
-    d->m_jobs.push_back(Internal::CommandPrivate::Job(arguments, timeout));
+    d->m_jobs.push_back(Internal::CommandPrivate::Job(arguments, timeout, interpreter));
 }
 
 void Command::execute()
@@ -249,10 +251,12 @@ void Command::run(QFutureInterface<void> &future)
     d->m_lastExecExitCode = -1;
     d->m_lastExecSuccess = true;
     for (int j = 0; j < count; j++) {
-        const int timeOutSeconds = d->m_jobs.at(j).timeout;
+        const Internal::CommandPrivate::Job &job = d->m_jobs.at(j);
+        const int timeOutSeconds = job.timeout;
         Utils::SynchronousProcessResponse resp = runVcs(
-                    d->m_jobs.at(j).arguments,
-                    timeOutSeconds >= 0 ? timeOutSeconds * 1000 : -1);
+                    job.arguments,
+                    timeOutSeconds >= 0 ? timeOutSeconds * 1000 : -1,
+                    job.exitCodeInterpreter);
         stdOut += resp.stdOut;
         stdErr += resp.stdErr;
         d->m_lastExecExitCode = resp.exitCode;
@@ -309,7 +313,8 @@ signals:
     void appendMessage(const QString &text);
 };
 
-Utils::SynchronousProcessResponse Command::runVcs(const QStringList &arguments, int timeoutMS)
+Utils::SynchronousProcessResponse Command::runVcs(const QStringList &arguments, int timeoutMS,
+                                                  Utils::ExitCodeInterpreter *interpreter)
 {
     Utils::SynchronousProcessResponse response;
     OutputProxy outputProxy;
@@ -353,9 +358,10 @@ Utils::SynchronousProcessResponse Command::runVcs(const QStringList &arguments,
     //    if (d->m_flags & ExpectRepoChanges)
     //        Core::DocumentManager::expectDirectoryChange(d->m_workingDirectory);
     if (d->m_flags & VcsBasePlugin::FullySynchronously) {
-        response = runSynchronous(arguments, timeoutMS);
+        response = runSynchronous(arguments, timeoutMS, interpreter);
     } else {
         Utils::SynchronousProcess process;
+        process.setExitCodeInterpreter(interpreter);
         connect(this, SIGNAL(doTerminate()), &process, SLOT(terminate()));
         if (!d->m_workingDirectory.isEmpty())
             process.setWorkingDirectory(d->m_workingDirectory);
@@ -412,7 +418,8 @@ Utils::SynchronousProcessResponse Command::runVcs(const QStringList &arguments,
     return response;
 }
 
-Utils::SynchronousProcessResponse Command::runSynchronous(const QStringList &arguments, int timeoutMS)
+Utils::SynchronousProcessResponse Command::runSynchronous(const QStringList &arguments, int timeoutMS,
+                                                          Utils::ExitCodeInterpreter *interpreter)
 {
     Utils::SynchronousProcessResponse response;
 
@@ -465,15 +472,15 @@ Utils::SynchronousProcessResponse Command::runSynchronous(const QStringList &arg
         }
     }
 
+    Utils::ExitCodeInterpreter defaultInterpreter(this);
+    Utils::ExitCodeInterpreter *currentInterpreter = interpreter ? interpreter : &defaultInterpreter;
     // Result
     if (timedOut) {
         response.result = Utils::SynchronousProcessResponse::Hang;
     } else if (process->exitStatus() != QProcess::NormalExit) {
         response.result = Utils::SynchronousProcessResponse::TerminatedAbnormally;
     } else {
-        response.result = process->exitCode() == 0 ?
-                          Utils::SynchronousProcessResponse::Finished :
-                          Utils::SynchronousProcessResponse::FinishedError;
+        response.result = currentInterpreter->interpretExitCode(process->exitCode());
     }
     return response;
 }
diff --git a/src/plugins/vcsbase/command.h b/src/plugins/vcsbase/command.h
index dd41f91dcf0688eb89b4b3991b7b969e02373fa9..bf4006187b3b5de3baa2d52946dde392b04aacb1 100644
--- a/src/plugins/vcsbase/command.h
+++ b/src/plugins/vcsbase/command.h
@@ -77,8 +77,8 @@ public:
             const QProcessEnvironment &environment);
     ~Command();
 
-    void addJob(const QStringList &arguments);
-    void addJob(const QStringList &arguments, int timeout);
+    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;
@@ -103,14 +103,16 @@ public:
     void setProgressParser(ProgressParser *parser);
     void setProgressiveOutput(bool progressive);
 
-    Utils::SynchronousProcessResponse runVcs(const QStringList &arguments, int timeoutMS);
+    Utils::SynchronousProcessResponse runVcs(const QStringList &arguments, int timeoutMS,
+                                             Utils::ExitCodeInterpreter *interpreter = 0);
     // Make sure to not pass through the event loop at all:
     bool runFullySynchronous(const QStringList &arguments, int timeoutMS,
                              QByteArray *outputData, QByteArray *errorData);
 
 private:
     void run(QFutureInterface<void> &future);
-    Utils::SynchronousProcessResponse runSynchronous(const QStringList &arguments, int timeoutMS);
+    Utils::SynchronousProcessResponse runSynchronous(const QStringList &arguments, int timeoutMS,
+                                                     Utils::ExitCodeInterpreter *interpreter = 0);
 
 private slots:
     void bufferedOutput(const QString &text);
diff --git a/src/plugins/vcsbase/vcsbaseclient.cpp b/src/plugins/vcsbase/vcsbaseclient.cpp
index f23580b72c454830eb0c0f1b31d4bb809fc5974a..1d83c0ef8b125e3afcede8dcff185d00bf7e2687 100644
--- a/src/plugins/vcsbase/vcsbaseclient.cpp
+++ b/src/plugins/vcsbase/vcsbaseclient.cpp
@@ -365,7 +365,8 @@ void VcsBaseClient::diff(const QString &workingDir, const QStringList &files,
     QStringList args;
     const QStringList paramArgs = paramWidget != 0 ? paramWidget->arguments() : QStringList();
     args << vcsCmdString << extraOptions << paramArgs << files;
-    enqueueJob(createCommand(workingDir, editor), args);
+    Command *command = createCommand(workingDir, editor);
+    enqueueJob(command, args, exitCodeInterpreter(DiffCommand, command));
 }
 
 void VcsBaseClient::log(const QString &workingDir, const QStringList &files,
@@ -461,6 +462,13 @@ QString VcsBaseClient::vcsCommandString(VcsCommand cmd) const
     return QString();
 }
 
+Utils::ExitCodeInterpreter *VcsBaseClient::exitCodeInterpreter(VcsCommand cmd, QObject *parent) const
+{
+    Q_UNUSED(cmd)
+    Q_UNUSED(parent)
+    return 0;
+}
+
 void VcsBaseClient::import(const QString &repositoryRoot, const QStringList &files,
                            const QStringList &extraOptions)
 {
@@ -605,9 +613,9 @@ Command *VcsBaseClient::createCommand(const QString &workingDirectory,
     return cmd;
 }
 
-void VcsBaseClient::enqueueJob(Command *cmd, const QStringList &args)
+void VcsBaseClient::enqueueJob(Command *cmd, const QStringList &args, Utils::ExitCodeInterpreter *interpreter)
 {
-    cmd->addJob(args);
+    cmd->addJob(args, interpreter);
     cmd->execute();
 }
 
diff --git a/src/plugins/vcsbase/vcsbaseclient.h b/src/plugins/vcsbase/vcsbaseclient.h
index 91d90d1e332bd081fcce633b3704edf32b8ffde1..f4c9bf957f35ed45bb37ddceec6df4d58a4aa37d 100644
--- a/src/plugins/vcsbase/vcsbaseclient.h
+++ b/src/plugins/vcsbase/vcsbaseclient.h
@@ -44,6 +44,7 @@ QT_END_NAMESPACE
 
 namespace Utils {
 struct SynchronousProcessResponse;
+class ExitCodeInterpreter;
 }
 
 namespace VcsBase {
@@ -150,6 +151,7 @@ protected:
     };
     virtual QString vcsCommandString(VcsCommand cmd) const;
     virtual Core::Id vcsEditorKind(VcsCommand cmd) const = 0;
+    virtual Utils::ExitCodeInterpreter *exitCodeInterpreter(VcsCommand cmd, QObject *parent) const;
 
     virtual QStringList revisionSpec(const QString &revision) const = 0;
     virtual VcsBaseEditorParameterWidget *createDiffEditor(const QString &workingDir,
@@ -183,7 +185,7 @@ protected:
     Command *createCommand(const QString &workingDirectory,
                            VcsBase::VcsBaseEditorWidget *editor = 0,
                            JobOutputBindMode mode = NoOutputBind);
-    void enqueueJob(Command *cmd, const QStringList &args);
+    void enqueueJob(Command *cmd, const QStringList &args, Utils::ExitCodeInterpreter *interpreter = 0);
 
     void resetCachedVcsInfo(const QString &workingDir);