Git - move ensureStash inside StashGuard

this is where stash popup question belongs

Change-Id: Ib3435f12eacd0b932ba2a67ecd728e5a41c0c64a
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
This commit is contained in:
Petar Perisin
2013-04-22 22:47:18 +02:00
parent 09ea0d235a
commit d425d6485e
4 changed files with 98 additions and 81 deletions

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);
}