diff --git a/src/libs/utils/submiteditorwidget.cpp b/src/libs/utils/submiteditorwidget.cpp
index 3513c27715d4eea1caef363dfc32d09bc70486eb..8f854217de84166164c82eb9b4050a406f43040b 100644
--- a/src/libs/utils/submiteditorwidget.cpp
+++ b/src/libs/utils/submiteditorwidget.cpp
@@ -234,6 +234,16 @@ void SubmitEditorWidget::setFileNameColumn(int c)
     m_d->m_fileNameColumn = c;
 }
 
+QAbstractItemView::SelectionMode SubmitEditorWidget::fileListSelectionMode() const
+{
+    return m_d->m_ui.fileView->selectionMode();
+}
+
+void SubmitEditorWidget::setFileListSelectionMode(QAbstractItemView::SelectionMode sm)
+{
+    m_d->m_ui.fileView->setSelectionMode(sm);
+}
+
 void SubmitEditorWidget::setFileModel(QAbstractItemModel *model)
 {
     m_d->m_ui.fileView->clearSelection(); // trigger the change signals
diff --git a/src/libs/utils/submiteditorwidget.h b/src/libs/utils/submiteditorwidget.h
index 788709f773b723c3866373dc246385a66268b30a..8d8883e1f9b59348bf7989fe387c23f7f888ffb1 100644
--- a/src/libs/utils/submiteditorwidget.h
+++ b/src/libs/utils/submiteditorwidget.h
@@ -37,6 +37,7 @@
 #include "utils_global.h"
 
 #include <QtGui/QWidget>
+#include <QtGui/QAbstractItemView>
 
 QT_BEGIN_NAMESPACE
 class QPlainTextEdit;
@@ -75,6 +76,7 @@ class QWORKBENCH_UTILS_EXPORT SubmitEditorWidget : public QWidget
     Q_DISABLE_COPY(SubmitEditorWidget)
     Q_PROPERTY(QString descriptionText READ descriptionText WRITE setDescriptionText DESIGNABLE true)
     Q_PROPERTY(int fileNameColumn READ fileNameColumn WRITE setFileNameColumn DESIGNABLE false)
+    Q_PROPERTY(QAbstractItemView::SelectionMode fileListSelectionMode READ fileListSelectionMode WRITE setFileListSelectionMode DESIGNABLE true)
 public:
     explicit SubmitEditorWidget(QWidget *parent = 0);
     virtual ~SubmitEditorWidget();
@@ -92,6 +94,9 @@ public:
     int fileNameColumn() const;
     void setFileNameColumn(int c);
 
+    QAbstractItemView::SelectionMode fileListSelectionMode() const;
+    void setFileListSelectionMode(QAbstractItemView::SelectionMode sm);
+
     void setFileModel(QAbstractItemModel *model);
     QAbstractItemModel *fileModel() const;
 
diff --git a/src/plugins/git/commitdata.cpp b/src/plugins/git/commitdata.cpp
index ada478e3743c283f1e681839a9adadd40e74c60f..65962ef557c614c41e86bc55bdf4eb7f5a4a4c69 100644
--- a/src/plugins/git/commitdata.cpp
+++ b/src/plugins/git/commitdata.cpp
@@ -130,6 +130,11 @@ static inline bool addStateFileSpecification(const QString &line, QList<CommitDa
     \endcode
 */
 
+bool CommitData::filesEmpty() const
+{
+    return stagedFiles.empty() && unstagedFiles.empty() && untrackedFiles.empty();
+}
+
 bool CommitData::parseFilesFromStatus(const QString &output)
 {
     enum State { None, CommitFiles, NotUpdatedFiles, UntrackedFiles };
@@ -183,7 +188,7 @@ bool CommitData::parseFilesFromStatus(const QString &output)
             }
         }
     }
-    return !stagedFiles.empty() || !unstagedFiles.empty() || !untrackedFiles.empty();
+    return true;
 }
 
 // Convert a spec pair list to a list of file names, optionally
