summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOrgad Shaneh <orgad.shaneh@audiocodes.com>2013-01-24 12:11:01 +0200
committerOrgad Shaneh <orgad.shaneh@audiocodes.com>2013-01-24 12:32:26 +0100
commit5551c1e906c617ba1214b97ecdc3a5fa04f71939 (patch)
tree39a81e28c30306c7f905a310bcf3ee2f5ceb93b0
parentc670a66fe10e20c92f9a7a40d68722f28b3af62b (diff)
downloadqt-creator-5551c1e906c617ba1214b97ecdc3a5fa04f71939.tar.gz
Git: Introduce StashGuard
Offers the user to stash changes (if relevant), stores the results and pops the stash when it goes out of scope (unless disabled) Change-Id: Ibc0d2a5d3e3c953062fb17ecba903ca814524837 Reviewed-by: Tobias Hunger <tobias.hunger@digia.com>
-rw-r--r--src/plugins/git/branchmodel.cpp15
-rw-r--r--src/plugins/git/changeselectiondialog.cpp2
-rw-r--r--src/plugins/git/gitclient.cpp45
-rw-r--r--src/plugins/git/gitclient.h24
-rw-r--r--src/plugins/git/gitplugin.cpp87
-rw-r--r--src/plugins/git/gitplugin.h1
-rw-r--r--src/plugins/vcsbase/vcsbaseplugin.cpp9
-rw-r--r--src/plugins/vcsbase/vcsbaseplugin.h1
8 files changed, 100 insertions, 84 deletions
diff --git a/src/plugins/git/branchmodel.cpp b/src/plugins/git/branchmodel.cpp
index 4a0c1af46f..17b2376a67 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 55023732a2..447cc38a58 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 1a82c4c4a7..d6a1309508 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 9e2469c5c6..9f77b0501b 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 19ddd7fd33..033e9d6e16 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 8e9dd0a636..0ff4961c06 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 21907765e8..0f3643ed3a 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 f2af81c08e..01b2525abc 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);