diff --git a/src/plugins/git/branchdialog.cpp b/src/plugins/git/branchdialog.cpp
index 9b97eae4fbdd93030bb501b2cef0b5bbbf412d18..78a7ba1648b2b83a87c6e5b76f54d4ef387d18ac 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 aac316d1c8dfa1b76d0c5ebab334f5d2e226bbd1..12d19e5e4e60b2a981355160a5d17c86c2cd1aad 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 e23889a3424deeda5bcdfcd78367c831fcadb2b8..c57bba79065aaa43be834a3a062d18ed79f642e7 100644
--- a/src/plugins/git/branchdialog.ui
+++ b/src/plugins/git/branchdialog.ui
@@ -153,6 +153,16 @@
           </item>
          </layout>
         </item>
+        <item>
+         <widget class="QPushButton" name="trackButton">
+          <property name="toolTip">
+           <string>Sets current branch to track the selected one</string>
+          </property>
+          <property name="text">
+           <string>&amp;Track</string>
+          </property>
+         </widget>
+        </item>
         <item>
          <spacer name="verticalSpacer">
           <property name="orientation">
diff --git a/src/plugins/git/branchmodel.cpp b/src/plugins/git/branchmodel.cpp
index 1a07e15692d3967ff470f804c97d564667735ec9..a7b4ca0371436902aa30725ae8c223414db7f040 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 f0bce5102152d49a1630fb3a4230e9422967d2c7..896d8ffabc64eb6f7378b186bed8a0d4203ce6f1 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 d0864461cd57733d01d9bbe36335a3d006137942..e80a947a0153884f8d4e6e70d3a75a3666095f4d 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 a51735eca66af17afeafe748e81f11aef8fa871c..f32382c9716c601ae46504f1442d282e936dd327 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);