diff --git a/src/plugins/git/commitdata.h b/src/plugins/git/commitdata.h
index 6cb5ddb42b9ca4f46996f7f1b3788bc4360867c1..ca9779c69ece88df990d83a9bef19059bcfbead3 100644
--- a/src/plugins/git/commitdata.h
+++ b/src/plugins/git/commitdata.h
@@ -77,6 +77,8 @@ struct CommitData
     // from a git status output
     bool parseFilesFromStatus(const QString &output);
 
+    bool filesEmpty() const;
+
     // Convenience to retrieve the file names from
     // the specification list. Optionally filter for a certain state
     QStringList stagedFileNames(const QString &stateFilter = QString()) const;
diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp
index d1ebda300b4bcfbe4329fc55bc4103d19f1fead3..5ae6d0b7dac1bb5bf0fe86d5af041055772c7482 100644
--- a/src/plugins/git/gitclient.cpp
+++ b/src/plugins/git/gitclient.cpp
@@ -184,12 +184,14 @@ VCSBase::VCSBaseEditor
     return rc;
 }
 
-void GitClient::diff(const QString &workingDirectory, const QStringList &fileNames)
+void GitClient::diff(const QString &workingDirectory,
+                     const QStringList &diffArgs,
+                     const QStringList &fileNames)
 {
       if (Git::Constants::debug)
         qDebug() << "diff" << workingDirectory << fileNames;
     QStringList arguments;
-    arguments << QLatin1String("diff") << QLatin1String("--") << fileNames;
+    arguments << QLatin1String("diff") << diffArgs << QLatin1String("--") << fileNames;
 
     const QString kind = QLatin1String(Git::Constants::GIT_DIFF_EDITOR_KIND);
     const QString title = tr("Git Diff");
@@ -199,14 +201,16 @@ void GitClient::diff(const QString &workingDirectory, const QStringList &fileNam
 
 }
 
-void GitClient::diff(const QString &workingDirectory, const QString &fileName)
+void GitClient::diff(const QString &workingDirectory,
+                     const QStringList &diffArgs,
+                     const QString &fileName)
 {
     if (Git::Constants::debug)
         qDebug() << "diff" << workingDirectory << fileName;
     QStringList arguments;
     arguments << QLatin1String("diff");
     if (!fileName.isEmpty())
-        arguments << QLatin1String("--") << fileName;
+        arguments << diffArgs << QLatin1String("--") << fileName;
 
     const QString kind = QLatin1String(Git::Constants::GIT_DIFF_EDITOR_KIND);
     const QString title = tr("Git Diff %1").arg(fileName);
@@ -710,6 +714,10 @@ bool GitClient::getCommitData(const QString &workingDirectory,
     }
     // Filter out untracked files that are not part of the project
     filterUntrackedFilesOfProject(repoDirectory, &d->untrackedFiles);
+    if (d->filesEmpty()) {
+        *errorMessage = msgNoChangedFiles();
+        return false;
+    }
 
     d->panelData.author = readConfigValue(workingDirectory, QLatin1String("user.name"));
     d->panelData.email = readConfigValue(workingDirectory, QLatin1String("user.email"));
diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h
index f09daa00ab8e74d0106a12abfd6118cc83db2e57..43a0957d913a68061de7c0917526f6a099db0a2a 100644
--- a/src/plugins/git/gitclient.h
+++ b/src/plugins/git/gitclient.h
@@ -78,8 +78,8 @@ public:
     static QString findRepositoryForFile(const QString &fileName);
     static QString findRepositoryForDirectory(const QString &dir);
 
-    void diff(const QString &workingDirectory, const QString &fileName);
-    void diff(const QString &workingDirectory, const QStringList &fileNames);
+    void diff(const QString &workingDirectory, const QStringList &diffArgs, const QString &fileName);
+    void diff(const QString &workingDirectory, const QStringList &diffArgs, const QStringList &fileNames);
 
     void status(const QString &workingDirectory);
     void log(const QString &workingDirectory, const QString &fileName);
diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp
index 2ef08083393531aca4164993246fa6b0356dedcd..50214c7c3542f0b37c1e03ab75310a0a5415316a 100644
--- a/src/plugins/git/gitplugin.cpp
+++ b/src/plugins/git/gitplugin.cpp
@@ -450,19 +450,24 @@ void GitPlugin::extensionsInitialized()
     m_projectExplorer = ExtensionSystem::PluginManager::instance()->getObject<ProjectExplorer::ProjectExplorerPlugin>();
 }
 
-void GitPlugin::submitEditorDiff(const QStringList &files)
+void GitPlugin::submitEditorDiffStaged(const QStringList &files)
 {
-    if (files.empty())
-        return;
-    m_gitClient->diff(m_submitRepository, files);
+    if (!files.empty())
+        m_gitClient->diff(m_submitRepository, QStringList(QLatin1String("--cached")), files);
+}
+
+void GitPlugin::submitEditorDiffUnstaged(const QStringList &files)
+{
+    if (!files.empty())
+        m_gitClient->diff(m_submitRepository, QStringList(), files);
 }
 
 void GitPlugin::diffCurrentFile()
 {
-    QFileInfo fileInfo = currentFile();
-    QString fileName = fileInfo.fileName();
-    QString workingDirectory = fileInfo.absolutePath();
-    m_gitClient->diff(workingDirectory, fileName);
+    const QFileInfo fileInfo = currentFile();
+    const QString fileName = fileInfo.fileName();
+    const QString workingDirectory = fileInfo.absolutePath();
+    m_gitClient->diff(workingDirectory, QStringList(), fileName);
 }
 
 void GitPlugin::diffCurrentProject()
@@ -470,7 +475,7 @@ void GitPlugin::diffCurrentProject()
     QString workingDirectory = getWorkingDirectory();
     if (workingDirectory.isEmpty())
         return;
-    m_gitClient->diff(workingDirectory, QString());
+    m_gitClient->diff(workingDirectory, QStringList(), QString());
 }
 
 QFileInfo GitPlugin::currentFile() const
