diff --git a/src/plugins/git/branchmodel.cpp b/src/plugins/git/branchmodel.cpp
index 4cb59ae8af7c5412908696dda0bea2b21371d579..c3321c533a00c534aaaabaadbefd616842332d5f 100644
--- a/src/plugins/git/branchmodel.cpp
+++ b/src/plugins/git/branchmodel.cpp
@@ -132,6 +132,15 @@ public:
             else
                 current = current->append(new BranchNode(path.at(i)));
         }
+        if (n->name.endsWith(QLatin1String("^{}"))) {
+            n->name.chop(3);
+            if (!current->children.isEmpty()) {
+                BranchNode* lastOne = current->children.last();
+                current->children.removeLast();
+                if (lastOne)
+                    delete lastOne;
+            }
+        }
         current->append(n);
     }
 
@@ -316,11 +325,10 @@ bool BranchModel::refresh(const QString &workingDirectory, QString *errorMessage
     if (workingDirectory.isEmpty())
         return false;
 
-    QStringList branchArgs;
-    branchArgs << QLatin1String(GitClient::noColorOption)
-               << QLatin1String("-v") << QLatin1String("-a");
+    QStringList args;
+    args << QLatin1String("--head") << QLatin1String("--dereference");
     QString output;
-    if (!m_client->synchronousBranchCmd(workingDirectory, branchArgs, &output, errorMessage))
+    if (!m_client->synchronousShowRefCmd(workingDirectory, args, &output, errorMessage))
         VcsBase::VcsBaseOutputWindow::instance()->appendError(*errorMessage);
 
     beginResetModel();
@@ -331,11 +339,32 @@ bool BranchModel::refresh(const QString &workingDirectory, QString *errorMessage
     foreach (const QString &l, lines)
         parseOutputLine(l);
 
+    if (m_currentBranch) {
+        if (m_currentBranch->parent == m_rootNode->children[0])
+            m_currentBranch = 0;
+        setCurrentBranch();
+    }
+
     endResetModel();
 
     return true;
 }
 
+void BranchModel::setCurrentBranch()
+{
+    QString currentBranch = m_client->synchronousCurrentLocalBranch(m_workingDirectory);
+    if (currentBranch.isEmpty())
+        return;
+
+    BranchNode *local = m_rootNode->children.at(0);
+    int pos = 0;
+    for (pos = 0; pos < local->count(); ++pos) {
+        if (local->children.at(pos)->name == currentBranch) {
+            m_currentBranch = local->children[pos];
+        }
+    }
+}
+
 void BranchModel::renameBranch(const QString &oldName, const QString &newName)
 {
     QString errorMessage;
@@ -538,33 +567,40 @@ void BranchModel::parseOutputLine(const QString &line)
     if (line.size() < 3)
         return;
 
-    bool current = line.startsWith(QLatin1String("* "));
+    const int shaLength = 40;
+    const QString sha = line.left(shaLength);
+    const QString fullName = line.mid(shaLength + 1);
 
-    const QString branchInfo = line.mid(2);
-    if (current && branchInfo.startsWith(QLatin1String("(no branch)")))
-        return;
-
-    QStringList tokens = branchInfo.split(QLatin1Char(' '), QString::SkipEmptyParts);
-    if (tokens.size() < 2)
+    static QString currentSha;
+    if (fullName == QLatin1String("HEAD")) {
+        currentSha = sha;
         return;
+    }
 
-    QString sha = tokens.at(1);
+    bool current = (sha == currentSha);
+    bool showTags = m_client->settings()->boolValue(GitSettings::showTagsKey);
 
     // insert node into tree:
-    QStringList nameParts = tokens.at(0).split(QLatin1Char('/'));
-    if (nameParts.count() < 1)
-        return;
+    QStringList nameParts = fullName.split(QLatin1Char('/'));
+    nameParts.removeFirst(); // remove refs...
 
-    if (nameParts.isEmpty() || nameParts.at(0) != QLatin1String("remotes"))
-        nameParts.prepend(m_rootNode->children.at(0)->name); // Insert the local designator
-    else
+    if (nameParts.first() == QLatin1String("heads"))
+        nameParts[0] = m_rootNode->children.at(0)->name; // Insert the local designator
+    else if (nameParts.first() == QLatin1String("remotes"))
         nameParts.removeFirst(); // remove "remotes"
+    else if (nameParts.first() == QLatin1String("stash"))
+        return;
+    else if (!showTags && (nameParts.first() == QLatin1String("tags")))
+        return;
+
+    // limit depth of list. Git basically only ever wants one / and considers the rest as part of
+    // the name.
     while (nameParts.count() > 3) {
         nameParts[2] = nameParts.at(2) + QLatin1Char('/') + nameParts.at(3);
         nameParts.removeAt(3);
     }
 
-    QString name = nameParts.last();
+    const QString name = nameParts.last();
     nameParts.removeLast();
 
     BranchNode *newNode = new BranchNode(name, sha);
diff --git a/src/plugins/git/branchmodel.h b/src/plugins/git/branchmodel.h
index 2383478a7805ce70eeaff9167390962f842e704a..5eda99d9d3603e529a4bb509e17e7f024808a09b 100644
--- a/src/plugins/git/branchmodel.h
+++ b/src/plugins/git/branchmodel.h
@@ -82,6 +82,7 @@ public:
 
 private:
     void parseOutputLine(const QString &line);
+    void setCurrentBranch();
     BranchNode *indexToNode(const QModelIndex &index) const;
     QModelIndex nodeToIndex(BranchNode *node) const;
 
diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp
index 2db128d416830a092edee9d3e8428348568f3a58..a6c211e48a3b5529d922eacd94ff89ff512cef68 100644
--- a/src/plugins/git/gitclient.cpp
+++ b/src/plugins/git/gitclient.cpp
@@ -1506,6 +1506,23 @@ bool GitClient::synchronousBranchCmd(const QString &workingDirectory, QStringLis
     return true;
 }
 
+bool GitClient::synchronousShowRefCmd(const QString &workingDirectory, QStringList args,
+                                      QString *output, QString *errorMessage)
+{
+    args.push_front(QLatin1String("show-ref"));
+    QByteArray outputText;
+    QByteArray errorText;
+    const bool rc = fullySynchronousGit(workingDirectory, args, &outputText, &errorText);
+    *output = commandOutputFromLocal8Bit(outputText);
+    if (!rc) {
+        *errorMessage = tr("Cannot run \"git show-ref\" in \"%1\": %2")
+                .arg(QDir::toNativeSeparators(workingDirectory), commandOutputFromLocal8Bit(errorText));
+
+        return false;
+    }
+    return true;
+}
+
 bool GitClient::synchronousRemoteCmd(const QString &workingDirectory, QStringList remoteArgs,
                                      QString *output, QString *errorMessage)
 {
diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h
index cd0df0a60c256efca1838d005551880d13065249..4e4f8dffe2a41bf0bf7874bd2d97971bb168a898 100644
--- a/src/plugins/git/gitclient.h
+++ b/src/plugins/git/gitclient.h
@@ -180,6 +180,8 @@ public:
                                 QString *errorMessage = 0);
     bool synchronousBranchCmd(const QString &workingDirectory, QStringList branchArgs,
                               QString *output, QString *errorMessage);
+    bool synchronousShowRefCmd(const QString &workingDirectory, QStringList args,
+                               QString *output, QString *errorMessage);
     bool synchronousRemoteCmd(const QString &workingDirectory, QStringList remoteArgs,
                               QString *output, QString *errorMessage);
 
diff --git a/src/plugins/git/gitsettings.cpp b/src/plugins/git/gitsettings.cpp
index d177bd707448fcf456e7dbade8d349056f49f40e..5b908c47600c9e4f427a4030cff7819705abf8b8 100644
--- a/src/plugins/git/gitsettings.cpp
+++ b/src/plugins/git/gitsettings.cpp
@@ -36,6 +36,7 @@ namespace Git {
 namespace Internal {
 
 const QLatin1String GitSettings::pullRebaseKey("PullRebase");
+const QLatin1String GitSettings::showTagsKey("ShowTags");
 const QLatin1String GitSettings::omitAnnotationDateKey("OmitAnnotationDate");
 const QLatin1String GitSettings::ignoreSpaceChangesInDiffKey("SpaceIgnorantDiff");
 const QLatin1String GitSettings::ignoreSpaceChangesInBlameKey("SpaceIgnorantBlame");
@@ -53,6 +54,7 @@ GitSettings::GitSettings()
     declareKey(binaryPathKey, QLatin1String("git"));
     declareKey(timeoutKey, Utils::HostOsInfo::isWindowsHost() ? 60 : 30);
     declareKey(pullRebaseKey, false);
+    declareKey(showTagsKey, false);
     declareKey(omitAnnotationDateKey, false);
     declareKey(ignoreSpaceChangesInDiffKey, true);
     declareKey(ignoreSpaceChangesInBlameKey, true);
diff --git a/src/plugins/git/gitsettings.h b/src/plugins/git/gitsettings.h
index 99f74cb200ae3ebaeee51ae479e822bc301a7a53..4858a284e13ce9ddac560466a1415ab3eab86b10 100644
--- a/src/plugins/git/gitsettings.h
+++ b/src/plugins/git/gitsettings.h
@@ -42,6 +42,7 @@ public:
     GitSettings();
 
     static const QLatin1String pullRebaseKey;
+    static const QLatin1String showTagsKey;
     static const QLatin1String omitAnnotationDateKey;
     static const QLatin1String ignoreSpaceChangesInDiffKey;
     static const QLatin1String ignoreSpaceChangesInBlameKey;
diff --git a/src/plugins/git/settingspage.cpp b/src/plugins/git/settingspage.cpp
index d2bf45d9ce75cbdd5effa9f6a8711eea7e793654..a76d07bc2ccdfd71f8f8b54d5815783aea38d93b 100644
--- a/src/plugins/git/settingspage.cpp
+++ b/src/plugins/git/settingspage.cpp
@@ -71,6 +71,7 @@ GitSettings SettingsPageWidget::settings() const
     rc.setValue(GitSettings::logCountKey, m_ui.logCountSpinBox->value());
     rc.setValue(GitSettings::timeoutKey, m_ui.timeoutSpinBox->value());
     rc.setValue(GitSettings::pullRebaseKey, m_ui.pullRebaseCheckBox->isChecked());
+    rc.setValue(GitSettings::showTagsKey, m_ui.showTagsCheckBox->isChecked());
     rc.setValue(GitSettings::promptOnSubmitKey, m_ui.promptToSubmitCheckBox->isChecked());
     rc.setValue(GitSettings::winSetHomeEnvironmentKey, m_ui.winHomeCheckBox->isChecked());
     rc.setValue(GitSettings::gitkOptionsKey, m_ui.gitkOptionsLineEdit->text().trimmed());
@@ -84,6 +85,7 @@ void SettingsPageWidget::setSettings(const GitSettings &s)
     m_ui.logCountSpinBox->setValue(s.intValue(GitSettings::logCountKey));
     m_ui.timeoutSpinBox->setValue(s.intValue(GitSettings::timeoutKey));
     m_ui.pullRebaseCheckBox->setChecked(s.boolValue(GitSettings::pullRebaseKey));
+    m_ui.showTagsCheckBox->setChecked(s.boolValue(GitSettings::showTagsKey));
     m_ui.promptToSubmitCheckBox->setChecked(s.boolValue(GitSettings::promptOnSubmitKey));
     m_ui.winHomeCheckBox->setChecked(s.boolValue(GitSettings::winSetHomeEnvironmentKey));
     m_ui.gitkOptionsLineEdit->setText(s.stringValue(GitSettings::gitkOptionsKey));
diff --git a/src/plugins/git/settingspage.ui b/src/plugins/git/settingspage.ui
index cdd3444e1dbee983b8dca9bf91e1e48bd3f3cf36..d67a59369ea2cb082f82eaef8b3aeb5935cbe855 100644
--- a/src/plugins/git/settingspage.ui
+++ b/src/plugins/git/settingspage.ui
@@ -130,6 +130,13 @@
         </property>
        </widget>
       </item>
+      <item row="1" column="3" colspan="2">
+       <widget class="QCheckBox" name="showTagsCheckBox">
+        <property name="text">
+         <string>Show Tags in Branches Dialog</string>
+        </property>
+       </widget>
+      </item>
      </layout>
     </widget>
    </item>