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 branches found
No related tags found
No related merge requests found
......@@ -287,7 +287,7 @@ void BranchDialog::rename()
void BranchDialog::diff()
{
QString fullName = m_model->fullName(selectedIndex());
QString fullName = m_model->fullName(selectedIndex(), true);
if (fullName.isEmpty())
return;
// Do not pass working dir by reference since it might change
......@@ -296,7 +296,7 @@ void BranchDialog::diff()
void BranchDialog::log()
{
QString branchName = m_model->fullName(selectedIndex());
QString branchName = m_model->fullName(selectedIndex(), true);
if (branchName.isEmpty())
return;
// Do not pass working dir by reference since it might change
......@@ -309,7 +309,7 @@ void BranchDialog::merge()
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!
const QString branch = m_model->fullName(idx);
const QString branch = m_model->fullName(idx, true);
GitClient *client = GitPlugin::instance()->gitClient();
if (client->beginStashScope(m_repository, QLatin1String("merge"), AllowUnstashed))
client->synchronousMerge(m_repository, branch);
......@@ -321,7 +321,7 @@ void BranchDialog::rebase()
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!
const QString baseBranch = m_model->fullName(idx);
const QString baseBranch = m_model->fullName(idx, true);
GitClient *client = GitPlugin::instance()->gitClient();
if (client->beginStashScope(m_repository, QLatin1String("rebase")))
client->rebase(m_repository, baseBranch);
......
......@@ -38,6 +38,12 @@
namespace Git {
namespace Internal {
enum RootNodes {
LocalBranches = 0,
RemoteBranches = 1,
Tags = 2
};
// --------------------------------------------------------------------------
// BranchNode:
// --------------------------------------------------------------------------
......@@ -77,18 +83,6 @@ public:
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
{
if (this == node)
......@@ -96,12 +90,22 @@ public:
return parent ? parent->childOf(node) : false;
}
bool isLocal() const
bool childOfRoot(RootNodes root) const
{
BranchNode *rn = rootNode();
if (rn->isLeaf())
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
......@@ -113,7 +117,7 @@ public:
return 0;
}
QStringList fullName() const
QStringList fullName(bool includePrefix = false) const
{
QTC_ASSERT(isLeaf(), return QStringList());
......@@ -125,8 +129,9 @@ public:
current = current->parent;
}
if (current->children.at(0) == nodes.at(0))
nodes.removeFirst(); // remove local branch designation
if (includePrefix)
fn.append(nodes.first()->sha);
nodes.removeFirst();
foreach (const BranchNode *n, nodes)
fn.append(n->name);
......@@ -191,7 +196,12 @@ BranchModel::BranchModel(GitClient *client, QObject *parent) :
m_currentBranch(0)
{
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()
......@@ -320,11 +330,9 @@ Qt::ItemFlags BranchModel::flags(const QModelIndex &index) const
void BranchModel::clear()
{
while (m_rootNode->count() > 1)
delete m_rootNode->children.takeLast();
BranchNode *locals = m_rootNode->children.at(0);
while (locals->count())
delete locals->children.takeLast();
foreach (BranchNode *root, m_rootNode->children)
while (root->count())
delete root->children.takeLast();
m_currentBranch = 0;
}
......@@ -419,22 +427,20 @@ QModelIndex BranchModel::currentBranch() const
return nodeToIndex(m_currentBranch);
}
QString BranchModel::fullName(const QModelIndex &idx) const
QString BranchModel::fullName(const QModelIndex &idx, bool includePrefix) const
{
if (!idx.isValid())
return QString();
BranchNode *node = indexToNode(idx);
if (!node || !node->isLeaf())
return QString();
QStringList path = node->fullName();
if (node->isTag())
path.removeFirst();
QStringList path = node->fullName(includePrefix);
return path.join(QString(QLatin1Char('/')));
}
QStringList BranchModel::localBranchNames() const
{
if (!m_rootNode || m_rootNode->children.isEmpty())
if (!m_rootNode || !m_rootNode->count())
return QStringList();
return m_rootNode->children.at(0)->childrenNames();
......@@ -509,7 +515,7 @@ void BranchModel::removeTag(const QModelIndex &idx)
void BranchModel::checkoutBranch(const QModelIndex &idx)
{
QString branch = fullName(idx);
QString branch = fullName(idx, !isLocal(idx));
if (branch.isEmpty())
return;
......@@ -574,14 +580,15 @@ QModelIndex BranchModel::addBranch(const QString &name, bool track, const QModel
return QModelIndex();
const QString trackedBranch = fullName(startPoint);
const QString fullTrackedBranch = fullName(startPoint, true);
QString output;
QString errorMessage;
QStringList args;
args << (track ? QLatin1String("--track") : QLatin1String("--no-track"));
args << name;
if (!trackedBranch.isEmpty())
args << trackedBranch;
if (!fullTrackedBranch.isEmpty())
args << fullTrackedBranch;
if (!m_client->synchronousBranchCmd(m_workingDirectory, args, &output, &errorMessage)) {
VcsBase::VcsBaseOutputWindow::instance()->appendError(errorMessage);
......@@ -632,15 +639,18 @@ void BranchModel::parseOutputLine(const QString &line)
QStringList nameParts = fullName.split(QLatin1Char('/'));
nameParts.removeFirst(); // remove refs...
BranchNode *root = 0;
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"))
nameParts.removeFirst(); // remove "remotes"
else if (nameParts.first() == QLatin1String("stash"))
return;
else if (!showTags && (nameParts.first() == QLatin1String("tags")))
root = m_rootNode->children.at(1);
else if (showTags && nameParts.first() == QLatin1String("tags"))
root = m_rootNode->children.at(2);
else
return;
nameParts.removeFirst();
// limit depth of list. Git basically only ever wants one / and considers the rest as part of
// the name.
while (nameParts.count() > 3) {
......@@ -652,7 +662,7 @@ void BranchModel::parseOutputLine(const QString &line)
nameParts.removeLast();
BranchNode *newNode = new BranchNode(name, sha, lineParts.at(2));
m_rootNode->insert(nameParts, newNode);
root->insert(nameParts, newNode);
if (current)
m_currentBranch = newNode;
}
......
......@@ -70,7 +70,7 @@ public:
GitClient *client() const;
QModelIndex currentBranch() const;
QString fullName(const QModelIndex &idx) const;
QString fullName(const QModelIndex &idx, bool includePrefix = false) const;
QStringList localBranchNames() const;
QString sha(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.
Finish editing this message first!
Please register or to comment