@@ -640,7 +645,8 @@ Core::IEditor *GitPlugin::openSubmitEditor(const QString &fileName, const Commit
     m_undoAction->setEnabled(false);
     m_redoAction->setEnabled(false);
     submitEditor->setCommitData(cd);
-    connect(submitEditor, SIGNAL(diffSelectedFiles(QStringList)), this, SLOT(submitEditorDiff(QStringList)));
+    connect(submitEditor, SIGNAL(diffStaged(QStringList)), this, SLOT(submitEditorDiffStaged(QStringList)));
+    connect(submitEditor, SIGNAL(diffUnstaged(QStringList)), this, SLOT(submitEditorDiffUnstaged(QStringList)));
     return editor;
 }
 
diff --git a/src/plugins/git/gitplugin.h b/src/plugins/git/gitplugin.h
index 39287e1939a253c20c607c9625999b40b1e2fec1..9fdde403d672ba6ec08a760ec8c956c95c37f655 100644
--- a/src/plugins/git/gitplugin.h
+++ b/src/plugins/git/gitplugin.h
@@ -108,7 +108,8 @@ public slots:
 private slots:
     void                        diffCurrentFile();
     void                        diffCurrentProject();
-    void                        submitEditorDiff(const QStringList &);
+    void                        submitEditorDiffUnstaged(const QStringList &);
+    void                        submitEditorDiffStaged(const QStringList &);
     void                        submitCurrentLog();
     void                        statusFile();
     void                        statusProject();
