diff --git a/src/plugins/git/branchdialog.cpp b/src/plugins/git/branchdialog.cpp
index 9b97eae4fbd..78a7ba1648b 100644
--- a/src/plugins/git/branchdialog.cpp
+++ b/src/plugins/git/branchdialog.cpp
@@ -69,6 +69,7 @@ BranchDialog::BranchDialog(QWidget *parent) :
connect(m_ui->logButton, SIGNAL(clicked()), this, SLOT(log()));
connect(m_ui->mergeButton, SIGNAL(clicked()), this, SLOT(merge()));
connect(m_ui->rebaseButton, SIGNAL(clicked()), this, SLOT(rebase()));
+ connect(m_ui->trackButton, SIGNAL(clicked()), this, SLOT(setRemoteTracking()));
m_ui->branchView->setModel(m_model);
@@ -106,12 +107,14 @@ void BranchDialog::refreshIfSame(const QString &repository)
void BranchDialog::enableButtons()
{
QModelIndex idx = selectedIndex();
+ QModelIndex currentBranch = m_model->currentBranch();
const bool hasSelection = idx.isValid();
- const bool currentSelected = hasSelection && idx == m_model->currentBranch();
+ const bool currentSelected = hasSelection && idx == currentBranch;
const bool isLocal = m_model->isLocal(idx);
const bool isLeaf = m_model->isLeaf(idx);
const bool isTag = m_model->isTag(idx);
const bool hasActions = hasSelection && isLeaf;
+ const bool currentLocal = m_model->isLocal(currentBranch);
m_ui->removeButton->setEnabled(hasActions && !currentSelected && (isLocal || isTag));
m_ui->renameButton->setEnabled(hasActions && (isLocal || isTag));
@@ -120,6 +123,7 @@ void BranchDialog::enableButtons()
m_ui->checkoutButton->setEnabled(hasActions && !currentSelected);
m_ui->rebaseButton->setEnabled(hasActions && !currentSelected);
m_ui->mergeButton->setEnabled(hasActions && !currentSelected);
+ m_ui->trackButton->setEnabled(hasActions && currentLocal && !currentSelected && !isTag);
}
void BranchDialog::refresh()
@@ -331,6 +335,11 @@ void BranchDialog::rebase()
client->rebase(m_repository, baseBranch);
}
+void BranchDialog::setRemoteTracking()
+{
+ m_model->setRemoteTracking(selectedIndex());
+}
+
QModelIndex BranchDialog::selectedIndex()
{
QModelIndexList selected = m_ui->branchView->selectionModel()->selectedIndexes();
diff --git a/src/plugins/git/branchdialog.h b/src/plugins/git/branchdialog.h
index aac316d1c8d..12d19e5e4e6 100644
--- a/src/plugins/git/branchdialog.h
+++ b/src/plugins/git/branchdialog.h
@@ -74,6 +74,7 @@ private slots:
void log();
void merge();
void rebase();
+ void setRemoteTracking();
private:
QModelIndex selectedIndex();
diff --git a/src/plugins/git/branchdialog.ui b/src/plugins/git/branchdialog.ui
index e23889a3424..c57bba79065 100644
--- a/src/plugins/git/branchdialog.ui
+++ b/src/plugins/git/branchdialog.ui
@@ -153,6 +153,16 @@
+ -
+
+
+ Sets current branch to track the selected one
+
+
+ &Track
+
+
+
-
diff --git a/src/plugins/git/branchmodel.cpp b/src/plugins/git/branchmodel.cpp
index 1a07e15692d..a7b4ca03714 100644
--- a/src/plugins/git/branchmodel.cpp
+++ b/src/plugins/git/branchmodel.cpp
@@ -623,6 +623,18 @@ QModelIndex BranchModel::addBranch(const QString &name, bool track, const QModel
return nodeToIndex(newNode);
}
+void BranchModel::setRemoteTracking(const QModelIndex &trackingIndex)
+{
+ QModelIndex current = currentBranch();
+ QTC_ASSERT(current.isValid(), return);
+ const QString currentName = fullName(current);
+ const QString shortTracking = fullName(trackingIndex);
+ const QString tracking = fullName(trackingIndex, true);
+ m_client->synchronousSetTrackingBranch(m_workingDirectory, currentName, tracking);
+ m_currentBranch->tracking = shortTracking;
+ emit dataChanged(current, current);
+}
+
void BranchModel::parseOutputLine(const QString &line)
{
if (line.size() < 3)
diff --git a/src/plugins/git/branchmodel.h b/src/plugins/git/branchmodel.h
index f0bce510215..896d8ffabc6 100644
--- a/src/plugins/git/branchmodel.h
+++ b/src/plugins/git/branchmodel.h
@@ -82,6 +82,7 @@ public:
void checkoutBranch(const QModelIndex &idx);
bool branchIsMerged(const QModelIndex &idx);
QModelIndex addBranch(const QString &name, bool track, const QModelIndex &trackedBranch);
+ void setRemoteTracking(const QModelIndex &trackingIndex);
private:
void parseOutputLine(const QString &line);
diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp
index d0864461cd5..e80a947a015 100644
--- a/src/plugins/git/gitclient.cpp
+++ b/src/plugins/git/gitclient.cpp
@@ -3059,6 +3059,26 @@ QString GitClient::synchronousTrackingBranch(const QString &workingDirectory, co
return remote + QLatin1Char('/') + rBranch;
}
+bool GitClient::synchronousSetTrackingBranch(const QString &workingDirectory,
+ const QString &branch, const QString &tracking)
+{
+ QByteArray outputText;
+ QByteArray errorText;
+ QStringList arguments;
+ arguments << QLatin1String("branch");
+ if (gitVersion() >= 0x010800)
+ arguments << (QLatin1String("--set-upstream-to=") + tracking) << branch;
+ else
+ arguments << QLatin1String("--set-upstream") << branch << tracking;
+ const bool rc = fullySynchronousGit(workingDirectory, arguments, &outputText, &errorText);
+ if (!rc) {
+ const QString errorMessage = tr("Cannot set tracking branch: %1")
+ .arg(commandOutputFromLocal8Bit(errorText));
+ outputWindow()->appendError(errorMessage);
+ }
+ return rc;
+}
+
void GitClient::handleMergeConflicts(const QString &workingDir, const QString &commit,
const QStringList &files, const QString &abortCommand)
{
diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h
index a51735eca66..f32382c9716 100644
--- a/src/plugins/git/gitclient.h
+++ b/src/plugins/git/gitclient.h
@@ -251,6 +251,9 @@ public:
void synchronousAbortCommand(const QString &workingDir, const QString &abortCommand);
QString synchronousTrackingBranch(const QString &workingDirectory,
const QString &branch = QString());
+ bool synchronousSetTrackingBranch(const QString &workingDirectory,
+ const QString &branch,
+ const QString &tracking);
// git svn support (asynchronous).
void synchronousSubversionFetch(const QString &workingDirectory);