diff --git a/src/plugins/diffeditor/diffeditor.cpp b/src/plugins/diffeditor/diffeditor.cpp
index 2d0405666fcebe1098358a1fd10bcc9229c8c629..d18e7bbfb28d9d1e1fa76d1171a1d97073835332 100644
--- a/src/plugins/diffeditor/diffeditor.cpp
+++ b/src/plugins/diffeditor/diffeditor.cpp
@@ -52,6 +52,7 @@
 #include <QComboBox>
 #include <QFileInfo>
 #include <QTextCodec>
+#include <QTextBlock>
 
 static const char settingsGroupC[] = "DiffEditor";
 static const char diffEditorTypeKeyC[] = "DiffEditorType";
@@ -74,6 +75,9 @@ public:
     DescriptionEditorWidget(QWidget *parent = 0);
     virtual QSize sizeHint() const;
 
+signals:
+    void expandBranchesRequested();
+
 public slots:
     void setDisplaySettings(const DisplaySettings &ds);
 
@@ -84,6 +88,15 @@ protected:
         editor->document()->setId("DiffEditor.DescriptionEditor");
         return editor;
     }
+    void mouseMoveEvent(QMouseEvent *e);
+    void mouseReleaseEvent(QMouseEvent *e);
+
+    bool findContentsUnderCursor(const QTextCursor &cursor);
+    void highlightCurrentContents();
+    void handleCurrentContents();
+
+private:
+    QTextCursor m_currentCursor;
 };
 
 DescriptionEditorWidget::DescriptionEditorWidget(QWidget *parent)
@@ -118,6 +131,67 @@ void DescriptionEditorWidget::setDisplaySettings(const DisplaySettings &ds)
     BaseTextEditorWidget::setDisplaySettings(settings);
 }
 
+void DescriptionEditorWidget::mouseMoveEvent(QMouseEvent *e)
+{
+    if (e->buttons()) {
+        TextEditor::BaseTextEditorWidget::mouseMoveEvent(e);
+        return;
+    }
+
+    Qt::CursorShape cursorShape;
+
+    const QTextCursor cursor = cursorForPosition(e->pos());
+    if (findContentsUnderCursor(cursor)) {
+        highlightCurrentContents();
+        cursorShape = Qt::PointingHandCursor;
+    } else {
+        setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>());
+        cursorShape = Qt::IBeamCursor;
+    }
+
+    TextEditor::BaseTextEditorWidget::mouseMoveEvent(e);
+    viewport()->setCursor(cursorShape);
+}
+
+void DescriptionEditorWidget::mouseReleaseEvent(QMouseEvent *e)
+{
+    if (e->button() == Qt::LeftButton && !(e->modifiers() & Qt::ShiftModifier)) {
+        const QTextCursor cursor = cursorForPosition(e->pos());
+        if (findContentsUnderCursor(cursor)) {
+            handleCurrentContents();
+            e->accept();
+            return;
+        }
+    }
+
+    TextEditor::BaseTextEditorWidget::mouseReleaseEvent(e);
+}
+
+bool DescriptionEditorWidget::findContentsUnderCursor(const QTextCursor &cursor)
+{
+    m_currentCursor = cursor;
+    return cursor.block().text() == QLatin1String(Constants::EXPAND_BRANCHES);
+}
+
+void DescriptionEditorWidget::highlightCurrentContents()
+{
+    QTextEdit::ExtraSelection sel;
+    sel.cursor = m_currentCursor;
+    sel.cursor.select(QTextCursor::LineUnderCursor);
+    sel.format.setFontUnderline(true);
+    setExtraSelections(BaseTextEditorWidget::OtherSelection,
+                       QList<QTextEdit::ExtraSelection>() << sel);
+
+}
+
+void DescriptionEditorWidget::handleCurrentContents()
+{
+    m_currentCursor.select(QTextCursor::LineUnderCursor);
+    m_currentCursor.removeSelectedText();
+    m_currentCursor.insertText(QLatin1String("Branches: Expanding..."));
+    emit expandBranchesRequested();
+}
+
 } // namespace Internal
 
 ///////////////////////////////// DiffEditor //////////////////////////////////
@@ -179,6 +253,8 @@ void DiffEditor::ctor()
 
     setWidget(splitter);
 
