Git: make ensureStash dialog more clear.

Change-Id: I19ecde462d7a8a5fb00caa0414a9833ecab5057b
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
This commit is contained in:
Petar Perisin
2013-03-16 15:12:28 +01:00
parent 39d000430e
commit 93e51c186a
5 changed files with 69 additions and 46 deletions

View File

@@ -188,7 +188,8 @@ void BranchDialog::checkout()
QString stashMessage; QString stashMessage;
if (branchCheckoutDialog.makeStashOfCurrentBranch() if (branchCheckoutDialog.makeStashOfCurrentBranch()
|| branchCheckoutDialog.moveLocalChangesToNextBranch()) { || branchCheckoutDialog.moveLocalChangesToNextBranch()) {
gitClient->ensureStash(m_repository, currentBranch + QLatin1String("-AutoStash"), false, &stashMessage); gitClient->ensureStash(m_repository, currentBranch + QLatin1String("-AutoStash"),
NoPrompt, &stashMessage);
} else if (branchCheckoutDialog.discardLocalChanges()) { } else if (branchCheckoutDialog.discardLocalChanges()) {
gitClient->synchronousReset(m_repository); gitClient->synchronousReset(m_repository);
} }
@@ -287,7 +288,7 @@ void BranchDialog::merge()
QTC_CHECK(idx != 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->branchName(idx); const QString branch = m_model->branchName(idx);
GitClient::StashGuard stashGuard(m_repository, QLatin1String("merge"), false); GitClient::StashGuard stashGuard(m_repository, QLatin1String("merge"), AllowUnstashed);
if (!GitPlugin::instance()->gitClient()->synchronousMerge(m_repository, branch)) if (!GitPlugin::instance()->gitClient()->synchronousMerge(m_repository, branch))
stashGuard.preventPop(); stashGuard.preventPop();
} }
@@ -299,7 +300,7 @@ void BranchDialog::rebase()
QTC_CHECK(idx != 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->branchName(idx); const QString baseBranch = m_model->branchName(idx);
GitClient::StashGuard stashGuard(m_repository, QLatin1String("rebase"), false); GitClient::StashGuard stashGuard(m_repository, QLatin1String("rebase"));
if (!GitPlugin::instance()->gitClient()->synchronousRebase(m_repository, baseBranch)) if (!GitPlugin::instance()->gitClient()->synchronousRebase(m_repository, baseBranch))
stashGuard.preventPop(); stashGuard.preventPop();
} }

View File

