Skip to content
Snippets Groups Projects
Commit 2c211007 authored by Orgad Shaneh's avatar Orgad Shaneh Committed by Orgad Shaneh
Browse files

Git: Disambiguate branch/tag names


Task-number: QTCREATORBUG-9700
Change-Id: I48e779fba65afc71ba13b426e526c3cb82070142
Reviewed-by: default avatarTobias Hunger <tobias.hunger@digia.com>
parent bcd5ce77
No related merge requests found
...@@ -287,7 +287,7 @@ void BranchDialog::rename() ...@@ -287,7 +287,7 @@ void BranchDialog::rename()
void BranchDialog::diff() void BranchDialog::diff()
{ {
QString fullName = m_model->fullName(selectedIndex()); QString fullName = m_model->fullName(selectedIndex(), true);
if (fullName.isEmpty()) if (fullName.isEmpty())
return; return;
// Do not pass working dir by reference since it might change // Do not pass working dir by reference since it might change
...@@ -296,7 +296,7 @@ void BranchDialog::diff() ...@@ -296,7 +296,7 @@ void BranchDialog::diff()
void BranchDialog::log() void BranchDialog::log()
{ {
QString branchName = m_model->fullName(selectedIndex()); QString branchName = m_model->fullName(selectedIndex(), true);
if (branchName.isEmpty()) if (branchName.isEmpty())
return; return;
// Do not pass working dir by reference since it might change // Do not pass working dir by reference since it might change
...@@ -309,7 +309,7 @@ void BranchDialog::merge() ...@@ -309,7 +309,7 @@ void BranchDialog::merge()
QTC_CHECK(m_model->isLocal(m_model->currentBranch())); // otherwise the button would not be enabled! QTC_CHECK(m_model->isLocal(m_model->currentBranch())); // otherwise the button would not be enabled!
QTC_CHECK(idx != m_model->currentBranch()); // otherwise the button would not be enabled! QTC_CHECK(idx != m_model->currentBranch()); // otherwise the button would not be enabled!
const QString branch = m_model->fullName(idx); const QString branch = m_model->fullName(idx, true);
GitClient *client = GitPlugin::instance()->gitClient(); GitClient *client = GitPlugin::instance()->gitClient();
if (client->beginStashScope(m_repository, QLatin1String("merge"), AllowUnstashed)) if (client->beginStashScope(m_repository, QLatin1String("merge"), AllowUnstashed))
client->synchronousMerge(m_repository, branch); client->synchronousMerge(m_repository, branch);
...@@ -321,7 +321,7 @@ void BranchDialog::rebase() ...@@ -321,7 +321,7 @@ void BranchDialog::rebase()
QTC_CHECK(m_model->isLocal(m_model->currentBranch())); // otherwise the button would not be enabled! QTC_CHECK(m_model->isLocal(m_model->currentBranch())); // otherwise the button would not be enabled!
QTC_CHECK(idx != m_model->currentBranch()); // otherwise the button would not be enabled! QTC_CHECK(idx != m_model->currentBranch()); // otherwise the button would not be enabled!
const QString baseBranch = m_model->fullName(idx); const QString baseBranch = m_model->fullName(idx, true);
GitClient *client = GitPlugin::instance()->gitClient(); GitClient *client = GitPlugin::instance()->gitClient();
if (client->beginStashScope(m_repository, QLatin1String("rebase"))) if (client->beginStashScope(m_repository, QLatin1String("rebase")))
client->rebase(m_repository, baseBranch); client->rebase(m_repository, baseBranch);
......
...@@ -38,6 +38,12 @@ ...@@ -38,6 +38,12 @@
namespace Git { namespace Git {
namespace Internal { namespace Internal {
enum RootNodes {
LocalBranches = 0,
RemoteBranches = 1,
Tags = 2
};
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// BranchNode: // BranchNode:
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
...@@ -77,18 +83,6 @@ public: ...@@ -77,18 +83,6 @@ public:
return children.isEmpty(); return children.isEmpty();
} }
bool isTag() const
{
if (!parent)
return false;
for (const BranchNode *p = this; p->parent; p = p->parent) {
// find root child with name "tags"
if (!p->parent->parent && p->name == QLatin1String("tags"))
return true;
}
return false;
}
bool childOf(BranchNode *node) const bool childOf(BranchNode *node) const
{ {
if (this == node) if (this == node)
...@@ -96,12 +90,22 @@ public: ...@@ -96,12 +90,22 @@ public:
return parent ? parent->childOf(node) : false; return parent ? parent->childOf(node) : false;
} }
bool isLocal() const bool childOfRoot(RootNodes root) const
{ {
BranchNode *rn = rootNode(); BranchNode *rn = rootNode();
if (rn->isLeaf()) if (rn->isLeaf())
return false; return false;
return childOf(rn->children.at(0)); return childOf(rn->children.at(root));
}
bool isTag() const
{
return childOfRoot(Tags);
}
bool isLocal() const
{
return childOfRoot(LocalBranches);
} }
BranchNode *childOfName(const QString &name) const BranchNode *childOfName(const QString &name) const
...@@ -113,7 +117,7 @@ public: ...@@ -113,7 +117,7 @@ public:
return 0; return 0;
} }
QStringList fullName() const QStringList fullName(bool includePrefix = false) const
{ {
QTC_ASSERT(isLeaf(), return QStringList()); QTC_ASSERT(isLeaf(), return QStringList());
...@@ -125,8 +129,9 @@ public: ...@@ -125,8 +129,9 @@ public:
current = current->parent; current = current->parent;
} }
if (current->children.at(0) == nodes.at(0)) if (includePrefix)
nodes.removeFirst(); // remove local branch designation fn.append(nodes.first()->sha);
nodes.removeFirst();
foreach (const BranchNode *n, nodes) foreach (const BranchNode *n, nodes)
fn.append(n->name); fn.append(n->name);
...@@ -191,7 +196,12 @@ BranchModel::BranchModel(GitClient *client, QObject *parent) : ...@@ -191,7 +196,12 @@ BranchModel::BranchModel(GitClient *client, QObject *parent) :
m_currentBranch(0) m_currentBranch(0)
{ {
QTC_CHECK(m_client); QTC_CHECK(m_client);
m_rootNode->append(new BranchNode(tr("Local Branches")));
// Abuse the sha field for ref prefix
m_rootNode->append(new BranchNode(tr("Local Branches"), QLatin1String("refs/heads")));
m_rootNode->append(new BranchNode(tr("Remote Branches"), QLatin1String("refs/remotes")));
if (m_client->settings()->boolValue(GitSettings::showTagsKey))
m_rootNode->append(new BranchNode(tr("Tags"), QLatin1String("refs/tags")));
} }
BranchModel::~BranchModel() BranchModel::~BranchModel()
...@@ -320,11 +330,9 @@ Qt::ItemFlags BranchModel::flags(const QModelIndex &index) const ...@@ -320,11 +330,9 @@ Qt::ItemFlags BranchModel::flags(const QModelIndex &index) const
void BranchModel::clear() void BranchModel::clear()
{ {
while (m_rootNode->count() > 1) foreach (BranchNode *root, m_rootNode->children)
delete m_rootNode->children.takeLast(); while (root->count())
BranchNode *locals = m_rootNode->children.at(0); delete root->children.takeLast();
while (locals->count())
delete locals->children.takeLast();
m_currentBranch = 0; m_currentBranch = 0;
} }
...@@ -419,22 +427,20 @@ QModelIndex BranchModel::currentBranch() const ...@@ -419,22 +427,20 @@ QModelIndex BranchModel::currentBranch() const
return nodeToIndex(m_currentBranch); return nodeToIndex(m_currentBranch);
} }
QString BranchModel::fullName(const QModelIndex &idx) const QString BranchModel::fullName(const QModelIndex &idx, bool includePrefix) const
{ {
if (!idx.isValid()) if (!idx.isValid())
return QString(); return QString();
BranchNode *node = indexToNode(idx); BranchNode *node = indexToNode(idx);
if (!node || !node->isLeaf()) if (!node || !node->isLeaf())
return QString(); return QString();
QStringList path = node->fullName(); QStringList path = node->fullName(includePrefix);
if (node->isTag())
path.removeFirst();
return path.join(QString(QLatin1Char('/'))); return path.join(QString(QLatin1Char('/')));
} }
QStringList BranchModel::localBranchNames() const QStringList BranchModel::localBranchNames() const
{ {
if (!m_rootNode || m_rootNode->children.isEmpty()) if (!m_rootNode || !m_rootNode->count())
return QStringList(); return QStringList();
return m_rootNode->children.at(0)->childrenNames(); return m_rootNode->children.at(0)->childrenNames();
...@@ -509,7 +515,7 @@ void BranchModel::removeTag(const QModelIndex &idx) ...@@ -509,7 +515,7 @@ void BranchModel::removeTag(const QModelIndex &idx)
void BranchModel::checkoutBranch(const QModelIndex &idx) void BranchModel::checkoutBranch(const QModelIndex &idx)
{ {
QString branch = fullName(idx); QString branch = fullName(idx, !isLocal(idx));
if (branch.isEmpty()) if (branch.isEmpty())
return; return;
...@@ -574,14 +580,15 @@ QModelIndex BranchModel::addBranch(const QString &name, bool track, const QModel ...@@ -574,14 +580,15 @@ QModelIndex BranchModel::addBranch(const QString &name, bool track, const QModel
return QModelIndex(); return QModelIndex();
const QString trackedBranch = fullName(startPoint); const QString trackedBranch = fullName(startPoint);
const QString fullTrackedBranch = fullName(startPoint, true);
QString output; QString output;
QString errorMessage; QString errorMessage;
QStringList args; QStringList args;
args << (track ? QLatin1String("--track") : QLatin1String("--no-track")); args << (track ? QLatin1String("--track") : QLatin1String("--no-track"));
args << name; args << name;
if (!trackedBranch.isEmpty()) if (!fullTrackedBranch.isEmpty())
args << trackedBranch; args << fullTrackedBranch;
if (!m_client->synchronousBranchCmd(m_workingDirectory, args, &output, &errorMessage)) { if (!m_client->synchronousBranchCmd(m_workingDirectory, args, &output, &errorMessage)) {
VcsBase::VcsBaseOutputWindow::instance()->appendError(errorMessage); VcsBase::VcsBaseOutputWindow::instance()->appendError(errorMessage);
...@@ -632,15 +639,18 @@ void BranchModel::parseOutputLine(const QString &line) ...@@ -632,15 +639,18 @@ void BranchModel::parseOutputLine(const QString &line)
QStringList nameParts = fullName.split(QLatin1Char('/')); QStringList nameParts = fullName.split(QLatin1Char('/'));
nameParts.removeFirst(); // remove refs... nameParts.removeFirst(); // remove refs...
BranchNode *root = 0;
if (nameParts.first() == QLatin1String("heads")) if (nameParts.first() == QLatin1String("heads"))
nameParts[0] = m_rootNode->children.at(0)->name; // Insert the local designator root = m_rootNode->children.at(0); // Insert the local designator
else if (nameParts.first() == QLatin1String("remotes")) else if (nameParts.first() == QLatin1String("remotes"))
nameParts.removeFirst(); // remove "remotes" root = m_rootNode->children.at(1);
else if (nameParts.first() == QLatin1String("stash")) else if (showTags && nameParts.first() == QLatin1String("tags"))
return; root = m_rootNode->children.at(2);
else if (!showTags && (nameParts.first() == QLatin1String("tags"))) else
return; return;
nameParts.removeFirst();
// limit depth of list. Git basically only ever wants one / and considers the rest as part of // limit depth of list. Git basically only ever wants one / and considers the rest as part of
// the name. // the name.
while (nameParts.count() > 3) { while (nameParts.count() > 3) {
...@@ -652,7 +662,7 @@ void BranchModel::parseOutputLine(const QString &line) ...@@ -652,7 +662,7 @@ void BranchModel::parseOutputLine(const QString &line)
nameParts.removeLast(); nameParts.removeLast();
BranchNode *newNode = new BranchNode(name, sha, lineParts.at(2)); BranchNode *newNode = new BranchNode(name, sha, lineParts.at(2));
m_rootNode->insert(nameParts, newNode); root->insert(nameParts, newNode);
if (current) if (current)
m_currentBranch = newNode; m_currentBranch = newNode;
} }
......
...@@ -70,7 +70,7 @@ public: ...@@ -70,7 +70,7 @@ public:
GitClient *client() const; GitClient *client() const;
QModelIndex currentBranch() const; QModelIndex currentBranch() const;
QString fullName(const QModelIndex &idx) const; QString fullName(const QModelIndex &idx, bool includePrefix = false) const;
QStringList localBranchNames() const; QStringList localBranchNames() const;
QString sha(const QModelIndex &idx) const; QString sha(const QModelIndex &idx) const;
bool isLocal(const QModelIndex &idx) const; bool isLocal(const QModelIndex &idx) const;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment