summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPetar Perisin <petar.perisin@gmail.com>2012-12-16 20:35:58 +0100
committerTobias Hunger <tobias.hunger@digia.com>2013-01-07 15:33:20 +0100
commit81bf2ec154f8a98269040b1e185d9b59d2c6f3e9 (patch)
tree445b19a8c792f65762e5ce03af78229f749e2eb2 /src
parent7df112b687c8694153ef3a5938921104b6e75115 (diff)
downloadqt-creator-81bf2ec154f8a98269040b1e185d9b59d2c6f3e9.tar.gz
Git: Auto stash for branches
Allow user to handle local changes when switching branches. Task-number: QTCREATORBUG-8417 Change-Id: I62d615aadfbd81c8ae03f3cd292b98773a36e1e7 Reviewed-by: Orgad Shaneh <orgads@gmail.com> Reviewed-by: Tobias Hunger <tobias.hunger@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/git/branchcheckoutdialog.cpp88
-rw-r--r--src/plugins/git/branchcheckoutdialog.h45
-rw-r--r--src/plugins/git/branchcheckoutdialog.ui133
-rw-r--r--src/plugins/git/branchdialog.cpp57
-rw-r--r--src/plugins/git/git.pro9
-rw-r--r--src/plugins/git/git.qbs3
6 files changed, 331 insertions, 4 deletions
diff --git a/src/plugins/git/branchcheckoutdialog.cpp b/src/plugins/git/branchcheckoutdialog.cpp
new file mode 100644
index 0000000000..fc0c34aefa
--- /dev/null
+++ b/src/plugins/git/branchcheckoutdialog.cpp
@@ -0,0 +1,88 @@
+#include "branchcheckoutdialog.h"
+#include "ui_branchcheckoutdialog.h"
+
+namespace Git {
+namespace Internal {
+
+BranchCheckoutDialog::BranchCheckoutDialog(QWidget *parent,
+ const QString& currentBranch,
+ const QString& nextBranch) :
+ QDialog(parent),
+ m_ui(new Ui::BranchCheckoutDialog),
+ m_foundStashForNextBranch(false),
+ m_hasLocalChanges(true)
+{
+ m_ui->setupUi(this);
+
+ setWindowTitle(tr("Checkout branch \"%1\"").arg(nextBranch));
+ m_ui->moveChangesRadioButton->setText(tr("Move Local Changes to \"%1\"").arg(nextBranch));
+ m_ui->popStashCheckBox->setText(tr("Pop Stash of \"%1\"").arg(nextBranch));
+
+ if (!currentBranch.isEmpty()) {
+ m_ui->makeStashRadioButton->setText(tr("Create Branch Stash for \"%1\"").arg(currentBranch));
+ } else {
+ m_ui->makeStashRadioButton->setText(tr("Create Branch Stash for Current Branch"));
+ foundNoLocalChanges();
+ }
+
+ connect(m_ui->moveChangesRadioButton, SIGNAL(toggled(bool)), this, SLOT(updatePopStashCheckBox(bool)));
+}
+
+BranchCheckoutDialog::~BranchCheckoutDialog()
+{
+ delete m_ui;
+}
+
+void BranchCheckoutDialog::foundNoLocalChanges()
+{
+ m_ui->discardChangesRadioButton->setChecked(true);
+ m_ui->localChangesGroupBox->setEnabled(false);
+ m_hasLocalChanges = false;
+}
+
+void BranchCheckoutDialog::foundStashForNextBranch()
+{
+ m_ui->popStashCheckBox->setChecked(true);
+ m_ui->popStashCheckBox->setEnabled(true);
+ m_foundStashForNextBranch = true;
+}
+
+bool BranchCheckoutDialog::makeStashOfCurrentBranch()
+{
+ return m_ui->makeStashRadioButton->isChecked();
+}
+
+bool BranchCheckoutDialog::moveLocalChangesToNextBranch()
+{
+ return m_ui->moveChangesRadioButton->isChecked();
+}
+
+bool BranchCheckoutDialog::discardLocalChanges()
+{
+ return m_ui->discardChangesRadioButton->isChecked() && m_ui->localChangesGroupBox->isEnabled();
+}
+
+bool BranchCheckoutDialog::popStashOfNextBranch()
+{
+ return m_ui->popStashCheckBox->isChecked();
+}
+
+bool BranchCheckoutDialog::hasStashForNextBranch()
+{
+ return m_foundStashForNextBranch;
+}
+
+bool BranchCheckoutDialog::hasLocalChanges()
+{
+ return m_hasLocalChanges;
+}
+
+void BranchCheckoutDialog::updatePopStashCheckBox(bool moveChangesChecked)
+{
+ m_ui->popStashCheckBox->setChecked(!moveChangesChecked && m_foundStashForNextBranch);
+ m_ui->popStashCheckBox->setEnabled(!moveChangesChecked && m_foundStashForNextBranch);
+}
+
+} // namespace Internal
+} // namespace Git
+
diff --git a/src/plugins/git/branchcheckoutdialog.h b/src/plugins/git/branchcheckoutdialog.h
new file mode 100644
index 0000000000..a794b8ef36
--- /dev/null
+++ b/src/plugins/git/branchcheckoutdialog.h
@@ -0,0 +1,45 @@
+#ifndef BRANCHCHECKOUTDIALOG_H
+#define BRANCHCHECKOUTDIALOG_H
+
+#include <QDialog>
+
+namespace Git {
+namespace Internal {
+
+namespace Ui {
+ class BranchCheckoutDialog;
+}
+
+class BranchCheckoutDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit BranchCheckoutDialog(QWidget *parent, const QString& currentBranch,
+ const QString& nextBranch);
+ ~BranchCheckoutDialog();
+
+ void foundNoLocalChanges();
+ void foundStashForNextBranch();
+
+ bool makeStashOfCurrentBranch();
+ bool moveLocalChangesToNextBranch();
+ bool discardLocalChanges();
+ bool popStashOfNextBranch();
+
+ bool hasStashForNextBranch();
+ bool hasLocalChanges();
+
+private slots:
+ void updatePopStashCheckBox(bool moveChangesChecked);
+
+private:
+ Ui::BranchCheckoutDialog *m_ui;
+ bool m_foundStashForNextBranch;
+ bool m_hasLocalChanges;
+};
+
+} // namespace Internal
+} // namespace Git
+
+#endif // BRANCHCHECKOUTDIALOG_H
diff --git a/src/plugins/git/branchcheckoutdialog.ui b/src/plugins/git/branchcheckoutdialog.ui
new file mode 100644
index 0000000000..b8cbc406a9
--- /dev/null
+++ b/src/plugins/git/branchcheckoutdialog.ui
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Git::Internal::BranchCheckoutDialog</class>
+ <widget class="QDialog" name="Git::Internal::BranchCheckoutDialog">
+ <property name="windowModality">
+ <enum>Qt::WindowModal</enum>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>394</width>
+ <height>199</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <property name="modal">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QGroupBox" name="localChangesGroupBox">
+ <property name="title">
+ <string>Local Changes Found. Choose Action:</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QRadioButton" name="makeStashRadioButton">
+ <property name="text">
+ <string>RadioButton</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="moveChangesRadioButton">
+ <property name="text">
+ <string>RadioButton</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="discardChangesRadioButton">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Discard Local Changes</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="popStashCheckBox">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>CheckBox</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>discardChangesRadioButton</tabstop>
+ <tabstop>buttonBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>Git::Internal::BranchCheckoutDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>227</x>
+ <y>219</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>179</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>Git::Internal::BranchCheckoutDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>295</x>
+ <y>219</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>179</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/plugins/git/branchdialog.cpp b/src/plugins/git/branchdialog.cpp
index b39adce43c..bf36548700 100644
--- a/src/plugins/git/branchdialog.cpp
+++ b/src/plugins/git/branchdialog.cpp
@@ -29,9 +29,11 @@
#include "branchdialog.h"
#include "branchadddialog.h"
+#include "branchcheckoutdialog.h"
#include "branchmodel.h"
#include "gitclient.h"
#include "gitplugin.h"
+#include "gitutils.h"
#include "ui_branchdialog.h"
#include "stashdialog.h" // Label helpers
@@ -42,6 +44,7 @@
#include <QItemSelectionModel>
#include <QPushButton>
#include <QMessageBox>
+#include <QList>
#include <QDebug>
@@ -159,7 +162,59 @@ void BranchDialog::checkout()
QModelIndex idx = selectedIndex();
QTC_CHECK(m_model->isLocal(idx));
- m_model->checkoutBranch(idx);
+ const QString currentBranch = m_model->branchName(m_model->currentBranch());
+ const QString nextBranch = m_model->branchName(idx);
+ const QString popMessageStart = QCoreApplication::applicationName() +
+ QLatin1String(" ") + nextBranch + QLatin1String("-AutoStash ");
+
+ BranchCheckoutDialog branchCheckoutDialog(this, currentBranch, nextBranch);
+ GitClient *gitClient = GitPlugin::instance()->gitClient();
+
+ if (gitClient->gitStatus(m_repository, StatusMode(NoUntracked | NoSubmodules)) != GitClient::StatusChanged)
+ branchCheckoutDialog.foundNoLocalChanges();
+
+ QList<Stash> stashes;
+ gitClient->synchronousStashList(m_repository, &stashes);
+ foreach (const Stash &stash, stashes) {
+ if (stash.message.startsWith(popMessageStart)) {
+ branchCheckoutDialog.foundStashForNextBranch();
+ break;
+ }
+ }
+
+ if (!branchCheckoutDialog.hasLocalChanges() &&
+ !branchCheckoutDialog.hasStashForNextBranch()) {
+ // No local changes and no Auto Stash - no need to open dialog
+ m_model->checkoutBranch(idx);
+ } else if (branchCheckoutDialog.exec() == QDialog::Accepted && m_model) {
+
+ QString stashMessage;
+ if (branchCheckoutDialog.makeStashOfCurrentBranch()
+ || branchCheckoutDialog.moveLocalChangesToNextBranch()) {
+ stashMessage = gitClient->synchronousStash(m_repository, currentBranch + QLatin1String("-AutoStash"));
+ } else if (branchCheckoutDialog.discardLocalChanges()) {
+ gitClient->synchronousReset(m_repository);
+ }
+
+ m_model->checkoutBranch(idx);
+
+ QString stashName;
+ gitClient->synchronousStashList(m_repository, &stashes);
+ foreach (const Stash &stash, stashes) {
+ if (stash.message.startsWith(popMessageStart)) {
+ stashName = stash.name;
+ break;
+ }
+ }
+
+ if (!stashMessage.isEmpty() && branchCheckoutDialog.moveLocalChangesToNextBranch())
+ gitClient->stashPop(m_repository);
+ else if (branchCheckoutDialog.popStashOfNextBranch())
+ gitClient->synchronousStashRestore(m_repository, stashName);
+
+ if (branchCheckoutDialog.hasStashForNextBranch())
+ gitClient->synchronousStashRemove(m_repository, stashName);
+ }
enableButtons();
}
diff --git a/src/plugins/git/git.pro b/src/plugins/git/git.pro
index 873ad6bacd..7ddef37097 100644
--- a/src/plugins/git/git.pro
+++ b/src/plugins/git/git.pro
@@ -29,7 +29,8 @@ HEADERS += gitplugin.h \
remotedialog.h \
branchadddialog.h \
resetdialog.h \
- mergetool.h
+ mergetool.h \
+ branchcheckoutdialog.h
SOURCES += gitplugin.cpp \
gitclient.cpp \
@@ -52,7 +53,8 @@ SOURCES += gitplugin.cpp \
remotedialog.cpp \
branchadddialog.cpp \
resetdialog.cpp \
- mergetool.cpp
+ mergetool.cpp \
+ branchcheckoutdialog.cpp
FORMS += changeselectiondialog.ui \
settingspage.ui \
@@ -61,7 +63,8 @@ FORMS += changeselectiondialog.ui \
stashdialog.ui \
remotedialog.ui \
remoteadditiondialog.ui \
- branchadddialog.ui
+ branchadddialog.ui \
+ branchcheckoutdialog.ui
include(gitorious/gitorious.pri)
diff --git a/src/plugins/git/git.qbs b/src/plugins/git/git.qbs
index ec5a0af292..92c2597219 100644
--- a/src/plugins/git/git.qbs
+++ b/src/plugins/git/git.qbs
@@ -21,6 +21,9 @@ QtcPlugin {
"branchadddialog.cpp",
"branchadddialog.h",
"branchadddialog.ui",
+ "branchcheckoutdialog.cpp",
+ "branchcheckoutdialog.h",
+ "branchcheckoutdialog.ui",
"branchdialog.cpp",
"branchdialog.h",
"branchdialog.ui",