diff --git a/src/plugins/git/gitsubmiteditor.cpp b/src/plugins/git/gitsubmiteditor.cpp
index d34a78240d21301e168a6f1249fbf48ded86db1a..fbdc4e51325b415f23cbb18a62fedf1f2c351654 100644
--- a/src/plugins/git/gitsubmiteditor.cpp
+++ b/src/plugins/git/gitsubmiteditor.cpp
@@ -43,10 +43,22 @@
 namespace Git {
 namespace Internal {
 
+enum { FileTypeRole = Qt::UserRole + 1 };
+enum FileType { StagedFile , UnstagedFile, UntrackedFile };
+
+/* The problem with git is that no diff can be obtained to for a random
+ * multiselection of staged/unstaged files; it requires the --cached
+ * option for staged files. So, we set the file list to
+ * single selection and sort the files manual according to a type
+ * flag we add to the model. */
+
 GitSubmitEditor::GitSubmitEditor(const VCSBase::VCSBaseSubmitEditorParameters *parameters, QWidget *parent) :
-    VCSBaseSubmitEditor(parameters, new GitSubmitEditorWidget(parent))
+    VCSBaseSubmitEditor(parameters, new GitSubmitEditorWidget(parent)),
+    m_model(0)
 {
     setDisplayName(tr("Git Commit"));
+    setFileListSelectionMode(QAbstractItemView::SingleSelection);
+    connect(this, SIGNAL(diffSelectedFiles(QStringList)), this, SLOT(slotDiffSelected(QStringList)));
 }
 
 GitSubmitEditorWidget *GitSubmitEditor::submitEditorWidget()
@@ -54,14 +66,20 @@ GitSubmitEditorWidget *GitSubmitEditor::submitEditorWidget()
     return static_cast<GitSubmitEditorWidget *>(widget());
 }
 
-static void addStateFileListToModel(const QList<CommitData::StateFilePair> &l,
-                                    VCSBase::SubmitFileModel *model,
-                                    bool checked)
+// Utility to add a list of state/file pairs to the model
+// setting a file type.
+static void addStateFileListToModel(const QList<CommitData::StateFilePair> &l,                               
+                                    bool checked, FileType ft,
+                                    VCSBase::SubmitFileModel *model)
 {
+
     typedef QList<CommitData::StateFilePair>::const_iterator ConstIterator;
-    const ConstIterator cend = l.constEnd();
-    for (ConstIterator it = l.constBegin(); it != cend; ++it)
-        model->addFile(it->second, it->first, checked);
+    if (!l.empty()) {
+        const ConstIterator cend = l.constEnd();
+        const QVariant fileTypeData(ft);
+        for (ConstIterator it = l.constBegin(); it != cend; ++it)
+            model->addFile(it->second, it->first, checked).front()->setData(fileTypeData, FileTypeRole);
+    }
 }
 
 void GitSubmitEditor::setCommitData(const CommitData &d)
@@ -69,16 +87,37 @@ void GitSubmitEditor::setCommitData(const CommitData &d)
     submitEditorWidget()->setPanelData(d.panelData);
     submitEditorWidget()->setPanelInfo(d.panelInfo);
 
-    VCSBase::SubmitFileModel *model = new VCSBase::SubmitFileModel(this);
-    addStateFileListToModel(d.stagedFiles, model, true);
-    addStateFileListToModel(d.unstagedFiles, model, false);
+    m_model = new VCSBase::SubmitFileModel(this);
+    addStateFileListToModel(d.stagedFiles,   true,  StagedFile,   m_model);
+    addStateFileListToModel(d.unstagedFiles, false, UnstagedFile, m_model);
     if (!d.untrackedFiles.empty()) {
         const QString untrackedSpec = QLatin1String("untracked");
+        const QVariant fileTypeData(UntrackedFile);
         const QStringList::const_iterator cend = d.untrackedFiles.constEnd();
         for (QStringList::const_iterator it = d.untrackedFiles.constBegin(); it != cend; ++it)
-            model->addFile(*it, untrackedSpec, false);
+            m_model->addFile(*it, untrackedSpec, false).front()->setData(fileTypeData, FileTypeRole);
+    }
+    setFileModel(m_model);
+}
+
+void GitSubmitEditor::slotDiffSelected(const QStringList &files)
+{
+    QList<QStandardItem *> fileRow = m_model->findRow(files.front(), fileNameColumn());
+    if (fileRow.empty())
+        return;
+    const FileType ft = static_cast<FileType>(fileRow.front()->data(FileTypeRole).toInt());
+    switch (ft) {
+        case StagedFile:
+            emit diffStaged(files);
+            break;
+        case UnstagedFile:
+            emit diffUnstaged(files);
+            break;
+        case UntrackedFile:
+            break;
     }
-    setFileModel(model);
+
+
 }
 
 GitSubmitEditorPanelData GitSubmitEditor::panelData() const