@@ -470,10 +470,8 @@ void BranchModel::checkoutBranch(const QModelIndex &idx)
if (branch.isEmpty()) if (branch.isEmpty())
return; return;
GitClient::StashGuard stashGuard(m_workingDirectory, QLatin1String("Branch-Checkout")); // No StashGuard since this function for now is only used with clean working dir.
if (stashGuard.stashingFailed(false)) // If it is ever used from another place, please add StashGuard here
return;
stashGuard.preventPop();
QString errorMessage; QString errorMessage;
if (m_client->synchronousCheckout(m_workingDirectory, branch, &errorMessage)) { if (m_client->synchronousCheckout(m_workingDirectory, branch, &errorMessage)) {
if (errorMessage.isEmpty()) { if (errorMessage.isEmpty()) {

View File

@@ -1765,22 +1765,10 @@ bool GitClient::fullySynchronousGit(const QString &workingDirectory,
logCommandToWindow); logCommandToWindow);
} }
static inline int askWithDetailedText(QWidget *parent,
const QString &title, const QString &msg,
const QString &inf,
QMessageBox::StandardButton defaultButton,
QMessageBox::StandardButtons buttons = QMessageBox::Yes|QMessageBox::No)
{
QMessageBox msgBox(QMessageBox::Question, title, msg, buttons, parent);
msgBox.setDetailedText(inf);
msgBox.setDefaultButton(defaultButton);
return msgBox.exec();
}
// Ensure that changed files are stashed before a pull or similar // Ensure that changed files are stashed before a pull or similar
GitClient::StashResult GitClient::ensureStash(const QString &workingDirectory, GitClient::StashResult GitClient::ensureStash(const QString &workingDirectory,
const QString &keyword, const QString &keyword,
bool askUser, StashFlag flag,
QString *message, QString *message,
QString *errorMessage) QString *errorMessage)
{ {
@@ -1795,17 +1783,41 @@ GitClient::StashResult GitClient::ensureStash(const QString &workingDirectory,
return StashFailed; return StashFailed;
} }
if (askUser) { if (!(flag & NoPrompt)) {
const int answer = askWithDetailedText(Core::ICore::mainWindow(), tr("Changes"), QPointer<QMessageBox> msgBox = new QMessageBox(QMessageBox::Question,
tr("Would you like to stash your changes?"), tr("Uncommited changes found"),
statusOutput, QMessageBox::Yes, QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel); tr("What would you like to do with local changes?"),
switch (answer) { QMessageBox::NoButton, Core::ICore::mainWindow());
case QMessageBox::Cancel:
return StashCanceled; msgBox->setDetailedText(statusOutput);
case QMessageBox::No: // At your own risk, so.
QPushButton *stashButton = msgBox->addButton(tr("Stash"), QMessageBox::AcceptRole);
stashButton->setToolTip(tr("Stash local changes and continue"));
QPushButton *discardButton = msgBox->addButton(tr("Discard"), QMessageBox::AcceptRole);
discardButton->setToolTip(tr("Discard (reset) local changes and continue"));
QPushButton *ignoreButton = 0;
if (flag & AllowUnstashed) {
ignoreButton = msgBox->addButton(QMessageBox::Ignore);
ignoreButton->setToolTip(tr("Continue with local changes in working directory"));
}
QPushButton *cancelButton = msgBox->addButton(QMessageBox::Cancel);
cancelButton->setToolTip(tr("Cancel current command"));
msgBox->exec();
if (msgBox.isNull())
return StashFailed;
if (msgBox->clickedButton() == discardButton) {
if (!synchronousReset(workingDirectory, QStringList(), errorMessage))
return StashFailed;
return StashUnchanged;
} else if (msgBox->clickedButton() == ignoreButton) { // At your own risk, so.
return NotStashed; return NotStashed;
default: } else if (msgBox->clickedButton() == cancelButton) {
break; return StashCanceled;
} }
} }
const QString stashMessage = creatorStashMessage(keyword); const QString stashMessage = creatorStashMessage(keyword);
@@ -2871,13 +2883,15 @@ unsigned GitClient::synchronousGitVersion(QString *errorMessage) const
return version(major, minor, patch); return version(major, minor, patch);
} }
GitClient::StashGuard::StashGuard(const QString &workingDirectory, const QString &keyword, bool askUser) : GitClient::StashGuard::StashGuard(const QString &workingDirectory, const QString &keyword,
StashFlag flag) :
pop(true), pop(true),
workingDir(workingDirectory) workingDir(workingDirectory),
flags(flag)
{ {
client = GitPlugin::instance()->gitClient(); client = GitPlugin::instance()->gitClient();
QString errorMessage; QString errorMessage;
stashResult = client->ensureStash(workingDir, keyword, askUser, &message, &errorMessage); stashResult = client->ensureStash(workingDir, keyword, flags, &message, &errorMessage);
if (stashResult == GitClient::StashFailed) if (stashResult == GitClient::StashFailed)
VcsBase::VcsBaseOutputWindow::instance()->appendError(errorMessage); VcsBase::VcsBaseOutputWindow::instance()->appendError(errorMessage);
} }
@@ -2896,14 +2910,14 @@ void GitClient::StashGuard::preventPop()
pop = false; pop = false;
} }
bool GitClient::StashGuard::stashingFailed(bool includeNotStashed) const bool GitClient::StashGuard::stashingFailed() const
{ {
switch (stashResult) { switch (stashResult) {
case GitClient::StashCanceled: case GitClient::StashCanceled:
case GitClient::StashFailed: case GitClient::StashFailed:
return true; return true;
case GitClient::NotStashed: case GitClient::NotStashed:
return includeNotStashed; return !(flags & AllowUnstashed);
default: default:
return false; return false;
} }

View File

@@ -76,6 +76,12 @@ enum StatusMode
NoSubmodules = 2 NoSubmodules = 2
}; };
enum StashFlag {
Default = 0x00, /* Prompt and do not allow unstashed */
AllowUnstashed = 0x01,
NoPrompt = 0x02
};
class GitClient : public QObject class GitClient : public QObject
{ {
Q_OBJECT Q_OBJECT
@@ -87,12 +93,14 @@ public:
class StashGuard class StashGuard
{ {
public: public:
StashGuard(const QString &workingDirectory, const QString &keyword, bool askUser = true); StashGuard(const QString &workingDirectory, const QString &keyword,
StashFlag flag = Default);
~StashGuard(); ~StashGuard();
void preventPop(); void preventPop();
bool stashingFailed(bool includeNotStashed) const; bool stashingFailed() const;
StashResult result() const { return stashResult; } StashResult result() const { return stashResult; }
QString stashMessage() const { return message; }
private: private:
bool pop; bool pop;
@@ -100,6 +108,7 @@ public:
QString message; QString message;
QString workingDir; QString workingDir;
GitClient *client; GitClient *client;
StashFlag flags;
}; };
static const char *stashNamePrefix; static const char *stashNamePrefix;
@@ -250,8 +259,8 @@ public:
QString readConfigValue(const QString &workingDirectory, const QString &configVar) const; QString readConfigValue(const QString &workingDirectory, const QString &configVar) const;
StashResult ensureStash(const QString &workingDirectory, const QString &keyword, bool askUser, StashResult ensureStash(const QString &workingDirectory, const QString &keyword,
QString *message, QString *errorMessage = 0); StashFlag flag, QString *message, QString *errorMessage = 0);
bool getCommitData(const QString &workingDirectory, bool amend, bool getCommitData(const QString &workingDirectory, bool amend,
QString *commitTemplate, CommitData *commitData, QString *commitTemplate, CommitData *commitData,

View File

@@ -724,7 +724,7 @@ void GitPlugin::startRebase()
if (workingDirectory.isEmpty() || !m_gitClient->canRebase(workingDirectory)) if (workingDirectory.isEmpty() || !m_gitClient->canRebase(workingDirectory))
return; return;
GitClient::StashGuard stashGuard(workingDirectory, QLatin1String("Rebase-i")); GitClient::StashGuard stashGuard(workingDirectory, QLatin1String("Rebase-i"));
if (stashGuard.stashingFailed(true)) if (stashGuard.stashingFailed())
return; return;
stashGuard.preventPop(); stashGuard.preventPop();
LogChangeDialog dialog(false); LogChangeDialog dialog(false);
@@ -778,7 +778,7 @@ void GitPlugin::startChangeRelatedAction()
} }
GitClient::StashGuard stashGuard(workingDirectory, command); GitClient::StashGuard stashGuard(workingDirectory, command);
if (stashGuard.stashingFailed(true)) if (stashGuard.stashingFailed())
return; return;
if (!(m_gitClient->*commandFunction)(workingDirectory, change)) if (!(m_gitClient->*commandFunction)(workingDirectory, change))
@@ -1009,8 +1009,9 @@ void GitPlugin::pull()
} }
} }
GitClient::StashGuard stashGuard(topLevel, QLatin1String("Pull")); GitClient::StashGuard stashGuard(topLevel, QLatin1String("Pull"),
if (stashGuard.stashingFailed(false) || (rebase && (stashGuard.result() == GitClient::NotStashed))) rebase ? Default : AllowUnstashed);
if (stashGuard.stashingFailed())
return; return;
if (!m_gitClient->synchronousPull(topLevel, rebase)) if (!m_gitClient->synchronousPull(topLevel, rebase))
stashGuard.preventPop(); stashGuard.preventPop();
@@ -1137,8 +1138,8 @@ void GitPlugin::promptApplyPatch()
void GitPlugin::applyPatch(const QString &workingDirectory, QString file) void GitPlugin::applyPatch(const QString &workingDirectory, QString file)
{ {
// Ensure user has been notified about pending changes // Ensure user has been notified about pending changes
GitClient::StashGuard stashGuard(workingDirectory, QLatin1String("Apply-Patch")); GitClient::StashGuard stashGuard(workingDirectory, QLatin1String("Apply-Patch"), AllowUnstashed);
if (stashGuard.stashingFailed(false)) if (stashGuard.stashingFailed())
return; return;
// Prompt for file // Prompt for file
if (file.isEmpty()) { if (file.isEmpty()) {
@@ -1168,7 +1169,7 @@ void GitPlugin::stash()
const VcsBase::VcsBasePluginState state = currentState(); const VcsBase::VcsBasePluginState state = currentState();
QTC_ASSERT(state.hasTopLevel(), return); QTC_ASSERT(state.hasTopLevel(), return);
QString id; QString id;
gitClient()->ensureStash(state.topLevel(), QString(), false, &id); gitClient()->ensureStash(state.topLevel(), QString(), NoPrompt, &id);
if (!id.isEmpty() && m_stashDialog) if (!id.isEmpty() && m_stashDialog)
m_stashDialog->refresh(state.topLevel(), true); m_stashDialog->refresh(state.topLevel(), true);
} }