+    connect(m_descriptionWidget, SIGNAL(expandBranchesRequested()),
+            m_document->controller(), SLOT(expandBranchesRequested()));
     connect(TextEditorSettings::instance(),
             SIGNAL(displaySettingsChanged(TextEditor::DisplaySettings)),
             m_descriptionWidget,
diff --git a/src/plugins/diffeditor/diffeditorconstants.h b/src/plugins/diffeditor/diffeditorconstants.h
index a59336eb0665b50d62b1f77797a5a20973026e83..c988415abe0a32d37d1adcbd6f40bdd23226d0a1 100644
--- a/src/plugins/diffeditor/diffeditorconstants.h
+++ b/src/plugins/diffeditor/diffeditorconstants.h
@@ -44,6 +44,8 @@ const char ICON_SIDE_BY_SIDE_DIFF[]  = ":/diffeditor/images/sidebysidediff.png";
 const char ICON_UNIFIED_DIFF[]       = ":/diffeditor/images/unifieddiff.png";
 const char ICON_TOP_BAR[]            = ":/diffeditor/images/topbar.png";
 
+const char EXPAND_BRANCHES[] = "Branches: <Expand>";
+
 } // namespace Constants
 } // namespace DiffEditor
 
diff --git a/src/plugins/diffeditor/diffeditorcontroller.cpp b/src/plugins/diffeditor/diffeditorcontroller.cpp
index e826cf1e7df3f2372445f70fd7b10fef1c60254f..1d9d76448fa261763fd2d2a7e1fd9839eeb72cda 100644
--- a/src/plugins/diffeditor/diffeditorcontroller.cpp
+++ b/src/plugins/diffeditor/diffeditorcontroller.cpp
@@ -27,10 +27,13 @@
 **
 ****************************************************************************/
 
+#include "diffeditorconstants.h"
 #include "diffeditorcontroller.h"
 
 #include <coreplugin/icore.h>
 
+#include <QStringList>
+
 static const char settingsGroupC[] = "DiffEditor";
 static const char contextLineNumbersKeyC[] = "ContextLineNumbers";
 static const char ignoreWhitespaceKeyC[] = "IgnoreWhitespace";
@@ -148,7 +151,11 @@ void DiffEditorController::setDescription(const QString &description)
         return;
 
     m_description = description;
-    emit descriptionChanged(description);
+    // Empty line before headers and commit message
+    const int emptyLine = m_description.indexOf(QLatin1String("\n\n"));
+    if (emptyLine != -1)
+        m_description.insert(emptyLine, QLatin1Char('\n') + QLatin1String(Constants::EXPAND_BRANCHES));
+    emit descriptionChanged(m_description);
 }
 
 void DiffEditorController::setDescriptionEnabled(bool on)
@@ -160,6 +167,44 @@ void DiffEditorController::setDescriptionEnabled(bool on)
     emit descriptionEnablementChanged(on);
 }
 
