diff --git a/src/plugins/git/branchmodel.cpp b/src/plugins/git/branchmodel.cpp
index 4a0c1af46f51aecf8cd094f9ec29eb9adc352e46..17b2376a67984cfa2dbddf2ed86fbda26eddcbbf 100644
--- a/src/plugins/git/branchmodel.cpp
+++ b/src/plugins/git/branchmodel.cpp
@@ -443,18 +443,11 @@ void BranchModel::checkoutBranch(const QModelIndex &idx)
     if (branch.isEmpty())
         return;
 
-    QString errorMessage;
-    switch (m_client->ensureStash(m_workingDirectory, QLatin1String("Branch-Checkout"), true, 0, &errorMessage)) {
-    case GitClient::StashUnchanged:
-    case GitClient::Stashed:
-    case GitClient::NotStashed:
-        break;
-    case GitClient::StashCanceled:
-        return;
-    case GitClient::StashFailed:
-        VcsBase::VcsBaseOutputWindow::instance()->appendError(errorMessage);
+    GitClient::StashGuard stashGuard(m_workingDirectory, QLatin1String("Branch-Checkout"));
+    if (stashGuard.stashingFailed(false))
         return;
-    }
+    stashGuard.preventPop();
+    QString errorMessage;
     if (m_client->synchronousCheckoutBranch(m_workingDirectory, branch, &errorMessage)) {
         if (errorMessage.isEmpty()) {
             QModelIndex currentIdx = currentBranch();
diff --git a/src/plugins/git/changeselectiondialog.cpp b/src/plugins/git/changeselectiondialog.cpp
index 55023732a219eacd7b8dc831f02b8a1fa3afc2e8..447cc38a588b8be0b251fcec839aaf9b7c7d6dd2 100644
--- a/src/plugins/git/changeselectiondialog.cpp
+++ b/src/plugins/git/changeselectiondialog.cpp
@@ -80,6 +80,8 @@ QString ChangeSelectionDialog::workingDirectory() const
 
 void ChangeSelectionDialog::setWorkingDirectory(const QString &s)
 {
+    if (s.isEmpty())
+        return;
     m_ui.workingDirectoryEdit->setText(QDir::toNativeSeparators(s));
     m_ui.changeNumberEdit->setFocus(Qt::ActiveWindowFocusReason);
     m_ui.changeNumberEdit->setText(QLatin1String("HEAD"));
diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp
index 1a82c4c4a7bb8c8bda9b453ddeb909f95cb25f02..d6a130950864cec4274ceb7ed553029d99c4ee64 100644
--- a/src/plugins/git/gitclient.cpp
+++ b/src/plugins/git/gitclient.cpp
@@ -1567,16 +1567,6 @@ static inline int askWithDetailedText(QWidget *parent,
     return msgBox.exec();
 }
 
-// Convenience that pops up an msg box.
-GitClient::StashResult GitClient::ensureStash(const QString &workingDirectory, const QString &keyword, QString *message)
-{
-    QString errorMessage;
-    const StashResult sr = ensureStash(workingDirectory, keyword, true, message, &errorMessage);
-    if (sr == StashFailed)
-        outputWindow()->appendError(errorMessage);
-    return sr;
-}
-
 // Ensure that changed files are stashed before a pull or similar
 GitClient::StashResult GitClient::ensureStash(const QString &workingDirectory,
                                               const QString &keyword,
@@ -2540,6 +2530,41 @@ unsigned GitClient::synchronousGitVersion(QString *errorMessage) const
     return version(major, minor, patch);
 }
 
+GitClient::StashGuard::StashGuard(const QString &workingDirectory, const QString &keyword) :
+    pop(true),
+    workingDir(workingDirectory)
+{
+    client = GitPlugin::instance()->gitClient();
+    QString errorMessage;
+    stashResult = client->ensureStash(workingDir, keyword, true, &message, &errorMessage);
+    if (stashResult == GitClient::StashFailed)
+        VcsBase::VcsBaseOutputWindow::instance()->appendError(errorMessage);
+}
+
+GitClient::StashGuard::~StashGuard()
+{
+    if (pop && stashResult == GitClient::Stashed)
+        client->stashPop(workingDir, message);
+}
+
+void GitClient::StashGuard::preventPop()
+{
+    pop = false;
+}
+
+bool GitClient::StashGuard::stashingFailed(bool includeNotStashed) const
+{
+    switch (stashResult) {
+    case GitClient::StashCanceled:
+    case GitClient::StashFailed:
+        return true;
+    case GitClient::NotStashed:
+        return includeNotStashed;
+    default:
+        return false;
+    }
+}
+
 } // namespace Internal
 } // namespace Git
 
diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h
index 9e2469c5c62f66cca0d28daedfc2a610ba21e4f1..9f77b0501b03e981d989b20754bdb7ef5659fc5a 100644
--- a/src/plugins/git/gitclient.h
+++ b/src/plugins/git/gitclient.h
@@ -82,6 +82,27 @@ class GitClient : public QObject
     Q_OBJECT
 
 public:
+    enum StashResult { StashUnchanged, StashCanceled, StashFailed,
+                       Stashed, NotStashed /* User did not want it */ };
+
+    class StashGuard
+    {
+    public:
+        StashGuard(const QString &workingDirectory, const QString &keyword);
+        ~StashGuard();
+
+        void preventPop();
+        bool stashingFailed(bool includeNotStashed) const;
+        StashResult result() const { return stashResult; }
+
+    private:
+        bool pop;
+        StashResult stashResult;
+        QString message;
+        QString workingDir;
+        GitClient *client;
+    };
+
     static const char *stashNamePrefix;
 
     explicit GitClient(GitSettings *settings);
@@ -210,9 +231,6 @@ public:
 
     QString readConfigValue(const QString &workingDirectory, const QString &configVar) const;
 
-    enum StashResult { StashUnchanged, StashCanceled, StashFailed,
-                       Stashed, NotStashed /* User did not want it */ };
-    StashResult ensureStash(const QString &workingDirectory, const QString &keyword, QString *message = 0);
     StashResult ensureStash(const QString &workingDirectory, const QString &keyword, bool askUser,
                             QString *message, QString *errorMessage = 0);
 
diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp
index 19ddd7fd33b3947bf2e1c5b238bad19e37d09000..033e9d6e1662b91eecd6d5d8f006c5a55a184d61 100644
--- a/src/plugins/git/gitplugin.cpp
+++ b/src/plugins/git/gitplugin.cpp
@@ -714,54 +714,40 @@ void GitPlugin::resetRepository()
         }
 }
 
