Commit f3106eba authored by Orgad Shaneh's avatar Orgad Shaneh Committed by Orgad Shaneh

Git: Use a separate thread for updating commit data

Task-number: QTCREATORBUG-12449
Change-Id: I3057ca458272daac72c54abce1d6f9acf6a5d4af
Reviewed-by: default avatarTobias Hunger <tobias.hunger@digia.com>
parent aaa7cd58
......@@ -3174,6 +3174,11 @@ void GitClient::handleMergeConflicts(const QString &workingDir, const QString &c
}
}
void GitClient::addFuture(const QFuture<void> &future)
{
m_synchronizer.addFuture(future);
}
// Subversion: git svn
void GitClient::synchronousSubversionFetch(const QString &workingDirectory)
{
......
......@@ -35,6 +35,7 @@
#include <coreplugin/editormanager/ieditor.h>
#include <QFutureSynchronizer>
#include <QObject>
#include <QString>
#include <QStringList>
......@@ -329,6 +330,7 @@ public:
void endStashScope(const QString &workingDirectory);
bool isValidRevision(const QString &revision) const;
void handleMergeConflicts(const QString &workingDir, const QString &commit, const QStringList &files, const QString &abortCommand);
void addFuture(const QFuture<void> &future);
static QString msgNoChangedFiles();
static QString msgNoCommits(bool includeRemote);
......@@ -433,6 +435,7 @@ private:
int m_contextDiffFileIndex;
int m_contextChunkIndex;
QPointer<DiffEditor::DiffEditorController> m_contextDocument;
QFutureSynchronizer<void> m_synchronizer; // for commit updates
};
} // namespace Internal
......
......@@ -34,6 +34,7 @@
#include "gitsubmiteditorwidget.h"
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <utils/qtcassert.h>
#include <vcsbase/submitfilemodel.h>
#include <vcsbase/vcsbaseoutputwindow.h>
......@@ -41,6 +42,9 @@
#include <QDebug>
#include <QStringList>
#include <QTextCodec>
#include <QtConcurrentRun>
static const char TASK_UPDATE_COMMIT[] = "Git.UpdateCommit";
namespace Git {
namespace Internal {
......@@ -80,6 +84,38 @@ private:
}
};
class CommitDataFetcher : public QObject
{
Q_OBJECT
public:
CommitDataFetcher(CommitType commitType, const QString &workingDirectory) :
m_commitData(commitType),
m_workingDirectory(workingDirectory)
{
}
void start()
{
GitClient *client = GitPlugin::instance()->gitClient();
QString commitTemplate;
bool success = client->getCommitData(m_workingDirectory, &commitTemplate,
m_commitData, &m_errorMessage);
emit finished(success);
}
const CommitData &commitData() const { return m_commitData; }
const QString &errorMessage() const { return m_errorMessage; }
signals:
void finished(bool result);
private:
CommitData m_commitData;
QString m_workingDirectory;
QString m_errorMessage;
};
/* The problem with git is that no diff can be obtained to for a random
* multiselection of staged/unstaged files; it requires the --cached
* option for staged files. So, we sort apart the diff file lists
......@@ -90,12 +126,18 @@ GitSubmitEditor::GitSubmitEditor(const VcsBase::VcsBaseSubmitEditorParameters *p
m_model(0),
m_commitEncoding(0),
m_commitType(SimpleCommit),
m_firstUpdate(true)
m_firstUpdate(true),
m_commitDataFetcher(0)
{
connect(this, SIGNAL(diffSelectedFiles(QList<int>)), this, SLOT(slotDiffSelected(QList<int>)));
connect(submitEditorWidget(), SIGNAL(show(QString)), this, SLOT(showCommit(QString)));
}
GitSubmitEditor::~GitSubmitEditor()
{
resetCommitDataFetcher();
}
GitSubmitEditorWidget *GitSubmitEditor::submitEditorWidget()
{
return static_cast<GitSubmitEditorWidget *>(widget());
......@@ -106,6 +148,14 @@ const GitSubmitEditorWidget *GitSubmitEditor::submitEditorWidget() const
return static_cast<GitSubmitEditorWidget *>(widget());
}
void GitSubmitEditor::resetCommitDataFetcher()
{
if (!m_commitDataFetcher)
return;
disconnect(m_commitDataFetcher, SIGNAL(finished(bool)), this, SLOT(commitDataRetrieved(bool)));
connect(m_commitDataFetcher, SIGNAL(finished(bool)), m_commitDataFetcher, SLOT(deleteLater()));
}
void GitSubmitEditor::setCommitData(const CommitData &d)
{
m_commitEncoding = d.commitEncoding;
......@@ -181,19 +231,32 @@ void GitSubmitEditor::updateFileModel()
}
if (m_workingDirectory.isEmpty())
return;
GitClient *client = GitPlugin::instance()->gitClient();
QString errorMessage, commitTemplate;
CommitData data(m_commitType);
if (client->getCommitData(m_workingDirectory, &commitTemplate, data, &errorMessage)) {
setCommitData(data);
submitEditorWidget()->setUpdateInProgress(true);
resetCommitDataFetcher();
m_commitDataFetcher = new CommitDataFetcher(m_commitType, m_workingDirectory);
connect(m_commitDataFetcher, SIGNAL(finished(bool)), this, SLOT(commitDataRetrieved(bool)));
QFuture<void> future = QtConcurrent::run(m_commitDataFetcher, &CommitDataFetcher::start);
Core::ProgressManager::addTask(future, tr("Refreshing Commit Data"), TASK_UPDATE_COMMIT);
GitPlugin::instance()->gitClient()->addFuture(future);
}
void GitSubmitEditor::commitDataRetrieved(bool success)
{
GitSubmitEditorWidget *w = submitEditorWidget();
w->setUpdateInProgress(false);
if (success) {
setCommitData(m_commitDataFetcher->commitData());
submitEditorWidget()->refreshLog(m_workingDirectory);
widget()->setEnabled(true);
w->setEnabled(true);
} else {
// Nothing to commit left!
VcsBase::VcsBaseOutputWindow::instance()->appendError(errorMessage);
VcsBase::VcsBaseOutputWindow::instance()->appendError(m_commitDataFetcher->errorMessage());
m_model->clear();
widget()->setEnabled(false);
w->setEnabled(false);
}
m_commitDataFetcher->deleteLater();
m_commitDataFetcher = 0;
}
GitSubmitEditorPanelData GitSubmitEditor::panelData() const
......@@ -222,3 +285,5 @@ QByteArray GitSubmitEditor::fileContents() const
} // namespace Internal
} // namespace Git
#include "gitsubmiteditor.moc"
......@@ -43,6 +43,7 @@ namespace Internal {
class GitSubmitEditorWidget;
class CommitData;
class CommitDataFetcher;
struct GitSubmitEditorPanelData;
class GitSubmitEditor : public VcsBase::VcsBaseSubmitEditor
......@@ -50,6 +51,7 @@ class GitSubmitEditor : public VcsBase::VcsBaseSubmitEditor
Q_OBJECT
public:
explicit GitSubmitEditor(const VcsBase::VcsBaseSubmitEditorParameters *parameters, QWidget *parent);
~GitSubmitEditor();
void setCommitData(const CommitData &);
GitSubmitEditorPanelData panelData() const;
......@@ -68,10 +70,12 @@ protected:
private slots:
void slotDiffSelected(const QList<int> &rows);
void showCommit(const QString &commit);
void commitDataRetrieved(bool success);
private:
inline GitSubmitEditorWidget *submitEditorWidget();
inline const GitSubmitEditorWidget *submitEditorWidget() const;
void resetCommitDataFetcher();
VcsBase::SubmitFileModel *m_model;
QTextCodec *m_commitEncoding;
......@@ -79,6 +83,7 @@ private:
QString m_amendSHA1;
QString m_workingDirectory;
bool m_firstUpdate;
CommitDataFetcher *m_commitDataFetcher;
};
} // namespace Internal
......
......@@ -156,6 +156,7 @@ struct SubmitEditorWidgetPrivate
bool m_commitEnabled;
bool m_ignoreChange;
bool m_descriptionMandatory;
bool m_updateInProgress;
QActionPushButton *m_submitButton;
};
......@@ -170,6 +171,7 @@ SubmitEditorWidgetPrivate::SubmitEditorWidgetPrivate() :
m_commitEnabled(false),
m_ignoreChange(false),
m_descriptionMandatory(true),
m_updateInProgress(false),
m_submitButton(0)
{
}
......@@ -567,12 +569,20 @@ void SubmitEditorWidget::descriptionTextChanged()
bool SubmitEditorWidget::canSubmit() const
{
if (d->m_updateInProgress)
return false;
if (isDescriptionMandatory() && cleanupDescription(descriptionText()).trimmed().isEmpty())
return false;
const unsigned checkedCount = checkedFilesCount();
return d->m_emptyFileListEnabled || checkedCount > 0;
}
void SubmitEditorWidget::setUpdateInProgress(bool value)
{
d->m_updateInProgress = value;
updateSubmitAction();
}
QString SubmitEditorWidget::commitName() const
{
return tr("&Commit");
......
......@@ -104,6 +104,7 @@ public:
QList<SubmitFieldWidget *> submitFieldWidgets() const;
virtual bool canSubmit() const;
void setUpdateInProgress(bool value);
signals:
void diffSelected(const QList<int> &);
......@@ -126,6 +127,8 @@ protected:
protected slots:
void descriptionTextChanged();
public slots:
void updateSubmitAction();
private slots:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment