From eb1226df68edb2180425fda8411f57aab06c7b5f Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 7 Feb 2020 11:24:32 +0100 Subject: [PATCH] Git: Partially move plugin pimpl to .cpp Same procedure as for ClearCase. Unfortuately, some deep accesses are not easy to get rid of. Make them available by static functions in the plugin itself. Definitely not the favorite setup, but allows to proceed with the QObject removals. Change-Id: Id85ed07bc7a6c1c053431a14dd7f68892f7ebea0 Reviewed-by: Orgad Shaneh --- src/plugins/git/branchadddialog.cpp | 2 +- src/plugins/git/branchview.cpp | 38 +-- src/plugins/git/changeselectiondialog.cpp | 6 +- src/plugins/git/gerrit/branchcombobox.cpp | 4 +- src/plugins/git/gerrit/gerritdialog.cpp | 2 +- src/plugins/git/gerrit/gerritmodel.cpp | 2 +- src/plugins/git/gerrit/gerritplugin.cpp | 24 +- src/plugins/git/gerrit/gerritpushdialog.cpp | 14 +- .../git/gerrit/gerritremotechooser.cpp | 2 +- src/plugins/git/gerrit/gerritserver.cpp | 4 +- src/plugins/git/gitclient.cpp | 56 ++-- src/plugins/git/giteditor.cpp | 28 +- src/plugins/git/gitgrep.cpp | 6 +- src/plugins/git/gitplugin.cpp | 248 ++++++++++++++++-- src/plugins/git/gitplugin.h | 222 ++-------------- src/plugins/git/gitsubmiteditor.cpp | 12 +- src/plugins/git/logchangedialog.cpp | 8 +- src/plugins/git/mergetool.cpp | 6 +- src/plugins/git/remotedialog.cpp | 8 +- src/plugins/git/remotemodel.cpp | 10 +- src/plugins/git/stashdialog.cpp | 20 +- 21 files changed, 377 insertions(+), 345 deletions(-) diff --git a/src/plugins/git/branchadddialog.cpp b/src/plugins/git/branchadddialog.cpp index 09e18fbe0e7..8a131a363cc 100644 --- a/src/plugins/git/branchadddialog.cpp +++ b/src/plugins/git/branchadddialog.cpp @@ -50,7 +50,7 @@ class BranchNameValidator : public QValidator public: BranchNameValidator(const QStringList &localBranches, QObject *parent = nullptr) : QValidator(parent), - m_invalidChars(GitPluginPrivate::invalidBranchAndRemoteNamePattern()), + m_invalidChars(GitPlugin::invalidBranchAndRemoteNamePattern()), m_localBranches(localBranches) { } diff --git a/src/plugins/git/branchview.cpp b/src/plugins/git/branchview.cpp index 9e52a8d9087..0751a46e7ca 100644 --- a/src/plugins/git/branchview.cpp +++ b/src/plugins/git/branchview.cpp @@ -82,7 +82,7 @@ BranchView::BranchView() : m_refreshButton(new QToolButton(this)), m_repositoryLabel(new Utils::ElidingLabel(this)), m_branchView(new Utils::NavigationTreeView(this)), - m_model(new BranchModel(GitPluginPrivate::client(), this)), + m_model(new BranchModel(GitPlugin::client(), this)), m_filterModel(new BranchFilterModel(this)) { m_addButton->setIcon(Utils::Icons::PLUS_TOOLBAR.icon()); @@ -122,7 +122,7 @@ BranchView::BranchView() : this, &BranchView::setIncludeOldEntries); m_includeTagsAction->setCheckable(true); m_includeTagsAction->setChecked( - GitPluginPrivate::client()->settings().boolValue(GitSettings::showTagsKey)); + GitPlugin::client()->settings().boolValue(GitSettings::showTagsKey)); connect(m_includeTagsAction, &QAction::toggled, this, &BranchView::setIncludeTags); @@ -138,7 +138,7 @@ BranchView::BranchView() : this, &BranchView::expandAndResize); m_branchView->selectionModel()->clear(); - m_repository = GitPluginPrivate::instance()->currentState().topLevel(); + m_repository = GitPlugin::currentState().topLevel(); refreshCurrentRepository(); } @@ -160,7 +160,7 @@ void BranchView::refresh(const QString &repository, bool force) m_branchView->setEnabled(false); } else { m_repositoryLabel->setText(QDir::toNativeSeparators(m_repository)); - m_repositoryLabel->setToolTip(GitPluginPrivate::msgRepositoryLabel(m_repository)); + m_repositoryLabel->setToolTip(GitPlugin::msgRepositoryLabel(m_repository)); m_addButton->setToolTip(tr("Add Branch...")); m_branchView->setEnabled(true); } @@ -214,17 +214,17 @@ void BranchView::slotCustomContextMenu(const QPoint &point) const Utils::optional remote = m_model->remoteName(index); if (remote.has_value()) { contextMenu.addAction(tr("&Fetch"), this, [this, &remote]() { - GitPluginPrivate::client()->fetch(m_repository, *remote); + GitPlugin::client()->fetch(m_repository, *remote); }); contextMenu.addSeparator(); if (!remote->isEmpty()) { contextMenu.addAction(tr("Remove &Stale Branches"), this, [this, &remote]() { - GitPluginPrivate::client()->removeStaleRemoteBranches(m_repository, *remote); + GitPlugin::client()->removeStaleRemoteBranches(m_repository, *remote); }); contextMenu.addSeparator(); } - contextMenu.addAction(tr("Manage &Remotes..."), GitPluginPrivate::instance(), - &GitPluginPrivate::manageRemotes); + QAction *act = contextMenu.addAction(tr("Manage &Remotes...")); + connect(act, &QAction::triggered, [this] { GitPlugin::manageRemotes(); }); } if (hasActions) { if (!currentSelected && (isLocal || isTag)) @@ -237,7 +237,7 @@ void BranchView::slotCustomContextMenu(const QPoint &point) contextMenu.addAction(tr("&Diff"), this, [this] { const QString fullName = m_model->fullName(selectedIndex(), true); if (!fullName.isEmpty()) - GitPluginPrivate::client()->diffBranch(m_repository, fullName); + GitPlugin::client()->diffBranch(m_repository, fullName); }); contextMenu.addAction(tr("&Log"), this, [this] { log(selectedIndex()); }); contextMenu.addSeparator(); @@ -287,7 +287,7 @@ void BranchView::setIncludeOldEntries(bool filter) void BranchView::setIncludeTags(bool includeTags) { - GitPluginPrivate::client()->settings().setValue(GitSettings::showTagsKey, includeTags); + GitPlugin::client()->settings().setValue(GitSettings::showTagsKey, includeTags); refreshCurrentRepository(); } @@ -302,7 +302,7 @@ QModelIndex BranchView::selectedIndex() bool BranchView::add() { if (m_repository.isEmpty()) { - GitPluginPrivate::instance()->initRepository(); + GitPlugin::initRepository(); return true; } @@ -363,7 +363,7 @@ bool BranchView::checkout() ' ' + nextBranch + "-AutoStash "; BranchCheckoutDialog branchCheckoutDialog(this, currentBranch, nextBranch); - GitClient *client = GitPluginPrivate::client(); + GitClient *client = GitPlugin::client(); if (client->gitStatus(m_repository, StatusMode(NoUntracked | NoSubmodules)) != GitClient::StatusChanged) branchCheckoutDialog.foundNoLocalChanges(); @@ -498,7 +498,7 @@ bool BranchView::reset(const QByteArray &resetType) if (QMessageBox::question(this, tr("Git Reset"), tr("Reset branch \"%1\" to \"%2\"?") .arg(currentName).arg(branchName), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) { - GitPluginPrivate::client()->reset(m_repository, QLatin1String("--" + resetType), branchName); + GitPlugin::client()->reset(m_repository, QLatin1String("--" + resetType), branchName); return true; } return false; @@ -510,7 +510,7 @@ bool BranchView::isFastForwardMerge() QTC_CHECK(selected != m_model->currentBranch()); const QString branch = m_model->fullName(selected, true); - return GitPluginPrivate::client()->isFastForwardMerge(m_repository, branch); + return GitPlugin::client()->isFastForwardMerge(m_repository, branch); } bool BranchView::merge(bool allowFastForward) @@ -521,7 +521,7 @@ bool BranchView::merge(bool allowFastForward) QTC_CHECK(selected != m_model->currentBranch()); const QString branch = m_model->fullName(selected, true); - GitClient *client = GitPluginPrivate::client(); + GitClient *client = GitPlugin::client(); if (client->beginStashScope(m_repository, "merge", AllowUnstashed)) return client->synchronousMerge(m_repository, branch, allowFastForward); @@ -536,7 +536,7 @@ void BranchView::rebase() QTC_CHECK(selected != m_model->currentBranch()); const QString baseBranch = m_model->fullName(selected, true); - GitClient *client = GitPluginPrivate::client(); + GitClient *client = GitPlugin::client(); if (client->beginStashScope(m_repository, "rebase")) client->rebase(m_repository, baseBranch); } @@ -549,14 +549,14 @@ bool BranchView::cherryPick() QTC_CHECK(selected != m_model->currentBranch()); const QString branch = m_model->fullName(selected, true); - return GitPluginPrivate::client()->synchronousCherryPick(m_repository, branch); + return GitPlugin::client()->synchronousCherryPick(m_repository, branch); } void BranchView::log(const QModelIndex &idx) { const QString branchName = m_model->fullName(idx, true); if (!branchName.isEmpty()) - GitPluginPrivate::client()->log(m_repository, QString(), false, {branchName}); + GitPlugin::client()->log(m_repository, QString(), false, {branchName}); } void BranchView::push() @@ -572,7 +572,7 @@ void BranchView::push() const QString remoteBranch = fullTargetName.mid(pos + 1); const QStringList pushArgs = {remoteName, localBranch + ':' + remoteBranch}; - GitPluginPrivate::client()->push(m_repository, pushArgs); + GitPlugin::client()->push(m_repository, pushArgs); } BranchViewFactory::BranchViewFactory() diff --git a/src/plugins/git/changeselectiondialog.cpp b/src/plugins/git/changeselectiondialog.cpp index 9f7585cd0dd..47a55be5c56 100644 --- a/src/plugins/git/changeselectiondialog.cpp +++ b/src/plugins/git/changeselectiondialog.cpp @@ -58,12 +58,12 @@ ChangeSelectionDialog::ChangeSelectionDialog(const QString &workingDirectory, Co QDialog(parent), m_ui(new Ui::ChangeSelectionDialog) { setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); - m_gitExecutable = GitPluginPrivate::client()->vcsBinary(); + m_gitExecutable = GitPlugin::client()->vcsBinary(); m_ui->setupUi(this); m_ui->workingDirectoryChooser->setExpectedKind(PathChooser::ExistingDirectory); m_ui->workingDirectoryChooser->setPromptDialogTitle(tr("Select Git Directory")); m_ui->workingDirectoryChooser->setPath(workingDirectory); - m_gitEnvironment = GitPluginPrivate::client()->processEnvironment(); + m_gitEnvironment = GitPlugin::client()->processEnvironment(); m_ui->changeNumberEdit->setFocus(); m_ui->changeNumberEdit->selectAll(); @@ -204,7 +204,7 @@ void ChangeSelectionDialog::recalculateCompletion() if (workingDir.isEmpty()) return; - GitClient *client = GitPluginPrivate::client(); + GitClient *client = GitPlugin::client(); VcsBase::VcsCommand *command = client->asyncForEachRefCmd( workingDir, {"--format=%(refname:short)"}); connect(this, &QObject::destroyed, command, &VcsBase::VcsCommand::abort); diff --git a/src/plugins/git/gerrit/branchcombobox.cpp b/src/plugins/git/gerrit/branchcombobox.cpp index 6505066a3b2..6cc866ce3f1 100644 --- a/src/plugins/git/gerrit/branchcombobox.cpp +++ b/src/plugins/git/gerrit/branchcombobox.cpp @@ -36,7 +36,7 @@ BranchComboBox::BranchComboBox(QWidget *parent) : QComboBox(parent) void BranchComboBox::init(const QString &repository) { m_repository = repository; - QString currentBranch = GitPluginPrivate::client()->synchronousCurrentLocalBranch(repository); + QString currentBranch = GitPlugin::client()->synchronousCurrentLocalBranch(repository); if (currentBranch.isEmpty()) { m_detached = true; currentBranch = "HEAD"; @@ -44,7 +44,7 @@ void BranchComboBox::init(const QString &repository) } QString output; const QString branchPrefix("refs/heads/"); - if (!GitPluginPrivate::client()->synchronousForEachRefCmd( + if (!GitPlugin::client()->synchronousForEachRefCmd( m_repository, {"--format=%(refname)", branchPrefix}, &output)) { return; } diff --git a/src/plugins/git/gerrit/gerritdialog.cpp b/src/plugins/git/gerrit/gerritdialog.cpp index 26babec2a1a..402c29763a1 100644 --- a/src/plugins/git/gerrit/gerritdialog.cpp +++ b/src/plugins/git/gerrit/gerritdialog.cpp @@ -139,7 +139,7 @@ void GerritDialog::setCurrentPath(const QString &path) if (path == m_repository) return; m_repository = path; - m_ui->repositoryLabel->setText(Git::Internal::GitPluginPrivate::msgRepositoryLabel(path)); + m_ui->repositoryLabel->setText(Git::Internal::GitPlugin::msgRepositoryLabel(path)); updateRemotes(); } diff --git a/src/plugins/git/gerrit/gerritmodel.cpp b/src/plugins/git/gerrit/gerritmodel.cpp index 694e25dc913..a9be6358ccb 100644 --- a/src/plugins/git/gerrit/gerritmodel.cpp +++ b/src/plugins/git/gerrit/gerritmodel.cpp @@ -295,7 +295,7 @@ QueryContext::QueryContext(const QString &query, connect(&m_process, &QProcess::errorOccurred, this, &QueryContext::processError); connect(&m_watcher, &QFutureWatcherBase::canceled, this, &QueryContext::terminate); m_watcher.setFuture(m_progress.future()); - m_process.setProcessEnvironment(Git::Internal::GitPluginPrivate::client()->processEnvironment()); + m_process.setProcessEnvironment(Git::Internal::GitPlugin::client()->processEnvironment()); m_progress.setProgressRange(0, 1); m_timer.setInterval(timeOutMS); diff --git a/src/plugins/git/gerrit/gerritplugin.cpp b/src/plugins/git/gerrit/gerritplugin.cpp index 598a6fb75d1..656f1e34f70 100644 --- a/src/plugins/git/gerrit/gerritplugin.cpp +++ b/src/plugins/git/gerrit/gerritplugin.cpp @@ -148,7 +148,7 @@ FetchContext::FetchContext(const QSharedPointer &change, connect(&m_watcher, &QFutureWatcher::canceled, this, &FetchContext::terminate); m_watcher.setFuture(m_progress.future()); m_process.setWorkingDirectory(repository); - m_process.setProcessEnvironment(GitPluginPrivate::client()->processEnvironment()); + m_process.setProcessEnvironment(GitPlugin::client()->processEnvironment()); m_process.closeWriteChannel(); } @@ -240,7 +240,7 @@ void FetchContext::show() { const QString title = QString::number(m_change->number) + '/' + QString::number(m_change->currentPatchSet.patchSetNumber); - GitPluginPrivate::client()->show(m_repository, "FETCH_HEAD", title); + GitPlugin::client()->show(m_repository, "FETCH_HEAD", title); } void FetchContext::cherryPick() @@ -248,12 +248,12 @@ void FetchContext::cherryPick() // Point user to errors. VcsBase::VcsOutputWindow::instance()->popup(IOutputPane::ModeSwitch | IOutputPane::WithFocus); - GitPluginPrivate::client()->synchronousCherryPick(m_repository, "FETCH_HEAD"); + GitPlugin::client()->synchronousCherryPick(m_repository, "FETCH_HEAD"); } void FetchContext::checkout() { - GitPluginPrivate::client()->checkout(m_repository, "FETCH_HEAD"); + GitPlugin::client()->checkout(m_repository, "FETCH_HEAD"); } void FetchContext::terminate() @@ -328,12 +328,12 @@ void GerritPlugin::push(const QString &topLevel) dialog.storeTopic(); m_reviewers = dialog.reviewers(); - GitPluginPrivate::client()->push(topLevel, {dialog.selectedRemoteName(), dialog.pushTarget()}); + GitPlugin::client()->push(topLevel, {dialog.selectedRemoteName(), dialog.pushTarget()}); } static QString currentRepository() { - return GitPluginPrivate::instance()->currentState().topLevel(); + return GitPlugin::currentState().topLevel(); } // Open or raise the Gerrit dialog window. @@ -375,19 +375,19 @@ void GerritPlugin::push() Utils::FilePath GerritPlugin::gitBinDirectory() { - return GitPluginPrivate::client()->gitBinDirectory(); + return GitPlugin::client()->gitBinDirectory(); } // Find the branch of a repository. QString GerritPlugin::branch(const QString &repository) { - return GitPluginPrivate::client()->synchronousCurrentLocalBranch(repository); + return GitPlugin::client()->synchronousCurrentLocalBranch(repository); } void GerritPlugin::fetch(const QSharedPointer &change, int mode) { // Locate git. - const Utils::FilePath git = GitPluginPrivate::client()->vcsBinary(); + const Utils::FilePath git = GitPlugin::client()->vcsBinary(); if (git.isEmpty()) { VcsBase::VcsOutputWindow::appendError(tr("Git is not available.")); return; @@ -400,7 +400,7 @@ void GerritPlugin::fetch(const QSharedPointer &change, int mode) if (!repository.isEmpty()) { // Check if remote from a working dir is the same as remote from patch - QMap remotesList = GitPluginPrivate::client()->synchronousRemotesList(repository); + QMap remotesList = GitPlugin::client()->synchronousRemotesList(repository); if (!remotesList.isEmpty()) { const QStringList remotes = remotesList.values(); for (QString remote : remotes) { @@ -413,7 +413,7 @@ void GerritPlugin::fetch(const QSharedPointer &change, int mode) } if (!verifiedRepository) { - const SubmoduleDataMap submodules = GitPluginPrivate::client()->submoduleList(repository); + const SubmoduleDataMap submodules = GitPlugin::client()->submoduleList(repository); for (const SubmoduleData &submoduleData : submodules) { QString remote = submoduleData.url; if (remote.endsWith(".git")) @@ -472,7 +472,7 @@ void GerritPlugin::fetch(const QSharedPointer &change, int mode) // Try to find a matching repository for a project by asking the VcsManager. QString GerritPlugin::findLocalRepository(QString project, const QString &branch) const { - const QStringList gitRepositories = VcsManager::repositories(GitPluginPrivate::instance()); + const QStringList gitRepositories = VcsManager::repositories(GitPlugin::versionControl()); // Determine key (file name) to look for (qt/qtbase->'qtbase'). const int slashPos = project.lastIndexOf('/'); if (slashPos != -1) diff --git a/src/plugins/git/gerrit/gerritpushdialog.cpp b/src/plugins/git/gerrit/gerritpushdialog.cpp index 305581ae40b..9a251b5eda1 100644 --- a/src/plugins/git/gerrit/gerritpushdialog.cpp +++ b/src/plugins/git/gerrit/gerritpushdialog.cpp @@ -70,7 +70,7 @@ QString GerritPushDialog::determineRemoteBranch(const QString &localBranch) QString output; QString error; - if (!GitPluginPrivate::client()->synchronousBranchCmd( + if (!GitPlugin::client()->synchronousBranchCmd( m_workingDir, {"-r", "--contains", earliestCommit + '^'}, &output, &error)) { return QString(); } @@ -79,7 +79,7 @@ QString GerritPushDialog::determineRemoteBranch(const QString &localBranch) QString remoteTrackingBranch; if (localBranch != "HEAD") - remoteTrackingBranch = GitPluginPrivate::client()->synchronousTrackingBranch(m_workingDir, localBranch); + remoteTrackingBranch = GitPlugin::client()->synchronousTrackingBranch(m_workingDir, localBranch); QString remoteBranch; for (const QString &reference : refs) { @@ -103,7 +103,7 @@ void GerritPushDialog::initRemoteBranches() const QString head = "/HEAD"; QString remotesPrefix("refs/remotes/"); - if (!GitPluginPrivate::client()->synchronousForEachRefCmd( + if (!GitPlugin::client()->synchronousForEachRefCmd( m_workingDir, {"--format=%(refname)\t%(committerdate:raw)", remotesPrefix}, &output)) { return; } @@ -187,7 +187,7 @@ QString GerritPushDialog::calculateChangeRange(const QString &branch) QString number; QString error; - GitPluginPrivate::client()->synchronousRevListCmd(m_workingDir, { remote + ".." + branch, "--count" }, + GitPlugin::client()->synchronousRevListCmd(m_workingDir, { remote + ".." + branch, "--count" }, &number, &error); number.chop(1); @@ -304,7 +304,7 @@ QString GerritPushDialog::pushTarget() const void GerritPushDialog::storeTopic() { const QString branch = m_ui->localBranchComboBox->currentText(); - GitPluginPrivate::client()->setConfigValue(m_workingDir, QString("branch.%1.topic").arg(branch), + GitPlugin::client()->setConfigValue(m_workingDir, QString("branch.%1.topic").arg(branch), selectedTopic()); } @@ -317,7 +317,7 @@ void GerritPushDialog::setRemoteBranches(bool includeOld) const QString remoteName = selectedRemoteName(); if (!m_remoteBranches.contains(remoteName)) { const QStringList remoteBranches = - GitPluginPrivate::client()->synchronousRepositoryBranches(remoteName, m_workingDir); + GitPlugin::client()->synchronousRepositoryBranches(remoteName, m_workingDir); for (const QString &branch : remoteBranches) m_remoteBranches.insertMulti(remoteName, qMakePair(branch, QDate())); if (remoteBranches.isEmpty()) { @@ -355,7 +355,7 @@ void GerritPushDialog::updateCommits(int index) { const QString branch = m_ui->localBranchComboBox->itemText(index); m_hasLocalCommits = m_ui->commitView->init(m_workingDir, branch, LogChangeWidget::Silent); - QString topic = GitPluginPrivate::client()->readConfigValue( + QString topic = GitPlugin::client()->readConfigValue( m_workingDir, QString("branch.%1.topic").arg(branch)); if (!topic.isEmpty()) m_ui->topicLineEdit->setText(topic); diff --git a/src/plugins/git/gerrit/gerritremotechooser.cpp b/src/plugins/git/gerrit/gerritremotechooser.cpp index f7c4d779a68..8e5e7cd8828 100644 --- a/src/plugins/git/gerrit/gerritremotechooser.cpp +++ b/src/plugins/git/gerrit/gerritremotechooser.cpp @@ -104,7 +104,7 @@ bool GerritRemoteChooser::updateRemotes(bool forceReload) m_remotes.clear(); QString errorMessage; // Mute errors. We'll just fallback to the defaults const QMap remotesList = - Git::Internal::GitPluginPrivate::client()->synchronousRemotesList(m_repository, &errorMessage); + Git::Internal::GitPlugin::client()->synchronousRemotesList(m_repository, &errorMessage); for (auto mapIt = remotesList.cbegin(), end = remotesList.cend(); mapIt != end; ++mapIt) { GerritServer server; if (!server.fillFromRemote(mapIt.value(), *m_parameters, forceReload)) diff --git a/src/plugins/git/gerrit/gerritserver.cpp b/src/plugins/git/gerrit/gerritserver.cpp index c47cd281f30..f642b1f9d68 100644 --- a/src/plugins/git/gerrit/gerritserver.cpp +++ b/src/plugins/git/gerrit/gerritserver.cpp @@ -240,7 +240,7 @@ QStringList GerritServer::curlArguments() const int GerritServer::testConnection() { - static GitClient *const client = GitPluginPrivate::client(); + static GitClient *const client = GitPlugin::client(); const QStringList arguments = curlArguments() << (url(RestUrl) + accountUrlC); const SynchronousProcessResponse resp = client->vcsFullySynchronousExec( QString(), {curlBinary, arguments}, @@ -332,7 +332,7 @@ bool GerritServer::resolveRoot() void GerritServer::resolveVersion(const GerritParameters &p, bool forceReload) { - static GitClient *const client = GitPluginPrivate::client(); + static GitClient *const client = GitPlugin::client(); QSettings *settings = Core::ICore::settings(); const QString fullVersionKey = "Gerrit/" + host + '/' + versionKey; version = settings->value(fullVersionKey).toString(); diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index d4a4a57edb0..eba618dd024 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -300,7 +300,7 @@ void GitDiffEditorController::updateBranchList() return; const QString workingDirectory = baseDirectory(); - VcsCommand *command = GitPluginPrivate::client()->vcsExec( + VcsCommand *command = GitPlugin::client()->vcsExec( workingDirectory, {"branch", noColorOption, "-a", "--contains", revision}, nullptr, false, 0, workingDirectory); connect(command, &VcsCommand::stdOutText, this, [this](const QString &text) { @@ -375,7 +375,7 @@ QStringList GitDiffEditorController::addHeadWhenCommandInProgress() const // This is workaround for lack of support for merge commits and resolving conflicts, // we compare the current state of working tree to the HEAD of current branch // instead of showing unsupported combined diff format. - GitClient::CommandInProgress commandInProgress = GitPluginPrivate::client()->checkCommandInProgress(workingDirectory()); + GitClient::CommandInProgress commandInProgress = GitPlugin::client()->checkCommandInProgress(workingDirectory()); if (commandInProgress != GitClient::NoCommand) return {HEAD}; return QStringList(); @@ -478,7 +478,7 @@ public: setReloader([this] { m_state = GettingDescription; const QStringList args = {"show", "-s", noColorOption, showFormatC, m_id}; - runCommand({args}, GitPluginPrivate::client()->encoding(workingDirectory(), "i18n.commitEncoding")); + runCommand({args}, GitPlugin::client()->encoding(workingDirectory(), "i18n.commitEncoding")); setStartupFile(VcsBase::source(this->document())); }); } @@ -495,7 +495,7 @@ void ShowController::processCommandOutput(const QString &output) { QTC_ASSERT(m_state != Idle, return); if (m_state == GettingDescription) { - setDescription(GitPluginPrivate::client()->extendedShowDescription(workingDirectory(), output)); + setDescription(GitPlugin::client()->extendedShowDescription(workingDirectory(), output)); // stage 2 m_state = GettingDiff; const QStringList args = {"show", "--format=format:", // omit header, already generated @@ -634,14 +634,12 @@ private: { // If interactive rebase editor window is closed, plugin is terminated // but referenced here when the command ends - if (GitPluginPrivate *plugin = GitPluginPrivate::instance()) { - GitClient *client = plugin->client(); - if (m_commit.isEmpty() && m_files.isEmpty()) { - if (client->checkCommandInProgress(m_workingDirectory) == GitClient::NoCommand) - client->endStashScope(m_workingDirectory); - } else { - client->handleMergeConflicts(m_workingDirectory, m_commit, m_files, m_abortCommand); - } + GitClient *client = GitPlugin::client(); + if (m_commit.isEmpty() && m_files.isEmpty()) { + if (client->checkCommandInProgress(m_workingDirectory) == GitClient::NoCommand) + client->endStashScope(m_workingDirectory); + } else { + client->handleMergeConflicts(m_workingDirectory, m_commit, m_files, m_abortCommand); } } @@ -1267,7 +1265,7 @@ void GitClient::removeStaleRemoteBranches(const QString &workingDirectory, const VcsCommand::ShowSuccessMessage); connect(command, &VcsCommand::success, - this, [workingDirectory]() { GitPluginPrivate::instance()->updateBranches(workingDirectory); }); + this, [workingDirectory]() { GitPlugin::updateBranches(workingDirectory); }); } void GitClient::recoverDeletedFiles(const QString &workingDirectory) @@ -2220,7 +2218,7 @@ GitClient::CommandInProgress GitClient::checkCommandInProgress(const QString &wo void GitClient::continueCommandIfNeeded(const QString &workingDirectory, bool allowContinue) { - if (GitPluginPrivate::instance()->isCommitEditorOpen()) + if (GitPlugin::isCommitEditorOpen()) return; CommandInProgress command = checkCommandInProgress(workingDirectory); ContinueCommandMode continueMode; @@ -2293,7 +2291,7 @@ void GitClient::continuePreviousGitCommand(const QString &workingDirectory, if (isRebase) rebase(workingDirectory, QLatin1String(hasChanges ? "--continue" : "--skip")); else - GitPluginPrivate::instance()->startCommit(); + GitPlugin::startCommit(); } } @@ -2786,7 +2784,7 @@ bool GitClient::addAndCommit(const QString &repositoryDirectory, if (resp.result == SynchronousProcessResponse::Finished) { VcsOutputWindow::appendMessage(msgCommitted(amendSHA1, commitCount)); VcsOutputWindow::appendError(stdErr); - GitPluginPrivate::instance()->updateCurrentBranch(); + GitPlugin::updateCurrentBranch(); return true; } else { VcsOutputWindow::appendError(tr("Cannot commit %n files: %1\n", nullptr, commitCount).arg(stdErr)); @@ -2888,7 +2886,7 @@ void GitClient::revert(const QStringList &files, bool revertStaging) QString errorMessage; switch (revertI(files, &isDirectory, &errorMessage, revertStaging)) { case RevertOk: - emit GitPluginPrivate::instance()->filesChanged(files); + GitPlugin::emitFilesChanged(files); break; case RevertCanceled: break; @@ -2909,7 +2907,7 @@ void GitClient::fetch(const QString &workingDirectory, const QString &remote) VcsCommand *command = vcsExec(workingDirectory, arguments, nullptr, true, VcsCommand::ShowSuccessMessage); connect(command, &VcsCommand::success, - this, [workingDirectory]() { GitPluginPrivate::instance()->updateBranches(workingDirectory); }); + this, [workingDirectory] { GitPlugin::updateBranches(workingDirectory); }); } bool GitClient::executeAndHandleConflicts(const QString &workingDirectory, @@ -3123,7 +3121,7 @@ void GitClient::push(const QString &workingDirectory, const QStringList &pushArg QStringList({"push", "--force-with-lease"}) + pushArgs, nullptr, true, VcsCommand::ShowSuccessMessage); connect(rePushCommand, &VcsCommand::success, - this, []() { GitPluginPrivate::instance()->updateCurrentBranch(); }); + this, []() { GitPlugin::updateCurrentBranch(); }); } break; } @@ -3144,13 +3142,13 @@ void GitClient::push(const QString &workingDirectory, const QStringList &pushArg fallbackCommandParts.mid(1), nullptr, true, VcsCommand::ShowSuccessMessage); connect(rePushCommand, &VcsCommand::success, this, [workingDirectory]() { - GitPluginPrivate::instance()->updateBranches(workingDirectory); + GitPlugin::updateBranches(workingDirectory); }); } break; } } else { - GitPluginPrivate::instance()->updateCurrentBranch(); + GitPlugin::updateCurrentBranch(); } }); } @@ -3412,7 +3410,7 @@ bool GitClient::StashInfo::init(const QString &workingDirectory, const QString & m_pushAction = pushAction; QString errorMessage; QString statusOutput; - switch (GitPluginPrivate::client()->gitStatus(m_workingDir, StatusMode(NoUntracked | NoSubmodules), + switch (GitPlugin::client()->gitStatus(m_workingDir, StatusMode(NoUntracked | NoSubmodules), &statusOutput, &errorMessage)) { case GitClient::StatusChanged: if (m_flags & NoPrompt) @@ -3465,14 +3463,14 @@ void GitClient::StashInfo::stashPrompt(const QString &command, const QString &st msgBox.exec(); if (msgBox.clickedButton() == discardButton) { - m_stashResult = GitPluginPrivate::client()->synchronousReset(m_workingDir, QStringList(), errorMessage) ? + m_stashResult = GitPlugin::client()->synchronousReset(m_workingDir, QStringList(), errorMessage) ? StashUnchanged : StashFailed; } else if (msgBox.clickedButton() == ignoreButton) { // At your own risk, so. m_stashResult = NotStashed; } else if (msgBox.clickedButton() == cancelButton) { m_stashResult = StashCanceled; } else if (msgBox.clickedButton() == stashButton) { - const bool result = GitPluginPrivate::client()->executeSynchronousStash( + const bool result = GitPlugin::client()->executeSynchronousStash( m_workingDir, creatorStashMessage(command), false, errorMessage); m_stashResult = result ? StashUnchanged : StashFailed; } else if (msgBox.clickedButton() == stashAndPopButton) { @@ -3483,7 +3481,7 @@ void GitClient::StashInfo::stashPrompt(const QString &command, const QString &st void GitClient::StashInfo::executeStash(const QString &command, QString *errorMessage) { m_message = creatorStashMessage(command); - if (!GitPluginPrivate::client()->executeSynchronousStash(m_workingDir, m_message, false, errorMessage)) + if (!GitPlugin::client()->executeSynchronousStash(m_workingDir, m_message, false, errorMessage)) m_stashResult = StashFailed; else m_stashResult = Stashed; @@ -3506,14 +3504,14 @@ void GitClient::StashInfo::end() { if (m_stashResult == Stashed) { QString stashName; - if (GitPluginPrivate::client()->stashNameFromMessage(m_workingDir, m_message, &stashName)) - GitPluginPrivate::client()->stashPop(m_workingDir, stashName); + if (GitPlugin::client()->stashNameFromMessage(m_workingDir, m_message, &stashName)) + GitPlugin::client()->stashPop(m_workingDir, stashName); } if (m_pushAction == NormalPush) - GitPluginPrivate::client()->push(m_workingDir); + GitPlugin::client()->push(m_workingDir); else if (m_pushAction == PushToGerrit) - GitPluginPrivate::instance()->gerritPlugin()->push(m_workingDir); + GitPlugin::gerritPush(m_workingDir); m_pushAction = NoPush; m_stashResult = NotStashed; diff --git a/src/plugins/git/giteditor.cpp b/src/plugins/git/giteditor.cpp index 53b41479e69..78b8389da18 100644 --- a/src/plugins/git/giteditor.cpp +++ b/src/plugins/git/giteditor.cpp @@ -126,7 +126,7 @@ static QString sanitizeBlameOutput(const QString &b) if (b.isEmpty()) return b; - const bool omitDate = GitPluginPrivate::client()->settings().boolValue( + const bool omitDate = GitPlugin::client()->settings().boolValue( GitSettings::omitAnnotationDateKey); const QChar space(' '); const int parenPos = b.indexOf(')'); @@ -192,7 +192,7 @@ void GitEditorWidget::setPlainText(const QString &text) void GitEditorWidget::resetChange(const QByteArray &resetType) { - GitPluginPrivate::client()->reset( + GitPlugin::client()->reset( sourceWorkingDirectory(), QLatin1String("--" + resetType), m_currentChange); } @@ -211,7 +211,7 @@ void GitEditorWidget::applyDiffChunk(const DiffChunk& chunk, bool revert) if (revert) args << "--reverse"; QString errorMessage; - if (GitPluginPrivate::client()->synchronousApplyPatch(baseDir, patchFile.fileName(), &errorMessage, args)) { + if (GitPlugin::client()->synchronousApplyPatch(baseDir, patchFile.fileName(), &errorMessage, args)) { if (errorMessage.isEmpty()) VcsOutputWindow::append(tr("Chunk successfully staged")); else @@ -260,14 +260,14 @@ void GitEditorWidget::aboutToOpen(const QString &fileName, const QString &realFi const QString gitPath = fi.absolutePath(); setSource(gitPath); textDocument()->setCodec( - GitPluginPrivate::client()->encoding(gitPath, "i18n.commitEncoding")); + GitPlugin::client()->encoding(gitPath, "i18n.commitEncoding")); } } QString GitEditorWidget::decorateVersion(const QString &revision) const { // Format verbose, SHA1 being first token - return GitPluginPrivate::client()->synchronousShortDescription(sourceWorkingDirectory(), revision); + return GitPlugin::client()->synchronousShortDescription(sourceWorkingDirectory(), revision); } QStringList GitEditorWidget::annotationPreviousVersions(const QString &revision) const @@ -275,7 +275,7 @@ QStringList GitEditorWidget::annotationPreviousVersions(const QString &revision) QStringList revisions; QString errorMessage; // Get the SHA1's of the file. - if (!GitPluginPrivate::client()->synchronousParentRevisions(sourceWorkingDirectory(), + if (!GitPlugin::client()->synchronousParentRevisions(sourceWorkingDirectory(), revision, &revisions, &errorMessage)) { VcsOutputWindow::appendSilently(errorMessage); return QStringList(); @@ -285,7 +285,7 @@ QStringList GitEditorWidget::annotationPreviousVersions(const QString &revision) bool GitEditorWidget::isValidRevision(const QString &revision) const { - return GitPluginPrivate::client()->isValidRevision(revision); + return GitPlugin::client()->isValidRevision(revision); } void GitEditorWidget::addChangeActions(QMenu *menu, const QString &change) @@ -295,25 +295,25 @@ void GitEditorWidget::addChangeActions(QMenu *menu, const QString &change) return; menu->addAction(tr("Cherr&y-Pick Change %1").arg(change), this, [this] { - GitPluginPrivate::client()->synchronousCherryPick(sourceWorkingDirectory(), m_currentChange); + GitPlugin::client()->synchronousCherryPick(sourceWorkingDirectory(), m_currentChange); }); menu->addAction(tr("Re&vert Change %1").arg(change), this, [this] { - GitPluginPrivate::client()->synchronousRevert(sourceWorkingDirectory(), m_currentChange); + GitPlugin::client()->synchronousRevert(sourceWorkingDirectory(), m_currentChange); }); menu->addAction(tr("C&heckout Change %1").arg(change), this, [this] { - GitPluginPrivate::client()->checkout(sourceWorkingDirectory(), m_currentChange); + GitPlugin::client()->checkout(sourceWorkingDirectory(), m_currentChange); }); connect(menu->addAction(tr("&Interactive Rebase from Change %1...").arg(change)), &QAction::triggered, this, [this] { - GitPluginPrivate::instance()->startRebaseFromCommit(sourceWorkingDirectory(), m_currentChange); + GitPlugin::startRebaseFromCommit(sourceWorkingDirectory(), m_currentChange); }); menu->addAction(tr("&Log for Change %1").arg(change), this, [this] { - GitPluginPrivate::client()->log(sourceWorkingDirectory(), QString(), false, {m_currentChange}); + GitPlugin::client()->log(sourceWorkingDirectory(), QString(), false, {m_currentChange}); }); menu->addAction(tr("Add &Tag for Change %1...").arg(change), this, [this] { QString output; QString errorMessage; - GitPluginPrivate::client()->synchronousTagCmd(sourceWorkingDirectory(), QStringList(), + GitPlugin::client()->synchronousTagCmd(sourceWorkingDirectory(), QStringList(), &output, &errorMessage); const QStringList tags = output.split('\n'); @@ -322,7 +322,7 @@ void GitEditorWidget::addChangeActions(QMenu *menu, const QString &change) if (dialog.exec() == QDialog::Rejected) return; - GitPluginPrivate::client()->synchronousTagCmd(sourceWorkingDirectory(), + GitPlugin::client()->synchronousTagCmd(sourceWorkingDirectory(), {dialog.branchName(), m_currentChange}, &output, &errorMessage); VcsOutputWindow::append(output); diff --git a/src/plugins/git/gitgrep.cpp b/src/plugins/git/gitgrep.cpp index 35fd7abc649..056903f855e 100644 --- a/src/plugins/git/gitgrep.cpp +++ b/src/plugins/git/gitgrep.cpp @@ -158,7 +158,7 @@ public: void exec() { - GitClient *client = GitPluginPrivate::client(); + GitClient *client = GitPlugin::client(); QStringList arguments = { "-c", "color.grep.match=bold red", "-c", "color.grep=always", @@ -248,7 +248,7 @@ GitGrep::GitGrep(QObject *parent) const QRegularExpression refExpression("[\\S]*"); m_treeLineEdit->setValidator(new QRegularExpressionValidator(refExpression, this)); layout->addWidget(m_treeLineEdit); - if (GitPluginPrivate::client()->gitVersion() >= 0x021300) { + if (GitPlugin::client()->gitVersion() >= 0x021300) { m_recurseSubmodules = new QCheckBox(tr("Recurse submodules")); layout->addWidget(m_recurseSubmodules); } @@ -320,7 +320,7 @@ IEditor *GitGrep::openEditor(const SearchResultItem &item, QByteArray content; const QString topLevel = parameters.additionalParameters.toString(); const QString relativePath = QDir(topLevel).relativeFilePath(path); - if (!GitPluginPrivate::client()->synchronousShow(topLevel, params.ref + ":./" + relativePath, + if (!GitPlugin::client()->synchronousShow(topLevel, params.ref + ":./" + relativePath, &content, nullptr)) { return nullptr; } diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index c733225429c..b676d2faf11 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -74,6 +74,7 @@ #include #include #include +#include #include #include @@ -98,6 +99,8 @@ using namespace VcsBase; namespace Git { namespace Internal { +using GitClientMemberFunc = void (GitClient::*)(const QString &); + class GitTopicCache : public Core::IVersionControl::TopicCache { public: @@ -150,6 +153,166 @@ const VcsBaseEditorParameters editorParameters[] = { // GitPlugin +class GitPluginPrivate final : public VcsBase::VcsBasePluginPrivate +{ + Q_OBJECT + +public: + GitPluginPrivate(); + ~GitPluginPrivate() final; + + // IVersionControl + QString displayName() const final; + Core::Id id() const final; + + bool isVcsFileOrDirectory(const Utils::FilePath &fileName) const final; + + bool managesDirectory(const QString &directory, QString *topLevel) const final; + bool managesFile(const QString &workingDirectory, const QString &fileName) const final; + QStringList unmanagedFiles(const QString &workingDir, const QStringList &filePaths) const final; + + bool isConfigured() const final; + bool supportsOperation(Operation operation) const final; + bool vcsOpen(const QString &fileName) final; + bool vcsAdd(const QString &fileName) final; + bool vcsDelete(const QString &filename) final; + bool vcsMove(const QString &from, const QString &to) final; + bool vcsCreateRepository(const QString &directory) final; + + bool vcsAnnotate(const QString &file, int line) final; + QString vcsTopic(const QString &directory) final; + + Core::ShellCommand *createInitialCheckoutCommand(const QString &url, + const Utils::FilePath &baseDirectory, + const QString &localName, + const QStringList &extraArgs) final; + + RepoUrl getRepoUrl(const QString &location) const override; + + QStringList additionalToolsPath() const final; + + bool isCommitEditorOpen() const; + void startCommit(CommitType commitType = SimpleCommit); + void updateBranches(const QString &repository); + void updateCurrentBranch(); + + void manageRemotes(); + void initRepository(); + void startRebaseFromCommit(const QString &workingDirectory, QString commit); + + void updateActions(VcsBase::VcsBasePluginPrivate::ActionState) override; + bool submitEditorAboutToClose() override; + + void diffCurrentFile(); + void diffCurrentProject(); + void commitFromEditor() override; + void logFile(); + void blameFile(); + void logProject(); + void logRepository(); + void undoFileChanges(bool revertStaging); + void resetRepository(); + void recoverDeletedFiles(); + void startRebase(); + void startChangeRelatedAction(const Core::Id &id); + void stageFile(); + void unstageFile(); + void gitkForCurrentFile(); + void gitkForCurrentFolder(); + void gitGui(); + void cleanProject(); + void cleanRepository(); + void updateSubmodules(); + void applyCurrentFilePatch(); + void promptApplyPatch(); + + void stash(bool unstagedOnly = false); + void stashUnstaged(); + void stashSnapshot(); + void stashPop(); + void branchList(); + void stashList(); + void fetch(); + void pull(); + void push(); + void startMergeTool(); + void continueOrAbortCommand(); + void updateContinueAndAbortCommands(); + void delayedPushToGerrit(); + + Core::Command *createCommand(QAction *action, Core::ActionContainer *ac, Core::Id id, + const Core::Context &context, bool addToLocator, + const std::function &callback, const QKeySequence &keys); + + Utils::ParameterAction *createParameterAction(Core::ActionContainer *ac, + const QString &defaultText, const QString ¶meterText, + Core::Id id, const Core::Context &context, bool addToLocator, + const std::function &callback, + const QKeySequence &keys = QKeySequence()); + + QAction *createFileAction(Core::ActionContainer *ac, + const QString &defaultText, const QString ¶meterText, + Core::Id id, const Core::Context &context, bool addToLocator, + const std::function &callback, + const QKeySequence &keys = QKeySequence()); + + QAction *createProjectAction(Core::ActionContainer *ac, + const QString &defaultText, const QString ¶meterText, + Core::Id id, const Core::Context &context, bool addToLocator, + void (GitPluginPrivate::*func)(), + const QKeySequence &keys = QKeySequence()); + + QAction *createRepositoryAction(Core::ActionContainer *ac, const QString &text, Core::Id id, + const Core::Context &context, bool addToLocator, + const std::function &callback, + const QKeySequence &keys = QKeySequence()); + QAction *createRepositoryAction(Core::ActionContainer *ac, const QString &text, Core::Id id, + const Core::Context &context, bool addToLocator, + GitClientMemberFunc, const QKeySequence &keys = QKeySequence()); + + QAction *createChangeRelatedRepositoryAction(const QString &text, Core::Id id, + const Core::Context &context); + + void updateRepositoryBrowserAction(); + Core::IEditor *openSubmitEditor(const QString &fileName, const CommitData &cd); + void cleanCommitMessageFile(); + void cleanRepository(const QString &directory); + void applyPatch(const QString &workingDirectory, QString file = QString()); + void updateVersionWarning(); + + Core::CommandLocator *m_commandLocator = nullptr; + + QAction *m_menuAction = nullptr; + QAction *m_repositoryBrowserAction = nullptr; + QAction *m_mergeToolAction = nullptr; + QAction *m_submoduleUpdateAction = nullptr; + QAction *m_abortMergeAction = nullptr; + QAction *m_abortRebaseAction = nullptr; + QAction *m_abortCherryPickAction = nullptr; + QAction *m_abortRevertAction = nullptr; + QAction *m_skipRebaseAction = nullptr; + QAction *m_continueRebaseAction = nullptr; + QAction *m_continueCherryPickAction = nullptr; + QAction *m_continueRevertAction = nullptr; + QAction *m_fixupCommitAction = nullptr; + QAction *m_interactiveRebaseAction = nullptr; + + QVector m_fileActions; + QVector m_projectActions; + QVector m_repositoryActions; + Utils::ParameterAction *m_applyCurrentFilePatchAction = nullptr; + Gerrit::Internal::GerritPlugin *m_gerritPlugin = nullptr; + + GitSettings m_settings; + GitClient *m_gitClient = nullptr; + QPointer m_stashDialog; + QPointer m_branchViewFactory; + QPointer m_remoteDialog; + QString m_submitRepository; + QString m_commitMessageFileName; + bool m_submitActionTriggered = false; +}; + static GitPluginPrivate *dd = nullptr; GitPluginPrivate::~GitPluginPrivate() @@ -178,17 +341,27 @@ bool GitPluginPrivate::isCommitEditorOpen() const return !m_commitMessageFileName.isEmpty(); } -GitPluginPrivate *GitPluginPrivate::instance() -{ - return dd; -} - -GitClient *GitPluginPrivate::client() +GitClient *GitPlugin::client() { return dd->m_gitClient; } -QString GitPluginPrivate::msgRepositoryLabel(const QString &repository) +IVersionControl *GitPlugin::versionControl() +{ + return dd; +} + +const GitSettings &GitPlugin::settings() +{ + return dd->m_settings; +} + +const VcsBasePluginState &GitPlugin::currentState() +{ + return dd->currentState(); +} + +QString GitPlugin::msgRepositoryLabel(const QString &repository) { return repository.isEmpty() ? tr("") : @@ -197,7 +370,7 @@ QString GitPluginPrivate::msgRepositoryLabel(const QString &repository) // Returns a regular expression pattern with characters not allowed // in branch and remote names. -QString GitPluginPrivate::invalidBranchAndRemoteNamePattern() +QString GitPlugin::invalidBranchAndRemoteNamePattern() { return QLatin1String( "\\s" // no whitespace @@ -1473,11 +1646,11 @@ void GitPluginPrivate::updateCurrentBranch() QObject *GitPlugin::remoteCommand(const QStringList &options, const QString &workingDirectory, const QStringList &) { - if (!GitPluginPrivate::client() || options.size() < 2) + if (!GitPlugin::client() || options.size() < 2) return nullptr; if (options.first() == "-git-show") - GitPluginPrivate::client()->show(workingDirectory, options.at(1)); + GitPlugin::client()->show(workingDirectory, options.at(1)); return nullptr; } @@ -1489,11 +1662,6 @@ void GitPluginPrivate::updateRepositoryBrowserAction() m_repositoryBrowserAction->setEnabled(repositoryEnabled && hasRepositoryBrowserCmd); } -Gerrit::Internal::GerritPlugin *GitPluginPrivate::gerritPlugin() const -{ - return m_gerritPlugin; -} - QString GitPluginPrivate::displayName() const { return QLatin1String("Git"); @@ -1631,14 +1799,54 @@ bool GitPluginPrivate::vcsAnnotate(const QString &file, int line) return true; } -void GitPluginPrivate::emitFilesChanged(const QStringList &l) +void GitPlugin::emitFilesChanged(const QStringList &l) { - emit filesChanged(l); + emit dd->filesChanged(l); } -void GitPluginPrivate::emitRepositoryChanged(const QString &r) +void GitPlugin::emitRepositoryChanged(const QString &r) { - emit repositoryChanged(r); + emit dd->repositoryChanged(r); +} + +void GitPlugin::startRebaseFromCommit(const QString &workingDirectory, const QString &commit) +{ + dd->startRebaseFromCommit(workingDirectory, commit); +} + +void GitPlugin::manageRemotes() +{ + dd->manageRemotes(); +} + +void GitPlugin::initRepository() +{ + dd->initRepository(); +} + +void GitPlugin::startCommit() +{ + dd->startCommit(); +} + +void GitPlugin::updateCurrentBranch() +{ + dd->updateCurrentBranch(); +} + +void GitPlugin::updateBranches(const QString &repository) +{ + dd->updateBranches(repository); +} + +void GitPlugin::gerritPush(const QString &topLevel) +{ + dd->m_gerritPlugin->push(topLevel); +} + +bool GitPlugin::isCommitEditorOpen() +{ + return dd->isCommitEditorOpen(); } #ifdef WITH_TESTS @@ -1873,3 +2081,5 @@ void GitPlugin::testGitRemote() } // namespace Internal } // namespace Git + +#include "gitplugin.moc" diff --git a/src/plugins/git/gitplugin.h b/src/plugins/git/gitplugin.h index 5e33f45718c..6bd13532c7d 100644 --- a/src/plugins/git/gitplugin.h +++ b/src/plugins/git/gitplugin.h @@ -28,215 +28,20 @@ #include "gitsettings.h" #include +#include -#include - -#include -#include -#include -#include +#include #include -QT_BEGIN_NAMESPACE -class QAction; -QT_END_NAMESPACE +#include -namespace Core { -class IEditor; -class Command; -class CommandLocator; -class Context; -class ActionContainer; -} // namespace Core -namespace Utils { class ParameterAction; } -namespace Gerrit { -namespace Internal { class GerritPlugin; } -} // namespace Gerrit +namespace VcsBase { class VcsBasePluginState; } namespace Git { namespace Internal { class GitClient; -class CommitData; -class StashDialog; -class BranchDialog; -class BranchViewFactory; -class RemoteDialog; - -using GitClientMemberFunc = void (GitClient::*)(const QString &); - -class GitPluginPrivate final : public VcsBase::VcsBasePluginPrivate -{ - Q_OBJECT - -public: - GitPluginPrivate(); - ~GitPluginPrivate() final; - - // IVersionControl - QString displayName() const final; - Core::Id id() const final; - - bool isVcsFileOrDirectory(const Utils::FilePath &fileName) const final; - - bool managesDirectory(const QString &directory, QString *topLevel) const final; - bool managesFile(const QString &workingDirectory, const QString &fileName) const final; - QStringList unmanagedFiles(const QString &workingDir, const QStringList &filePaths) const final; - - bool isConfigured() const final; - bool supportsOperation(Operation operation) const final; - bool vcsOpen(const QString &fileName) final; - bool vcsAdd(const QString &fileName) final; - bool vcsDelete(const QString &filename) final; - bool vcsMove(const QString &from, const QString &to) final; - bool vcsCreateRepository(const QString &directory) final; - - bool vcsAnnotate(const QString &file, int line) final; - QString vcsTopic(const QString &directory) final; - - Core::ShellCommand *createInitialCheckoutCommand(const QString &url, - const Utils::FilePath &baseDirectory, - const QString &localName, - const QStringList &extraArgs) final; - - RepoUrl getRepoUrl(const QString &location) const override; - - QStringList additionalToolsPath() const final; - - void emitFilesChanged(const QStringList &); - void emitRepositoryChanged(const QString &); - - /// - static GitPluginPrivate *instance(); - static GitClient *client(); - - Gerrit::Internal::GerritPlugin *gerritPlugin() const; - bool isCommitEditorOpen() const; - static QString msgRepositoryLabel(const QString &repository); - static QString invalidBranchAndRemoteNamePattern(); - void startCommit(CommitType commitType = SimpleCommit); - void updateBranches(const QString &repository); - void updateCurrentBranch(); - - void manageRemotes(); - void initRepository(); - void startRebaseFromCommit(const QString &workingDirectory, QString commit); - -protected: - void updateActions(VcsBase::VcsBasePluginPrivate::ActionState) override; - bool submitEditorAboutToClose() override; - -private: - void diffCurrentFile(); - void diffCurrentProject(); - void commitFromEditor() override; - void logFile(); - void blameFile(); - void logProject(); - void logRepository(); - void undoFileChanges(bool revertStaging); - void resetRepository(); - void recoverDeletedFiles(); - void startRebase(); - void startChangeRelatedAction(const Core::Id &id); - void stageFile(); - void unstageFile(); - void gitkForCurrentFile(); - void gitkForCurrentFolder(); - void gitGui(); - void cleanProject(); - void cleanRepository(); - void updateSubmodules(); - void applyCurrentFilePatch(); - void promptApplyPatch(); - - void stash(bool unstagedOnly = false); - void stashUnstaged(); - void stashSnapshot(); - void stashPop(); - void branchList(); - void stashList(); - void fetch(); - void pull(); - void push(); - void startMergeTool(); - void continueOrAbortCommand(); - void updateContinueAndAbortCommands(); - void delayedPushToGerrit(); - - Core::Command *createCommand(QAction *action, Core::ActionContainer *ac, Core::Id id, - const Core::Context &context, bool addToLocator, - const std::function &callback, const QKeySequence &keys); - - Utils::ParameterAction *createParameterAction(Core::ActionContainer *ac, - const QString &defaultText, const QString ¶meterText, - Core::Id id, const Core::Context &context, bool addToLocator, - const std::function &callback, - const QKeySequence &keys = QKeySequence()); - - QAction *createFileAction(Core::ActionContainer *ac, - const QString &defaultText, const QString ¶meterText, - Core::Id id, const Core::Context &context, bool addToLocator, - const std::function &callback, - const QKeySequence &keys = QKeySequence()); - - QAction *createProjectAction(Core::ActionContainer *ac, - const QString &defaultText, const QString ¶meterText, - Core::Id id, const Core::Context &context, bool addToLocator, - void (GitPluginPrivate::*func)(), - const QKeySequence &keys = QKeySequence()); - - QAction *createRepositoryAction(Core::ActionContainer *ac, const QString &text, Core::Id id, - const Core::Context &context, bool addToLocator, - const std::function &callback, - const QKeySequence &keys = QKeySequence()); - QAction *createRepositoryAction(Core::ActionContainer *ac, const QString &text, Core::Id id, - const Core::Context &context, bool addToLocator, - GitClientMemberFunc, const QKeySequence &keys = QKeySequence()); - - QAction *createChangeRelatedRepositoryAction(const QString &text, Core::Id id, - const Core::Context &context); - - void updateRepositoryBrowserAction(); - Core::IEditor *openSubmitEditor(const QString &fileName, const CommitData &cd); - void cleanCommitMessageFile(); - void cleanRepository(const QString &directory); - void applyPatch(const QString &workingDirectory, QString file = QString()); - void updateVersionWarning(); - - Core::CommandLocator *m_commandLocator = nullptr; - - QAction *m_menuAction = nullptr; - QAction *m_repositoryBrowserAction = nullptr; - QAction *m_mergeToolAction = nullptr; - QAction *m_submoduleUpdateAction = nullptr; - QAction *m_abortMergeAction = nullptr; - QAction *m_abortRebaseAction = nullptr; - QAction *m_abortCherryPickAction = nullptr; - QAction *m_abortRevertAction = nullptr; - QAction *m_skipRebaseAction = nullptr; - QAction *m_continueRebaseAction = nullptr; - QAction *m_continueCherryPickAction = nullptr; - QAction *m_continueRevertAction = nullptr; - QAction *m_fixupCommitAction = nullptr; - QAction *m_interactiveRebaseAction = nullptr; - - QVector m_fileActions; - QVector m_projectActions; - QVector m_repositoryActions; - Utils::ParameterAction *m_applyCurrentFilePatchAction = nullptr; - Gerrit::Internal::GerritPlugin *m_gerritPlugin = nullptr; - - GitSettings m_settings; - GitClient *m_gitClient = nullptr; - QPointer m_stashDialog; - QPointer m_branchViewFactory; - QPointer m_remoteDialog; - QString m_submitRepository; - QString m_commitMessageFileName; - bool m_submitActionTriggered = false; -}; class GitPlugin final : public ExtensionSystem::IPlugin { @@ -252,6 +57,25 @@ public: QObject *remoteCommand(const QStringList &options, const QString &workingDirectory, const QStringList &args) final; + static GitClient *client(); + static Core::IVersionControl *versionControl(); + static const GitSettings &settings(); + static const VcsBase::VcsBasePluginState ¤tState(); + + static QString msgRepositoryLabel(const QString &repository); + static QString invalidBranchAndRemoteNamePattern(); + static bool isCommitEditorOpen(); + + static void emitFilesChanged(const QStringList &); + static void emitRepositoryChanged(const QString &); + static void startRebaseFromCommit(const QString &workingDirectory, const QString &commit); + static void manageRemotes(); + static void initRepository(); + static void startCommit(); + static void updateCurrentBranch(); + static void updateBranches(const QString &repository); + static void gerritPush(const QString &topLevel); + #ifdef WITH_TESTS private slots: void testStatusParsing_data(); diff --git a/src/plugins/git/gitsubmiteditor.cpp b/src/plugins/git/gitsubmiteditor.cpp index 726ce80c250..35f7892dd65 100644 --- a/src/plugins/git/gitsubmiteditor.cpp +++ b/src/plugins/git/gitsubmiteditor.cpp @@ -88,7 +88,7 @@ CommitDataFetchResult CommitDataFetchResult::fetch(CommitType commitType, const CommitDataFetchResult result; result.commitData.commitType = commitType; QString commitTemplate; - result.success = GitPluginPrivate::client()->getCommitData(workingDirectory, &commitTemplate, + result.success = GitPlugin::client()->getCommitData(workingDirectory, &commitTemplate, result.commitData, &result.errorMessage); return result; } @@ -103,7 +103,7 @@ GitSubmitEditor::GitSubmitEditor() : { connect(this, &VcsBaseSubmitEditor::diffSelectedRows, this, &GitSubmitEditor::slotDiffSelected); connect(submitEditorWidget(), &GitSubmitEditorWidget::show, this, &GitSubmitEditor::showCommit); - connect(GitPluginPrivate::instance(), &Core::IVersionControl::repositoryChanged, + connect(GitPlugin::versionControl(), &Core::IVersionControl::repositoryChanged, this, &GitSubmitEditor::forceUpdateFileModel); connect(&m_fetchWatcher, &QFutureWatcher::finished, this, &GitSubmitEditor::commitDataRetrieved); @@ -202,15 +202,15 @@ void GitSubmitEditor::slotDiffSelected(const QList &rows) } } if (!unstagedFiles.empty() || !stagedFiles.empty()) - GitPluginPrivate::client()->diffFiles(m_workingDirectory, unstagedFiles, stagedFiles); + GitPlugin::client()->diffFiles(m_workingDirectory, unstagedFiles, stagedFiles); if (!unmergedFiles.empty()) - GitPluginPrivate::client()->merge(m_workingDirectory, unmergedFiles); + GitPlugin::client()->merge(m_workingDirectory, unmergedFiles); } void GitSubmitEditor::showCommit(const QString &commit) { if (!m_workingDirectory.isEmpty()) - GitPluginPrivate::client()->show(m_workingDirectory, commit); + GitPlugin::client()->show(m_workingDirectory, commit); } void GitSubmitEditor::updateFileModel() @@ -230,7 +230,7 @@ void GitSubmitEditor::updateFileModel() Core::ProgressManager::addTask(m_fetchWatcher.future(), tr("Refreshing Commit Data"), TASK_UPDATE_COMMIT); - GitPluginPrivate::client()->addFuture(m_fetchWatcher.future()); + GitPlugin::client()->addFuture(m_fetchWatcher.future()); } void GitSubmitEditor::forceUpdateFileModel() diff --git a/src/plugins/git/logchangedialog.cpp b/src/plugins/git/logchangedialog.cpp index 93186c01e1f..e57dda49e0f 100644 --- a/src/plugins/git/logchangedialog.cpp +++ b/src/plugins/git/logchangedialog.cpp @@ -79,7 +79,7 @@ bool LogChangeWidget::init(const QString &repository, const QString &commit, Log return true; if (!(flags & Silent)) { VcsOutputWindow::appendError( - GitPluginPrivate::client()->msgNoCommits(flags & IncludeRemotes)); + GitPlugin::client()->msgNoCommits(flags & IncludeRemotes)); } return false; } @@ -159,7 +159,7 @@ bool LogChangeWidget::populateLog(const QString &repository, const QString &comm arguments << "--not" << "--remotes"; arguments << "--"; QString output; - if (!GitPluginPrivate::client()->synchronousLog(repository, arguments, &output, nullptr, VcsCommand::NoOutput)) + if (!GitPlugin::client()->synchronousLog(repository, arguments, &output, nullptr, VcsCommand::NoOutput)) return false; const QStringList lines = output.split('\n'); for (const QString &line : lines) { @@ -211,7 +211,7 @@ LogChangeDialog::LogChangeDialog(bool isReset, QWidget *parent) : m_resetTypeComboBox->addItem(tr("Hard"), "--hard"); m_resetTypeComboBox->addItem(tr("Mixed"), "--mixed"); m_resetTypeComboBox->addItem(tr("Soft"), "--soft"); - m_resetTypeComboBox->setCurrentIndex(GitPluginPrivate::client()->settings().intValue( + m_resetTypeComboBox->setCurrentIndex(GitPlugin::client()->settings().intValue( GitSettings::lastResetIndexKey)); popUpLayout->addWidget(m_resetTypeComboBox); popUpLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored)); @@ -240,7 +240,7 @@ bool LogChangeDialog::runDialog(const QString &repository, if (QDialog::exec() == QDialog::Accepted) { if (m_resetTypeComboBox) { - GitPluginPrivate::client()->settings().setValue(GitSettings::lastResetIndexKey, + GitPlugin::client()->settings().setValue(GitSettings::lastResetIndexKey, m_resetTypeComboBox->currentIndex()); } return true; diff --git a/src/plugins/git/mergetool.cpp b/src/plugins/git/mergetool.cpp index c73f10e3963..d951200784c 100644 --- a/src/plugins/git/mergetool.cpp +++ b/src/plugins/git/mergetool.cpp @@ -60,7 +60,7 @@ bool MergeTool::start(const QString &workingDirectory, const QStringList &files) m_process->setWorkingDirectory(workingDirectory); m_process->setProcessEnvironment(env); m_process->setProcessChannelMode(QProcess::MergedChannels); - const Utils::FilePath binary = GitPluginPrivate::client()->vcsBinary(); + const Utils::FilePath binary = GitPlugin::client()->vcsBinary(); VcsOutputWindow::appendCommand(workingDirectory, {binary, arguments}); m_process->start(binary.toString(), arguments); if (m_process->waitForStarted()) { @@ -263,8 +263,8 @@ void MergeTool::done() VcsOutputWindow::appendError(tr("Merge tool process terminated with exit code %1") .arg(exitCode)); } - GitPluginPrivate::client()->continueCommandIfNeeded(workingDirectory, exitCode == 0); - GitPluginPrivate::instance()->emitRepositoryChanged(workingDirectory); + GitPlugin::client()->continueCommandIfNeeded(workingDirectory, exitCode == 0); + GitPlugin::emitRepositoryChanged(workingDirectory); deleteLater(); } diff --git a/src/plugins/git/remotedialog.cpp b/src/plugins/git/remotedialog.cpp index 47432b05e55..50b7a994f24 100644 --- a/src/plugins/git/remotedialog.cpp +++ b/src/plugins/git/remotedialog.cpp @@ -49,7 +49,7 @@ class RemoteAdditionDialog : public QDialog { public: RemoteAdditionDialog(const QStringList &remoteNames) : - m_invalidRemoteNameChars(GitPluginPrivate::invalidBranchAndRemoteNamePattern()), + m_invalidRemoteNameChars(GitPlugin::invalidBranchAndRemoteNamePattern()), m_remoteNames(remoteNames) { m_ui.setupUi(this); @@ -157,7 +157,7 @@ void RemoteDialog::refresh(const QString &repository, bool force) if (m_remoteModel->workingDirectory() == repository && !force) return; // Refresh - m_ui->repositoryLabel->setText(GitPluginPrivate::msgRepositoryLabel(repository)); + m_ui->repositoryLabel->setText(GitPlugin::msgRepositoryLabel(repository)); if (repository.isEmpty()) { m_remoteModel->clear(); } else { @@ -205,7 +205,7 @@ void RemoteDialog::pushToRemote() const int row = indexList.at(0).row(); const QString remoteName = m_remoteModel->remoteName(row); - GitPluginPrivate::client()->push(m_remoteModel->workingDirectory(), {remoteName}); + GitPlugin::client()->push(m_remoteModel->workingDirectory(), {remoteName}); } void RemoteDialog::fetchFromRemote() @@ -216,7 +216,7 @@ void RemoteDialog::fetchFromRemote() int row = indexList.at(0).row(); const QString remoteName = m_remoteModel->remoteName(row); - GitPluginPrivate::client()->fetch(m_remoteModel->workingDirectory(), remoteName); + GitPlugin::client()->fetch(m_remoteModel->workingDirectory(), remoteName); } void RemoteDialog::updateButtonState() diff --git a/src/plugins/git/remotemodel.cpp b/src/plugins/git/remotemodel.cpp index 69b9eb11ae2..0a0f30c1b4e 100644 --- a/src/plugins/git/remotemodel.cpp +++ b/src/plugins/git/remotemodel.cpp @@ -55,7 +55,7 @@ bool RemoteModel::removeRemote(int row) { QString output; QString error; - bool success = GitPluginPrivate::client()->synchronousRemoteCmd( + bool success = GitPlugin::client()->synchronousRemoteCmd( m_workingDirectory, {"rm", remoteName(row)}, &output, &error); if (success) success = refresh(m_workingDirectory, &error); @@ -69,7 +69,7 @@ bool RemoteModel::addRemote(const QString &name, const QString &url) if (name.isEmpty() || url.isEmpty()) return false; - bool success = GitPluginPrivate::client()->synchronousRemoteCmd( + bool success = GitPlugin::client()->synchronousRemoteCmd( m_workingDirectory, {"add", name, url}, &output, &error); if (success) success = refresh(m_workingDirectory, &error); @@ -80,7 +80,7 @@ bool RemoteModel::renameRemote(const QString &oldName, const QString &newName) { QString output; QString error; - bool success = GitPluginPrivate::client()->synchronousRemoteCmd( + bool success = GitPlugin::client()->synchronousRemoteCmd( m_workingDirectory, {"rename", oldName, newName}, &output, &error); if (success) success = refresh(m_workingDirectory, &error); @@ -91,7 +91,7 @@ bool RemoteModel::updateUrl(const QString &name, const QString &newUrl) { QString output; QString error; - bool success = GitPluginPrivate::client()->synchronousRemoteCmd( + bool success = GitPlugin::client()->synchronousRemoteCmd( m_workingDirectory, {"set-url", name, newUrl}, &output, &error); if (success) success = refresh(m_workingDirectory, &error); @@ -186,7 +186,7 @@ bool RemoteModel::refresh(const QString &workingDirectory, QString *errorMessage // get list of remotes. QMap remotesList - = GitPluginPrivate::client()->synchronousRemotesList(workingDirectory, errorMessage); + = GitPlugin::client()->synchronousRemotesList(workingDirectory, errorMessage); beginResetModel(); m_remotes.clear(); diff --git a/src/plugins/git/stashdialog.cpp b/src/plugins/git/stashdialog.cpp index 9ecb77168de..e20cb6dcc89 100644 --- a/src/plugins/git/stashdialog.cpp +++ b/src/plugins/git/stashdialog.cpp @@ -157,12 +157,12 @@ void StashDialog::refresh(const QString &repository, bool force) return; // Refresh m_repository = repository; - ui->repositoryLabel->setText(GitPluginPrivate::msgRepositoryLabel(repository)); + ui->repositoryLabel->setText(GitPlugin::msgRepositoryLabel(repository)); if (m_repository.isEmpty()) { m_model->setStashes(QList()); } else { QList stashes; - GitPluginPrivate::client()->synchronousStashList(m_repository, &stashes); + GitPlugin::client()->synchronousStashList(m_repository, &stashes); m_model->setStashes(stashes); if (!stashes.isEmpty()) { for (int c = 0; c < ColumnCount; c++) @@ -178,7 +178,7 @@ void StashDialog::deleteAll() if (!ask(title, tr("Do you want to delete all stashes?"))) return; QString errorMessage; - if (GitPluginPrivate::client()->synchronousStashRemove(m_repository, QString(), &errorMessage)) + if (GitPlugin::client()->synchronousStashRemove(m_repository, QString(), &errorMessage)) refresh(m_repository, true); else warning(title, errorMessage); @@ -195,7 +195,7 @@ void StashDialog::deleteSelection() QStringList errors; // Delete in reverse order as stashes rotate for (int r = rows.size() - 1; r >= 0; r--) - if (!GitPluginPrivate::client()->synchronousStashRemove(m_repository, m_model->at(rows.at(r)).name, &errorMessage)) + if (!GitPlugin::client()->synchronousStashRemove(m_repository, m_model->at(rows.at(r)).name, &errorMessage)) errors.push_back(errorMessage); refresh(m_repository, true); if (!errors.isEmpty()) @@ -206,7 +206,7 @@ void StashDialog::showCurrent() { const int index = currentRow(); QTC_ASSERT(index >= 0, return); - GitPluginPrivate::client()->show(m_repository, QString(m_model->at(index).name)); + GitPlugin::client()->show(m_repository, QString(m_model->at(index).name)); } // Suggest Branch name to restore 'stash@{0}' -> 'stash0-date' @@ -267,7 +267,7 @@ bool StashDialog::promptForRestore(QString *stash, { const QString stashIn = *stash; bool modifiedPromptShown = false; - switch (GitPluginPrivate::client()->gitStatus(m_repository, StatusMode(NoUntracked | NoSubmodules), nullptr, errorMessage)) { + switch (GitPlugin::client()->gitStatus(m_repository, StatusMode(NoUntracked | NoSubmodules), nullptr, errorMessage)) { case GitClient::StatusFailed: return false; case GitClient::StatusChanged: { @@ -275,13 +275,13 @@ bool StashDialog::promptForRestore(QString *stash, case ModifiedRepositoryCancel: return false; case ModifiedRepositoryStash: - if (GitPluginPrivate::client()->synchronousStash(m_repository, QString(), GitClient::StashPromptDescription).isEmpty()) + if (GitPlugin::client()->synchronousStash(m_repository, QString(), GitClient::StashPromptDescription).isEmpty()) return false; *stash = nextStash(*stash); // Our stash id to be restored changed QTC_ASSERT(!stash->isEmpty(), return false); break; case ModifiedRepositoryDiscard: - if (!GitPluginPrivate::client()->synchronousReset(m_repository)) + if (!GitPlugin::client()->synchronousReset(m_repository)) return false; break; } @@ -318,7 +318,7 @@ void StashDialog::restoreCurrent() // Make sure repository is not modified, restore. The command will // output to window on success. if (promptForRestore(&name, nullptr, &errorMessage) - && GitPluginPrivate::client()->synchronousStashRestore(m_repository, name)) { + && GitPlugin::client()->synchronousStashRestore(m_repository, name)) { refresh(m_repository, true); // Might have stashed away local changes. } else if (!errorMessage.isEmpty()) { warning(msgRestoreFailedTitle(name), errorMessage); @@ -333,7 +333,7 @@ void StashDialog::restoreCurrentInBranch() QString branch; QString name = m_model->at(index).name; if (promptForRestore(&name, &branch, &errorMessage) - && GitPluginPrivate::client()->synchronousStashRestore(m_repository, name, false, branch)) { + && GitPlugin::client()->synchronousStashRestore(m_repository, name, false, branch)) { refresh(m_repository, true); // git deletes the stash, unfortunately. } else if (!errorMessage.isEmpty()) { warning(msgRestoreFailedTitle(name), errorMessage);