diff options
author | Orgad Shaneh <orgad.shaneh@audiocodes.com> | 2013-01-24 12:11:01 +0200 |
---|---|---|
committer | Orgad Shaneh <orgad.shaneh@audiocodes.com> | 2013-01-24 12:32:26 +0100 |
commit | 5551c1e906c617ba1214b97ecdc3a5fa04f71939 (patch) | |
tree | 39a81e28c30306c7f905a310bcf3ee2f5ceb93b0 | |
parent | c670a66fe10e20c92f9a7a40d68722f28b3af62b (diff) | |
download | qt-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.cpp | 15 | ||||
-rw-r--r-- | src/plugins/git/changeselectiondialog.cpp | 2 | ||||
-rw-r--r-- | src/plugins/git/gitclient.cpp | 45 | ||||
-rw-r--r-- | src/plugins/git/gitclient.h | 24 | ||||
-rw-r--r-- | src/plugins/git/gitplugin.cpp | 87 | ||||
-rw-r--r-- | src/plugins/git/gitplugin.h | 1 | ||||
-rw-r--r-- | src/plugins/vcsbase/vcsbaseplugin.cpp | 9 | ||||
-rw-r--r-- | src/plugins/vcsbase/vcsbaseplugin.h | 1 |
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); |