diff --git a/src/plugins/git/gitsubmiteditor.h b/src/plugins/git/gitsubmiteditor.h
index a1a80ac22cf11be556f6dfe39fb27a602c79e91f..78b99682d0d2949d694084fe2813a18768472eae 100644
--- a/src/plugins/git/gitsubmiteditor.h
+++ b/src/plugins/git/gitsubmiteditor.h
@@ -38,6 +38,10 @@
 
 #include <QtCore/QStringList>
 
+namespace VCSBase {
+    class SubmitFileModel;
+}
+
 namespace Git {
 namespace Internal {
 
@@ -54,8 +58,17 @@ public:
     void setCommitData(const CommitData &);
     GitSubmitEditorPanelData panelData() const;
 
+signals:
+    void diffStaged(const QStringList &);
+    void diffUnstaged(const QStringList &);
+
+private slots:
+    void slotDiffSelected(const QStringList &);
+
 private:
     inline GitSubmitEditorWidget *submitEditorWidget();
+
+    VCSBase::SubmitFileModel *m_model;
 };
 
 } // namespace Internal
diff --git a/src/plugins/vcsbase/submitfilemodel.cpp b/src/plugins/vcsbase/submitfilemodel.cpp
index f12eab38d14bd0291346c346dfe88a08435eed79..e38c1f4e389ca5c2a776f21f26cb358b0f940119 100644
--- a/src/plugins/vcsbase/submitfilemodel.cpp
+++ b/src/plugins/vcsbase/submitfilemodel.cpp
@@ -48,20 +48,47 @@ SubmitFileModel::SubmitFileModel(QObject *parent) :
     setHorizontalHeaderLabels(headerLabels);
 }
 
-QList<QStandardItem *> SubmitFileModel::addFile(const QString &fileName, const QString &status, bool checked)
+QList<QStandardItem *> SubmitFileModel::createFileRow(const QString &fileName, const QString &status, bool checked)
 {
     if (VCSBase::Constants::Internal::debug)
         qDebug() << Q_FUNC_INFO << fileName << status << checked;
     QStandardItem *statusItem = new QStandardItem(status);
     statusItem->setCheckable(true);
     statusItem->setCheckState(checked ? Qt::Checked : Qt::Unchecked);
+    statusItem->setFlags(Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled);
     QStandardItem *fileItem = new QStandardItem(fileName);
+    fileItem->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
     QList<QStandardItem *> row;
     row << statusItem << fileItem;
+    return row;
+}
+
+QList<QStandardItem *> SubmitFileModel::addFile(const QString &fileName, const QString &status, bool checked)
+{
+    const QList<QStandardItem *> row = createFileRow(fileName, status, checked);
     appendRow(row);
     return row;
 }
 
