From e9443ff51ff7b2882f594cc09bf5a8e2a9879aca Mon Sep 17 00:00:00 2001
From: Orgad Shaneh <orgad.shaneh@audiocodes.com>
Date: Thu, 13 Jun 2013 23:17:37 +0300
Subject: [PATCH] Git: Show tracking branch on Branches dialog

Simplify branch model parsing a bit

Change-Id: Id9e41c6c2769397d6eee3ab74de4afbb94111e25
Reviewed-by: Tobias Hunger <tobias.hunger@digia.com>
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
Reviewed-by: Petar Perisin <petar.perisin@gmail.com>
---
 src/plugins/git/branchmodel.cpp | 43 ++++++++++++++-------------------
 src/plugins/git/branchmodel.h   |  1 +
 src/plugins/git/gitclient.cpp   |  7 +++---
 src/plugins/git/gitclient.h     |  2 +-
 4 files changed, 24 insertions(+), 29 deletions(-)

diff --git a/src/plugins/git/branchmodel.cpp b/src/plugins/git/branchmodel.cpp
index 034c93e72ad..324ba174344 100644
--- a/src/plugins/git/branchmodel.cpp
+++ b/src/plugins/git/branchmodel.cpp
@@ -50,8 +50,8 @@ public:
         name(QLatin1String("<ROOT>"))
     { }
 
-    BranchNode(const QString &n, const QString &s = QString()) :
-        parent(0), name(n), sha(s)
+    BranchNode(const QString &n, const QString &s = QString(), const QString &t = QString()) :
+        parent(0), name(n), sha(s), tracking(t)
     { }
 
     ~BranchNode()
@@ -132,15 +132,6 @@ 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);
     }
 
@@ -173,6 +164,7 @@ public:
 
     QString name;
     QString sha;
+    QString tracking;
     mutable QString toolTip;
 };
 
@@ -238,7 +230,12 @@ QVariant BranchModel::data(const QModelIndex &index, int role) const
         return QVariant();
 
     switch (role) {
-    case Qt::DisplayRole:
+    case Qt::DisplayRole: {
+        QString res = node->name;
+        if (!node->tracking.isEmpty())
+            res += QLatin1String(" [") + node->tracking + QLatin1Char(']');
+        return res;
+    }
     case Qt::EditRole:
         return node->name;
     case Qt::ToolTipRole:
@@ -325,10 +322,11 @@ bool BranchModel::refresh(const QString &workingDirectory, QString *errorMessage
     if (workingDirectory.isEmpty())
         return false;
 
+    m_currentSha = m_client->synchronousTopRevision(workingDirectory);
     QStringList args;
-    args << QLatin1String("--head") << QLatin1String("--dereference");
+    args << QLatin1String("--format=%(objectname)\t%(refname)\t%(upstream:short)\t%(*objectname)");
     QString output;
-    if (!m_client->synchronousShowRefCmd(workingDirectory, args, &output, errorMessage))
+    if (!m_client->synchronousForEachRefCmd(workingDirectory, args, &output, errorMessage))
         VcsBase::VcsBaseOutputWindow::instance()->appendError(*errorMessage);
 
     beginResetModel();
@@ -565,17 +563,12 @@ void BranchModel::parseOutputLine(const QString &line)
     if (line.size() < 3)
         return;
 
-    const int shaLength = 40;
-    const QString sha = line.left(shaLength);
-    const QString fullName = line.mid(shaLength + 1);
-
-    static QString currentSha;
-    if (fullName == QLatin1String("HEAD")) {
-        currentSha = sha;
-        return;
-    }
+    QStringList lineParts = line.split(QLatin1Char('\t'));
+    const QString shaDeref = lineParts.at(3);
+    const QString sha = shaDeref.isEmpty() ? lineParts.at(0) : shaDeref;
+    const QString fullName = lineParts.at(1);
 
-    bool current = (sha == currentSha);
+    bool current = (sha == m_currentSha);
     bool showTags = m_client->settings()->boolValue(GitSettings::showTagsKey);
 
     // insert node into tree:
@@ -601,7 +594,7 @@ void BranchModel::parseOutputLine(const QString &line)
     const QString name = nameParts.last();
     nameParts.removeLast();
 
-    BranchNode *newNode = new BranchNode(name, sha);
+    BranchNode *newNode = new BranchNode(name, sha, lineParts.at(2));
     m_rootNode->insert(nameParts, newNode);
     if (current)
         m_currentBranch = newNode;
diff --git a/src/plugins/git/branchmodel.h b/src/plugins/git/branchmodel.h
index 5eda99d9d36..c386e258f36 100644
--- a/src/plugins/git/branchmodel.h
+++ b/src/plugins/git/branchmodel.h
@@ -92,6 +92,7 @@ private:
     QString m_workingDirectory;
     BranchNode *m_rootNode;
     BranchNode *m_currentBranch;
+    QString m_currentSha;
 };
 
 } // namespace Internal
diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp
index b6c8fe36e64..af34f190fd3 100644
--- a/src/plugins/git/gitclient.cpp
+++ b/src/plugins/git/gitclient.cpp
@@ -1883,16 +1883,17 @@ bool GitClient::synchronousBranchCmd(const QString &workingDirectory, QStringLis
     return true;
 }
 
-bool GitClient::synchronousShowRefCmd(const QString &workingDirectory, QStringList args,
+bool GitClient::synchronousForEachRefCmd(const QString &workingDirectory, QStringList args,
                                       QString *output, QString *errorMessage)
 {
-    args.push_front(QLatin1String("show-ref"));
+    args.push_front(QLatin1String("for-each-ref"));
     QByteArray outputText;
     QByteArray errorText;
     const bool rc = fullySynchronousGit(workingDirectory, args, &outputText, &errorText);
     *output = commandOutputFromLocal8Bit(outputText);
     if (!rc) {
-        *errorMessage = msgCannotRun(QLatin1String("git show-ref"),  workingDirectory, commandOutputFromLocal8Bit(errorText));
+        *errorMessage = msgCannotRun(QLatin1String("git for-each-ref"), workingDirectory,
+                                     commandOutputFromLocal8Bit(errorText));
 
         return false;
     }
diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h
index 3c8cc28a2f9..7eb42ebb179 100644
--- a/src/plugins/git/gitclient.h
+++ b/src/plugins/git/gitclient.h
@@ -201,7 +201,7 @@ public:
                                 QString *errorMessage = 0);
     bool synchronousBranchCmd(const QString &workingDirectory, QStringList branchArgs,
                               QString *output, QString *errorMessage);
-    bool synchronousShowRefCmd(const QString &workingDirectory, QStringList args,
+    bool synchronousForEachRefCmd(const QString &workingDirectory, QStringList args,
                                QString *output, QString *errorMessage);
     bool synchronousRemoteCmd(const QString &workingDirectory, QStringList remoteArgs,
                               QString *output, QString *errorMessage);
-- 
GitLab