Git: Make checkout asynchronous

It can be slow when many files are replaced.

Change-Id: I308698ef36973374f4526107fbda0d9ad907e707
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
Orgad Shaneh
2018-10-10 09:54:47 +03:00
committed by Orgad Shaneh
parent 86732dbdc0
commit 762fb5c353
6 changed files with 21 additions and 31 deletions

View File

@@ -529,7 +529,7 @@ void BranchModel::checkoutBranch(const QModelIndex &idx)
// No StashGuard since this function for now is only used with clean working dir.
// If it is ever used from another place, please add StashGuard here
m_client->synchronousCheckout(m_workingDirectory, branch);
m_client->checkout(m_workingDirectory, branch, GitClient::StashMode::NoStash);
}
bool BranchModel::branchIsMerged(const QModelIndex &idx)

View File

@@ -254,7 +254,7 @@ void FetchContext::cherryPick()
void FetchContext::checkout()
{
GitPlugin::client()->stashAndCheckout(m_repository, "FETCH_HEAD");
GitPlugin::client()->checkout(m_repository, "FETCH_HEAD");
}
void FetchContext::terminate()

View File

@@ -1113,21 +1113,22 @@ VcsBaseEditorWidget *GitClient::annotate(
return editor;
}
bool GitClient::synchronousCheckout(const QString &workingDirectory,
const QString &ref,
QString *errorMessage)
void GitClient::checkout(const QString &workingDirectory, const QString &ref,
StashMode stashMode)
{
if (stashMode == StashMode::TryStash && !beginStashScope(workingDirectory, "Checkout"))
return;
QStringList arguments = setupCheckoutArguments(workingDirectory, ref);
const SynchronousProcessResponse resp = vcsFullySynchronousExec(
workingDirectory, arguments, VcsCommand::ExpectRepoChanges);
VcsOutputWindow::append(resp.stdOut());
if (resp.result == SynchronousProcessResponse::Finished) {
updateSubmodulesIfNeeded(workingDirectory, true);
return true;
} else {
msgCannotRun(arguments, workingDirectory, resp.stdErr(), errorMessage);
return false;
}
VcsCommand *command = vcsExec(
workingDirectory, arguments, nullptr, true,
VcsCommand::ExpectRepoChanges | VcsCommand::ShowSuccessMessage);
connect(command, &VcsCommand::finished,
this, [this, workingDirectory, stashMode](bool success) {
if (stashMode == StashMode::TryStash)
endStashScope(workingDirectory);
if (success)
updateSubmodulesIfNeeded(workingDirectory, true);
});
}
/* method used to setup arguments for checkout, in case user wants to create local branch */
@@ -1358,16 +1359,6 @@ bool GitClient::synchronousCheckoutFiles(const QString &workingDirectory, QStrin
return true;
}
bool GitClient::stashAndCheckout(const QString &workingDirectory, const QString &ref)
{
if (!beginStashScope(workingDirectory, "Checkout"))
return false;
if (!synchronousCheckout(workingDirectory, ref))
return false;
endStashScope(workingDirectory);
return true;
}
static inline QString msgParentRevisionFailed(const QString &workingDirectory,
const QString &revision,
const QString &why)

View File

@@ -173,10 +173,9 @@ public:
bool synchronousCheckoutFiles(const QString &workingDirectory, QStringList files = QStringList(),
QString revision = QString(), QString *errorMessage = nullptr,
bool revertStaging = true);
// Checkout ref
bool stashAndCheckout(const QString &workingDirectory, const QString &ref);
bool synchronousCheckout(const QString &workingDirectory, const QString &ref,
QString *errorMessage = nullptr);
enum class StashMode { NoStash, TryStash };
void checkout(const QString &workingDirectory, const QString &ref,
StashMode stashMode = StashMode::TryStash);
QStringList setupCheckoutArguments(const QString &workingDirectory, const QString &ref);
void updateSubmodulesIfNeeded(const QString &workingDirectory, bool prompt);

View File

@@ -191,7 +191,7 @@ void GitEditorWidget::setPlainText(const QString &text)
void GitEditorWidget::checkoutChange()
{
GitPlugin::client()->stashAndCheckout(sourceWorkingDirectory(), m_currentChange);
GitPlugin::client()->checkout(sourceWorkingDirectory(), m_currentChange);
}
void GitEditorWidget::resetChange(const QByteArray &resetType)

View File

@@ -861,7 +861,7 @@ void GitPlugin::startChangeRelatedAction(const Id &id)
m_gitClient->synchronousRevert(workingDirectory, change);
break;
case Checkout:
m_gitClient->stashAndCheckout(workingDirectory, change);
m_gitClient->checkout(workingDirectory, change);
break;
default:
return;