+void DiffEditorController::branchesForCommitReceived(const QString &output)
+{
+    const QString branches = prepareBranchesForCommit(output);
+
+    m_description.replace(QLatin1String(Constants::EXPAND_BRANCHES), branches);
+    emit descriptionChanged(m_description);
+}
+
+void DiffEditorController::expandBranchesRequested()
+{
+    emit expandBranchesRequested(m_description.mid(7, 8));
+}
+
+QString DiffEditorController::prepareBranchesForCommit(const QString &output)
+{
+    QString moreBranches;
+    QString branches;
+    QStringList res;
+    foreach (const QString &branch, output.split(QLatin1Char('\n'))) {
+        const QString b = branch.mid(2).trimmed();
+        if (!b.isEmpty())
+            res << b;
+    }
+    const int branchCount = res.count();
+    // If there are more than 20 branches, list first 10 followed by a hint
+    if (branchCount > 20) {
+        const int leave = 10;
+        //: Displayed after the untranslated message "Branches: branch1, branch2 'and %n more'"
+        //  in git show.
+        moreBranches = QLatin1Char(' ') + tr("and %n more", 0, branchCount - leave);
+        res.erase(res.begin() + leave, res.end());
+    }
+    if (!res.isEmpty())
+        branches = (QLatin1String("Branches: ") + res.join(QLatin1String(", ")) + moreBranches);
+
+    return branches;
+}
+
 void DiffEditorController::setContextLinesNumber(int lines)
 {
     const int l = qMax(lines, 1);
diff --git a/src/plugins/diffeditor/diffeditorcontroller.h b/src/plugins/diffeditor/diffeditorcontroller.h
index 5bdfbd1cc4215565e10e9f294e3df00964362cad..82c150435ffad6fced3a1366acb253b6dce22475 100644
--- a/src/plugins/diffeditor/diffeditorcontroller.h
+++ b/src/plugins/diffeditor/diffeditorcontroller.h
@@ -68,6 +68,8 @@ public slots:
     void requestChunkActions(QMenu *menu,
                              int diffFileIndex,
                              int chunkIndex);
+    void branchesForCommitReceived(const QString &output);
+    void expandBranchesRequested();
 
 signals:
     void cleared(const QString &message);
@@ -81,9 +83,10 @@ signals:
     void chunkActionsRequested(QMenu *menu,
                                int diffFileIndex,
                                int chunkIndex);
-
+    void expandBranchesRequested(const QString &revision);
 
 private:
+    QString prepareBranchesForCommit(const QString &output);
     QString m_clearMessage;
 
     QList<FileData> m_diffFiles;
diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp
index 1e47d1aa63c33a0509447cce814a8fe41cbb0b82..7bec91dce36f6fa494760d19775dcf977f4322cd 100644
--- a/src/plugins/git/gitclient.cpp
+++ b/src/plugins/git/gitclient.cpp
@@ -1139,6 +1139,10 @@ void GitClient::show(const QString &source, const QString &id, const QString &na
             DiffEditor::DiffEditorManager::find(documentId);
     if (!diffEditorDocument) {
         diffEditorDocument = createDiffEditor(documentId, source, title);
+
+        connect(diffEditorDocument->controller(), SIGNAL(expandBranchesRequested(QString)),
+                this, SLOT(branchesForCommit(QString)));
+
         diffEditorDocument->controller()->setDescriptionEnabled(true);
 
         GitDiffEditorReloader *reloader =
@@ -1738,23 +1742,25 @@ void GitClient::synchronousTagsForCommit(const QString &workingDirectory, const
     }
 }
 
-QStringList GitClient::synchronousBranchesForCommit(const QString &workingDirectory, const QString &revision)
+void GitClient::branchesForCommit(const QString &revision)
 {
-    QByteArray outputData;
-    QString output;
     QStringList arguments;
     arguments << QLatin1String("branch") << QLatin1String(noColorOption)
               << QLatin1String("-a") << QLatin1String("--contains") << revision;
-    fullySynchronousGit(workingDirectory, arguments, &outputData, 0,
-                        VcsBasePlugin::SuppressCommandLogging);
-    output = commandOutputFromLocal8Bit(outputData);
-    QStringList res;
-    foreach (const QString &branch, output.split(QLatin1Char('\n'))) {
-        const QString b = branch.mid(2).trimmed();
-        if (!b.isEmpty())
-            res << b;
-    }
-    return res;
+
+    DiffEditor::DiffEditorController *editorController
+            = qobject_cast<DiffEditor::DiffEditorController *>(sender());
+    QString workingDirectory = editorController->workingDirectory();
+    VcsBase::Command *command = new VcsBase::Command(gitBinaryPath(), workingDirectory,
+                                                     processEnvironment());
+    command->setCodec(getSourceCodec(currentDocumentPath()));
+
+    connect(command, SIGNAL(output(QString)), editorController,
+            SLOT(branchesForCommitReceived(QString)));
+
+    command->addJob(arguments, -1);
+    command->execute();
+    command->setCookie(workingDirectory);
 }
 
 bool GitClient::isRemoteCommit(const QString &workingDirectory, const QString &commit)
diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h
index 5602d175e56087def18dda5f784cdb27221c9891..1b20d75e2a71c71b50f834c04364ecf23e843b9b 100644
--- a/src/plugins/git/gitclient.h
+++ b/src/plugins/git/gitclient.h
@@ -241,8 +241,6 @@ public:
     QString synchronousTopRevision(const QString &workingDirectory, QString *errorMessage = 0);
     void synchronousTagsForCommit(const QString &workingDirectory, const QString &revision,
                                   QString &precedes, QString &follows);
-    QStringList synchronousBranchesForCommit(const QString &workingDirectory,
-                                             const QString &revision);
     bool isRemoteCommit(const QString &workingDirectory, const QString &commit);
     bool isFastForwardMerge(const QString &workingDirectory, const QString &branch);
 
@@ -349,6 +347,7 @@ private slots:
     void slotChunkActionsRequested(QMenu *menu, int diffFileIndex, int chunkIndex);
     void slotStageChunk();
     void slotUnstageChunk();
+    void branchesForCommit(const QString &revision);
 
 private:
     QString makePatch(int diffFileIndex, int chunkIndex, bool revert) const;