+QList<QStandardItem *> SubmitFileModel::rowAt(int row) const
+{
+    const int colCount = columnCount();
+    QList<QStandardItem *> rc;
+    for (int c = 0; c < colCount; c++)
+        rc.push_back(item(row, c));
+    return rc;
+}
+
+QList<QStandardItem *> SubmitFileModel::findRow(const QString &text, int column) const
+{
+    // Single item
+    const QList<QStandardItem *> items = findItems(text, Qt::MatchExactly, column);
+    if (items.empty())
+        return items;
+    // Compile row
+    return rowAt(items.front()->row());
+ }
+
 unsigned SubmitFileModel::filter(const QStringList &filter, int column)
 {
     unsigned rc = 0;
diff --git a/src/plugins/vcsbase/submitfilemodel.h b/src/plugins/vcsbase/submitfilemodel.h
index fef89df83bef6b4e4d1d92d14566c822cfb69550..e6a0cd76f20d6eb1e673f91119a8b2242b5da5a7 100644
--- a/src/plugins/vcsbase/submitfilemodel.h
+++ b/src/plugins/vcsbase/submitfilemodel.h
@@ -49,9 +49,16 @@ class VCSBASE_EXPORT SubmitFileModel : public QStandardItemModel
 public:
     explicit SubmitFileModel(QObject *parent = 0);
 
-    // Convenience to add a file plus status text.
+    // Convenience to create and add rows containing a file plus status text.
+    static QList<QStandardItem *> createFileRow(const QString &fileName, const QString &status = QString(), bool checked = true);
     QList<QStandardItem *> addFile(const QString &fileName, const QString &status = QString(), bool checked = true);
 
+    // Find convenience that returns the whole row (as opposed to QStandardItemModel::find).
+    QList<QStandardItem *> findRow(const QString &text, int column = 0) const;
+
+    // Convenience to obtain a row
+    QList<QStandardItem *> rowAt(int row) const;
+
     // Filter for entries contained in the filter list. Returns the
     // number of deleted entries.
     unsigned filter(const QStringList &filter, int column);
diff --git a/src/plugins/vcsbase/vcsbasesubmiteditor.cpp b/src/plugins/vcsbase/vcsbasesubmiteditor.cpp
index d130c2664596505fe65e1ccb4ed37956fa4ecca7..25fbce7634c63e8a6f206df75ef113bd91448039 100644
--- a/src/plugins/vcsbase/vcsbasesubmiteditor.cpp
+++ b/src/plugins/vcsbase/vcsbasesubmiteditor.cpp
@@ -139,6 +139,17 @@ void VCSBaseSubmitEditor::setFileNameColumn(int c)
     m_d->m_widget->setFileNameColumn(c);
 }
 
+QAbstractItemView::SelectionMode VCSBaseSubmitEditor::fileListSelectionMode() const
+{
+    return m_d->m_widget->fileListSelectionMode();
+}
+
+void VCSBaseSubmitEditor::setFileListSelectionMode(QAbstractItemView::SelectionMode sm)
+{
+    m_d->m_widget->setFileListSelectionMode(sm);
+}
+
+
 void VCSBaseSubmitEditor::slotDescriptionChanged()
 {
 }
diff --git a/src/plugins/vcsbase/vcsbasesubmiteditor.h b/src/plugins/vcsbase/vcsbasesubmiteditor.h
index 91b10d488f99b0e8754a2699267cda3178c1abcc..d3e9166b35fd0be98a7b158755e43812e1fe692d 100644
--- a/src/plugins/vcsbase/vcsbasesubmiteditor.h
+++ b/src/plugins/vcsbase/vcsbasesubmiteditor.h
@@ -39,6 +39,7 @@
 #include <coreplugin/editormanager/ieditor.h>
 
 #include <QtCore/QList>
+#include <QtGui/QAbstractItemView>
 
 QT_BEGIN_NAMESPACE
 class QIcon;
@@ -92,6 +93,7 @@ class VCSBASE_EXPORT VCSBaseSubmitEditor : public Core::IEditor
 {
     Q_OBJECT
     Q_PROPERTY(int fileNameColumn READ fileNameColumn WRITE setFileNameColumn DESIGNABLE false)
+    Q_PROPERTY(QAbstractItemView::SelectionMode fileListSelectionMode READ fileListSelectionMode WRITE setFileListSelectionMode DESIGNABLE true)
 public:
     typedef QList<int> Context;
 
@@ -105,6 +107,9 @@ public:
     int fileNameColumn() const;
     void setFileNameColumn(int c);
 
+    QAbstractItemView::SelectionMode fileListSelectionMode() const;
+    void setFileListSelectionMode(QAbstractItemView::SelectionMode sm);
+
     // Core::IEditor
     virtual bool createNew(const QString &contents);
     virtual bool open(const QString &fileName);