From d425d6485e0a85b609f074bea78576fdd8612fb3 Mon Sep 17 00:00:00 2001
From: Petar Perisin <petar.perisin@gmail.com>
Date: Mon, 22 Apr 2013 22:47:18 +0200
Subject: [PATCH] Git - move ensureStash inside StashGuard

this is where stash popup question belongs

Change-Id: Ib3435f12eacd0b932ba2a67ecd728e5a41c0c64a
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
---
 src/plugins/git/branchdialog.cpp |  13 ++-
 src/plugins/git/gitclient.cpp    | 145 ++++++++++++++++---------------
 src/plugins/git/gitclient.h      |  12 +--
 src/plugins/git/gitplugin.cpp    |   9 +-
 4 files changed, 98 insertions(+), 81 deletions(-)

diff --git a/src/plugins/git/branchdialog.cpp b/src/plugins/git/branchdialog.cpp
index a32ae4d210f..14346a268a4 100644
--- a/src/plugins/git/branchdialog.cpp
+++ b/src/plugins/git/branchdialog.cpp
@@ -187,9 +187,16 @@ void BranchDialog::checkout()
 
         QString stashMessage;
         if (branchCheckoutDialog.makeStashOfCurrentBranch()
-            || branchCheckoutDialog.moveLocalChangesToNextBranch()) {
-            gitClient->ensureStash(m_repository, currentBranch + QLatin1String("-AutoStash"),
-                                   NoPrompt, &stashMessage);
+                || branchCheckoutDialog.moveLocalChangesToNextBranch()) {
+
+            GitClient::StashGuard stashGuard(m_repository,
+                                             currentBranch + QLatin1String("-AutoStash"),
+                                             NoPrompt);
+            if (stashGuard.stashingFailed())
+                return;
+            stashGuard.preventPop();
+            stashMessage = stashGuard.stashMessage();
+
         } else if (branchCheckoutDialog.discardLocalChanges()) {
             gitClient->synchronousReset(m_repository);
         }
diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp
index f4b65335d22..6ba8a88c275 100644
--- a/src/plugins/git/gitclient.cpp
+++ b/src/plugins/git/gitclient.cpp
@@ -1756,69 +1756,6 @@ bool GitClient::fullySynchronousGit(const QString &workingDirectory,
                                                        logCommandToWindow);
 }
 
-// Ensure that changed files are stashed before a pull or similar
-GitClient::StashResult GitClient::ensureStash(const QString &workingDirectory,
-                                              const QString &keyword,
-                                              StashFlag flag,
-                                              QString *message,
-                                              QString *errorMessage)
-{
-    QString statusOutput;
-    switch (gitStatus(workingDirectory, StatusMode(NoUntracked | NoSubmodules),
-                      &statusOutput, errorMessage)) {
-    case StatusChanged:
-        break;
-    case StatusUnchanged:
-        return StashUnchanged;
-    case StatusFailed:
-        return StashFailed;
-    }
-
-    if (!(flag & NoPrompt)) {
-        QPointer<QMessageBox> msgBox = new QMessageBox(QMessageBox::Question,
-                              tr("Uncommited changes found"),
-                              tr("What would you like to do with local changes?"),
-                              QMessageBox::NoButton, Core::ICore::mainWindow());
-
-        msgBox->setDetailedText(statusOutput);
-
-        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;
-        } else if (msgBox->clickedButton() == cancelButton) {
-            return StashCanceled;
-        }
-    }
-    const QString stashMessage = creatorStashMessage(keyword);
-    if (!executeSynchronousStash(workingDirectory, stashMessage, errorMessage))
-        return StashFailed;
-    if (message)
-        *message = stashMessage;
-    return Stashed;
- }
-
 void GitClient::submoduleUpdate(const QString &workingDirectory)
 {
     QStringList arguments;
@@ -2908,20 +2845,90 @@ GitClient::StashGuard::StashGuard(const QString &workingDirectory, const QString
 {
     client = GitPlugin::instance()->gitClient();
     QString errorMessage;
-    stashResult = client->ensureStash(workingDir, keyword, flags, &message, &errorMessage);
-    if (stashResult == GitClient::StashFailed)
+    if (flags & NoPrompt)
+        executeStash(keyword, &errorMessage);
+    else
+        stashPrompt(keyword, &errorMessage);
+
+    if (stashResult == StashFailed)
         VcsBase::VcsBaseOutputWindow::instance()->appendError(errorMessage);
 }
 
 GitClient::StashGuard::~StashGuard()
 {
-    if (pop && stashResult == GitClient::Stashed) {
+    if (pop && stashResult == Stashed) {
         QString stashName;
         if (client->stashNameFromMessage(workingDir, message, &stashName))
             client->stashPop(workingDir, stashName);
     }
 }
 
+void GitClient::StashGuard::stashPrompt(const QString &keyword, QString *errorMessage)
+{
+    QString statusOutput;
+    switch (client->gitStatus(workingDir, StatusMode(NoUntracked | NoSubmodules),
+                              &statusOutput, errorMessage)) {
+    case GitClient::StatusChanged:
+        break;
+    case GitClient::StatusUnchanged:
+        stashResult = StashUnchanged;
+        return;
+    case GitClient::StatusFailed:
+        stashResult = StashFailed;
+        return;
+    }
+
+    QPointer<QMessageBox> msgBox = new QMessageBox(QMessageBox::Question,
+                                   tr("Uncommitted Changes Found"),
+                                   tr("What would you like to do with local changes in:")
+                                        + QLatin1String("\n\n\"") + workingDir + QLatin1Char('\"'),
+                                   QMessageBox::NoButton, Core::ICore::mainWindow());
+
+    msgBox->setDetailedText(statusOutput);
+
+    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 (flags & 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;
+
+    if (msgBox->clickedButton() == discardButton) {
+        if (!client->synchronousReset(workingDir, QStringList(), errorMessage))
+            stashResult = StashFailed;
+        else
+            stashResult = StashUnchanged;
+    } else if (msgBox->clickedButton() == ignoreButton) { // At your own risk, so.
+        stashResult = NotStashed;
+    } else if (msgBox->clickedButton() == cancelButton) {
+        stashResult = StashCanceled;
+    } else if (msgBox->clickedButton() == stashButton) {
+        executeStash(keyword, errorMessage);
+    }
+}
+
+void GitClient::StashGuard::executeStash(const QString &keyword, QString *errorMessage)
+{
+    message = creatorStashMessage(keyword);
+    if (!client->executeSynchronousStash(workingDir, message, errorMessage))
+        stashResult = StashFailed;
+    else
+        stashResult = Stashed;
+ }
+
 void GitClient::StashGuard::preventPop()
 {
     pop = false;
@@ -2930,10 +2937,10 @@ void GitClient::StashGuard::preventPop()
 bool GitClient::StashGuard::stashingFailed() const
 {
     switch (stashResult) {
-    case GitClient::StashCanceled:
-    case GitClient::StashFailed:
+    case StashCanceled:
+    case StashFailed:
         return true;
-    case GitClient::NotStashed:
+    case NotStashed:
         return !(flags & AllowUnstashed);
     default:
         return false;
diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h
index b6e9315c013..046c9ae9543 100644
--- a/src/plugins/git/gitclient.h
+++ b/src/plugins/git/gitclient.h
@@ -87,15 +87,15 @@ class GitClient : public QObject
     Q_OBJECT
 
 public:
-    enum StashResult { StashUnchanged, StashCanceled, StashFailed,
-                       Stashed, NotStashed /* User did not want it */ };
-
     enum CommandInProgress { NoCommand, Revert, CherryPick,
                              Rebase, Merge, RebaseMerge };
 
     class StashGuard
     {
     public:
+        enum StashResult { StashUnchanged, StashCanceled, StashFailed,
+                           Stashed, NotStashed /* User did not want it */ };
+
         StashGuard(const QString &workingDirectory, const QString &keyword,
                    StashFlag flag = Default);
         ~StashGuard();
@@ -106,6 +106,9 @@ public:
         QString stashMessage() const { return message; }
 
     private:
+        void stashPrompt(const QString &keyword, QString *errorMessage);
+        void executeStash(const QString &keyword, QString *errorMessage);
+
         bool pop;
         StashResult stashResult;
         QString message;
@@ -260,9 +263,6 @@ public:
 
     QString readConfigValue(const QString &workingDirectory, const QString &configVar) const;
 
-    StashResult ensureStash(const QString &workingDirectory, const QString &keyword,
-                            StashFlag flag, QString *message, QString *errorMessage = 0);
-
     bool getCommitData(const QString &workingDirectory, bool amend,
                        QString *commitTemplate, CommitData *commitData,
                        QString *errorMessage);
diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp
index c9dcdd39f74..85d8c373b29 100644
--- a/src/plugins/git/gitplugin.cpp
+++ b/src/plugins/git/gitplugin.cpp
@@ -1220,9 +1220,12 @@ void GitPlugin::stash()
     // Simple stash without prompt, reset repo.
     const VcsBase::VcsBasePluginState state = currentState();
     QTC_ASSERT(state.hasTopLevel(), return);
-    QString id;
-    gitClient()->ensureStash(state.topLevel(), QString(), NoPrompt, &id);
-    if (!id.isEmpty() && m_stashDialog)
+
+    GitClient::StashGuard stashGuard(state.topLevel(), QString(), NoPrompt);
+    if (stashGuard.stashingFailed())
+        return;
+    stashGuard.preventPop();
+    if (stashGuard.result() == GitClient::StashGuard::Stashed && m_stashDialog)
         m_stashDialog->refresh(state.topLevel(), true);
 }
 
-- 
GitLab