-
 void GitPlugin::startRevertCommit()
 {
-    startRevertOrCherryPick(true);
-}
+    const VcsBase::VcsBasePluginState state = currentState();
+    QString workingDirectory = state.currentDirectoryOrTopLevel();
+    if (workingDirectory.isEmpty())
+        return;
+    GitClient::StashGuard stashGuard(workingDirectory, QLatin1String("Revert"));
+    if (stashGuard.stashingFailed(true))
+        return;
+    ChangeSelectionDialog changeSelectionDialog(workingDirectory);
 
-void GitPlugin::startCherryPickCommit()
-{
-    startRevertOrCherryPick(false);
+    if (changeSelectionDialog.exec() != QDialog::Accepted)
+        return;
+    const QString change = changeSelectionDialog.change();
+    if (!change.isEmpty() && !m_gitClient->revertCommit(workingDirectory, change))
+        stashGuard.preventPop();
 }
 
-void GitPlugin::startRevertOrCherryPick(bool isRevert)
+void GitPlugin::startCherryPickCommit()
 {
     const VcsBase::VcsBasePluginState state = currentState();
-
-    QString stashKeyword = (isRevert ? QLatin1String("Revert") : QLatin1String("Cherry-pick"));
-
-    GitClient::StashResult stashResult =
-            m_gitClient->ensureStash(state.topLevel(), stashKeyword);
-    switch (stashResult) {
-    case GitClient::StashUnchanged:
-    case GitClient::Stashed:
-        break;
-    default:
+    QString workingDirectory = state.currentDirectoryOrTopLevel();
+    if (workingDirectory.isEmpty())
         return;
-    }
-
-    QString workingDirectory;
-    if (state.hasFile())
-        workingDirectory = state.currentFileDirectory();
-    else if (state.hasTopLevel())
-        workingDirectory = state.topLevel();
-    else
+    GitClient::StashGuard stashGuard(state.topLevel(), QLatin1String("Cherry-pick"));
+    if (stashGuard.stashingFailed(true))
         return;
-
     ChangeSelectionDialog changeSelectionDialog(workingDirectory);
 
     if (changeSelectionDialog.exec() != QDialog::Accepted)
         return;
     const QString change = changeSelectionDialog.change();
-    if (change.isEmpty())
-        return;
-
-    bool success = (isRevert ? m_gitClient->revertCommit(workingDirectory, change) :
-                               m_gitClient->cherryPickCommit(workingDirectory, change));
-
-    if (success && (stashResult == GitClient::Stashed))
-        m_gitClient->stashPop(workingDirectory);
+    if (!change.isEmpty() && !m_gitClient->cherryPickCommit(workingDirectory, change))
+        stashGuard.preventPop();
 }
 
 void GitPlugin::stageFile()
@@ -960,20 +946,11 @@ void GitPlugin::pull()
         }
     }
 
-    GitClient::StashResult stashResult = m_gitClient->ensureStash(state.topLevel(), QLatin1String("Pull"));
-    switch (stashResult) {
-    case GitClient::StashUnchanged:
-    case GitClient::Stashed:
-        if (m_gitClient->synchronousPull(state.topLevel(), rebase) && (stashResult == GitClient::Stashed))
-            m_gitClient->stashPop(state.topLevel());
-        break;
-    case GitClient::NotStashed:
-        if (!rebase)
-            m_gitClient->synchronousPull(state.topLevel(), false);
-        break;
-    default:
-        break;
-    }
+    GitClient::StashGuard stashGuard(state.topLevel(), QLatin1String("Pull"));
+    if (stashGuard.stashingFailed(false) || (rebase && (stashGuard.result() == GitClient::NotStashed)))
+        return;
+    if (!m_gitClient->synchronousPull(state.topLevel(), false))
+        stashGuard.preventPop();
 }
 
 void GitPlugin::push()
@@ -1090,14 +1067,9 @@ void GitPlugin::promptApplyPatch()
 void GitPlugin::applyPatch(const QString &workingDirectory, QString file)
 {
     // Ensure user has been notified about pending changes
-    switch (m_gitClient->ensureStash(workingDirectory, QLatin1String("Apply-Patch"))) {
-    case GitClient::StashUnchanged:
-    case GitClient::Stashed:
-    case GitClient::NotStashed:
-        break;
-    default:
+    GitClient::StashGuard stashGuard(workingDirectory, QLatin1String("Apply-Patch"));
+    if (stashGuard.stashingFailed(false))
         return;
-    }
     // Prompt for file
     if (file.isEmpty()) {
         const QString filter = tr("Patches (*.patch *.diff)");
@@ -1219,10 +1191,7 @@ void GitPlugin::showCommit()
     if (!m_changeSelectionDialog)
         m_changeSelectionDialog = new ChangeSelectionDialog();
 
-    if (state.hasFile())
-        m_changeSelectionDialog->setWorkingDirectory(state.currentFileDirectory());
-    else if (state.hasTopLevel())
-        m_changeSelectionDialog->setWorkingDirectory(state.topLevel());
+    m_changeSelectionDialog->setWorkingDirectory(state.currentDirectoryOrTopLevel());
 
     if (m_changeSelectionDialog->exec() != QDialog::Accepted)
         return;
diff --git a/src/plugins/git/gitplugin.h b/src/plugins/git/gitplugin.h
index 8e9dd0a636d01e5e44e9eb89fcd835af083e67a2..0ff4961c06d68e18230adf5f2cd11418e6fb2b12 100644
--- a/src/plugins/git/gitplugin.h
+++ b/src/plugins/git/gitplugin.h
@@ -118,7 +118,6 @@ private slots:
     void resetRepository();
     void startRevertCommit();
     void startCherryPickCommit();
-    void startRevertOrCherryPick(bool isRevert);
     void stageFile();
     void unstageFile();
     void gitkForCurrentFile();
diff --git a/src/plugins/vcsbase/vcsbaseplugin.cpp b/src/plugins/vcsbase/vcsbaseplugin.cpp
index 21907765e84ba94618ed864c68895bb52ee6f43f..0f3643ed3a504f021ad5b77e0741a3e4135372f6 100644
--- a/src/plugins/vcsbase/vcsbaseplugin.cpp
+++ b/src/plugins/vcsbase/vcsbaseplugin.cpp
@@ -409,6 +409,15 @@ QString VcsBasePluginState::topLevel() const
     return hasFile() ? data->m_state.currentFileTopLevel : data->m_state.currentProjectTopLevel;
 }
 
+QString VcsBasePluginState::currentDirectoryOrTopLevel() const
+{
+    if (hasFile())
+        return data->m_state.currentFileDirectory;
+    else if (data->m_state.hasProject())
+        return data->m_state.currentProjectTopLevel;
+    return QString();
+}
+
 bool VcsBasePluginState::equals(const Internal::State &rhs) const
 {
     return data->m_state.equals(rhs);
diff --git a/src/plugins/vcsbase/vcsbaseplugin.h b/src/plugins/vcsbase/vcsbaseplugin.h
index f2af81c08efa356967c94e4a26e73f851c535c74..01b2525abc7833edd8bff459ee3fe0ea0a160d55 100644
--- a/src/plugins/vcsbase/vcsbaseplugin.h
+++ b/src/plugins/vcsbase/vcsbaseplugin.h
@@ -99,6 +99,7 @@ public:
     // the file one.
     QString topLevel() const;
 
+    QString currentDirectoryOrTopLevel() const;
     bool equals(const VcsBasePluginState &rhs) const;
 
     friend VCSBASE_EXPORT QDebug operator<<(QDebug in, const VcsBasePluginState &state);