forked from qt-creator/qt-creator
		
	Fixes: Add ensureStashed() method asking user to stash before a change such as pull
This commit is contained in:
		@@ -379,6 +379,23 @@ bool GitClient::synchronousCheckout(const QString &workingDirectory,
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool GitClient::synchronousStash(const QString &workingDirectory, QString *errorMessage)
 | 
			
		||||
{
 | 
			
		||||
    if (Git::Constants::debug)
 | 
			
		||||
        qDebug() << Q_FUNC_INFO << workingDirectory;
 | 
			
		||||
    QByteArray outputText;
 | 
			
		||||
    QByteArray errorText;
 | 
			
		||||
    QStringList arguments;
 | 
			
		||||
    arguments << QLatin1String("stash");
 | 
			
		||||
    const bool rc = synchronousGit(workingDirectory, arguments, &outputText, &errorText);
 | 
			
		||||
    if (!rc) {
 | 
			
		||||
        *errorMessage = tr("Unable stash in %1: %2").arg(workingDirectory, QString::fromLocal8Bit(errorText));
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void GitClient::executeGit(const QString &workingDirectory, const QStringList &arguments,
 | 
			
		||||
                           VCSBase::VCSBaseEditor* editor,
 | 
			
		||||
                           bool outputToWindow)
 | 
			
		||||
@@ -467,6 +484,60 @@ bool GitClient::synchronousGit(const QString &workingDirectory,
 | 
			
		||||
    return process.exitCode() == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
        askWithDetailedText(QWidget *parent,
 | 
			
		||||
                            const QString &title, const QString &msg,
 | 
			
		||||
                            const QString &inf,
 | 
			
		||||
                            QMessageBox::StandardButton defaultButton,
 | 
			
		||||
                            QMessageBox::StandardButtons buttons = QMessageBox::Yes|QMessageBox::No)
 | 
			
		||||
{
 | 
			
		||||
    QMessageBox msgBox(QMessageBox::Question, title, msg, buttons, parent);
 | 
			
		||||
    msgBox.setDetailedText(inf);
 | 
			
		||||
    msgBox.setDefaultButton(defaultButton);
 | 
			
		||||
    return msgBox.exec();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Convenience that pops up an msg box.
 | 
			
		||||
GitClient::StashResult GitClient::ensureStash(const QString &workingDirectory)
 | 
			
		||||
{
 | 
			
		||||
    QString errorMessage;
 | 
			
		||||
    const StashResult sr = ensureStash(workingDirectory, &errorMessage);
 | 
			
		||||
    if (sr == StashFailed) {
 | 
			
		||||
        m_plugin->outputWindow()->append(errorMessage);
 | 
			
		||||
        m_plugin->outputWindow()->popup();
 | 
			
		||||
    }
 | 
			
		||||
    return sr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Ensure that changed files are stashed before a pull or similar
 | 
			
		||||
GitClient::StashResult GitClient::ensureStash(const QString &workingDirectory, QString *errorMessage)
 | 
			
		||||
{
 | 
			
		||||
    QString statusOutput;
 | 
			
		||||
    switch (gitStatus(workingDirectory, false, &statusOutput, errorMessage)) {
 | 
			
		||||
        case StatusChanged:
 | 
			
		||||
        break;
 | 
			
		||||
        case StatusUnchanged:
 | 
			
		||||
        return StashUnchanged;
 | 
			
		||||
        case StatusFailed:
 | 
			
		||||
        return StashFailed;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const int answer = askWithDetailedText(m_core->mainWindow(), tr("Changes"),
 | 
			
		||||
                             tr("You have modified files. Would you like to stash your changes?"),
 | 
			
		||||
                             statusOutput, QMessageBox::Yes, QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel);
 | 
			
		||||
    switch (answer) {
 | 
			
		||||
        case QMessageBox::Cancel:
 | 
			
		||||
            return StashCanceled;
 | 
			
		||||
        case QMessageBox::Yes:
 | 
			
		||||
            if (!synchronousStash(workingDirectory, errorMessage))
 | 
			
		||||
                return StashFailed;
 | 
			
		||||
            break;
 | 
			
		||||
        case QMessageBox::No: // At your own risk, so.
 | 
			
		||||
            return NotStashed;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    return Stashed;
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
// Trim a git status file spec: "modified:    foo .cpp" -> "modified: foo .cpp"
 | 
			
		||||
static inline QString trimFileSpecification(QString fileSpec)
 | 
			
		||||
@@ -703,18 +774,6 @@ bool GitClient::addAndCommit(const QString &repositoryDirectory,
 | 
			
		||||
    return rc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool askWithInformativeText(QWidget *parent,
 | 
			
		||||
                                          const QString &title,
 | 
			
		||||
                                          const QString &msg,
 | 
			
		||||
                                          const QString &inf,
 | 
			
		||||
                                          bool defaultValue)
 | 
			
		||||
{
 | 
			
		||||
    QMessageBox msgBox(QMessageBox::Question, title, msg, QMessageBox::Yes|QMessageBox::No, parent);
 | 
			
		||||
    msgBox.setInformativeText(inf);
 | 
			
		||||
    msgBox.setDefaultButton(defaultValue ? QMessageBox::Yes : QMessageBox::No);
 | 
			
		||||
    return msgBox.exec() == QMessageBox::Yes;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Revert: This function can be called with a file list (to revert single
 | 
			
		||||
 * files)  or a single directory (revert all). Qt Creator currently has only
 | 
			
		||||
 * 'revert single' in its VCS menus, but the code is prepared to deal with
 | 
			
		||||
 
 | 
			
		||||
@@ -92,6 +92,7 @@ public:
 | 
			
		||||
    bool synchronousReset(const QString &workingDirectory, const QStringList &files);
 | 
			
		||||
    bool synchronousReset(const QString &workingDirectory, const QStringList &files, QString *errorMessage);
 | 
			
		||||
    bool synchronousCheckout(const QString &workingDirectory, const QStringList &files, QString *errorMessage);
 | 
			
		||||
    bool synchronousStash(const QString &workingDirectory, QString *errorMessage);
 | 
			
		||||
    void pull(const QString &workingDirectory);
 | 
			
		||||
    void push(const QString &workingDirectory);
 | 
			
		||||
 | 
			
		||||
@@ -105,6 +106,11 @@ public:
 | 
			
		||||
 | 
			
		||||
    QString readConfigValue(const QString &workingDirectory, const QString &configVar);
 | 
			
		||||
 | 
			
		||||
    enum StashResult { StashUnchanged, StashCanceled, StashFailed,
 | 
			
		||||
                       Stashed, NotStashed /* User did not want it */ };
 | 
			
		||||
    StashResult ensureStash(const QString &workingDirectory, QString *errorMessage);
 | 
			
		||||
    StashResult ensureStash(const QString &workingDirectory);
 | 
			
		||||
 | 
			
		||||
    bool getCommitData(const QString &workingDirectory,
 | 
			
		||||
                       QString *commitTemplate,
 | 
			
		||||
                       CommitData *d,
 | 
			
		||||
@@ -118,7 +124,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    enum StatusResult { StatusChanged, StatusUnchanged, StatusFailed };
 | 
			
		||||
    StatusResult gitStatus(const QString &workingDirectory,
 | 
			
		||||
                           bool untracked,
 | 
			
		||||
                           bool untracked = false,
 | 
			
		||||
                           QString *output = 0,
 | 
			
		||||
                           QString *errorMessage = 0);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -703,8 +703,17 @@ bool GitPlugin::editorAboutToClose(Core::IEditor *iEditor)
 | 
			
		||||
void GitPlugin::pull()
 | 
			
		||||
{
 | 
			
		||||
    const QString workingDirectory = getWorkingDirectory();
 | 
			
		||||
    if (!workingDirectory.isEmpty())
 | 
			
		||||
        m_gitClient->pull(workingDirectory);
 | 
			
		||||
    if (workingDirectory.isEmpty())
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    switch (m_gitClient->ensureStash(workingDirectory)) {
 | 
			
		||||
        case GitClient::StashUnchanged:
 | 
			
		||||
        case GitClient::Stashed:
 | 
			
		||||
        case GitClient::NotStashed:
 | 
			
		||||
            m_gitClient->pull(workingDirectory);
 | 
			
		||||
        default:
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GitPlugin::push()
 | 
			
		||||
 
 | 
			
		||||
@@ -97,6 +97,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    GitOutputWindow             *outputWindow() const;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    GitSettings  settings() const;
 | 
			
		||||
    void setSettings(const GitSettings &s);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user