Commit 81bf2ec1 authored by Petar Perisin's avatar Petar Perisin Committed by Tobias Hunger
Browse files

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's avatarOrgad Shaneh <orgads@gmail.com>
Reviewed-by: default avatarTobias Hunger <tobias.hunger@digia.com>
parent 7df112b6
#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
#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
<?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>
......@@ -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();
}
......
......@@ -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)
......
......@@ -21,6 +21,9 @@ QtcPlugin {
"branchadddialog.cpp",
"branchadddialog.h",
"branchadddialog.ui",
"branchcheckoutdialog.cpp",
"branchcheckoutdialog.h",
"branchcheckoutdialog.ui",
"branchdialog.cpp",
"branchdialog.h",
"branchdialog.ui",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment