Git: Initialize GitClient on first access

This does not change the current timing of construction a lot as
the GerritPlugin may need it immediately in some cases, in any
case the gitGrep instance will need it.

There's nothing big going on at destruction time, so the prolonged
lifetime until really close to the end does not hurt.

The reason here is that this way we will avoid cases like in change
5e5b90a9a1.

Change-Id: I326d83c1a3d21114322ac6cce8d9e9b782faacdc
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
hjk
2023-07-25 16:09:50 +02:00
parent 8d5897b8eb
commit 778a1d75ba
24 changed files with 255 additions and 280 deletions

View File

@@ -201,9 +201,8 @@ public:
class BranchModel::Private class BranchModel::Private
{ {
public: public:
explicit Private(BranchModel *q, GitClient *client) : explicit Private(BranchModel *q) :
q(q), q(q),
client(client),
rootNode(new BranchNode) rootNode(new BranchNode)
{ {
} }
@@ -222,7 +221,6 @@ public:
void updateAllUpstreamStatus(BranchNode *node); void updateAllUpstreamStatus(BranchNode *node);
BranchModel *q; BranchModel *q;
GitClient *client;
FilePath workingDirectory; FilePath workingDirectory;
BranchNode *rootNode; BranchNode *rootNode;
BranchNode *currentBranch = nullptr; BranchNode *currentBranch = nullptr;
@@ -249,12 +247,10 @@ public:
// BranchModel: // BranchModel:
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
BranchModel::BranchModel(GitClient *client, QObject *parent) : BranchModel::BranchModel(QObject *parent) :
QAbstractItemModel(parent), QAbstractItemModel(parent),
d(new Private(this, client)) d(new Private(this))
{ {
QTC_CHECK(d->client);
// Abuse the sha field for ref prefix // Abuse the sha field for ref prefix
d->rootNode->append(new BranchNode(Tr::tr("Local Branches"), "refs/heads")); d->rootNode->append(new BranchNode(Tr::tr("Local Branches"), "refs/heads"));
d->rootNode->append(new BranchNode(Tr::tr("Remote Branches"), "refs/remotes")); d->rootNode->append(new BranchNode(Tr::tr("Remote Branches"), "refs/remotes"));
@@ -415,7 +411,7 @@ void BranchModel::refresh(const FilePath &workingDirectory, ShowError showError)
} }
const ProcessTask topRevisionProc = const ProcessTask topRevisionProc =
d->client->topRevision(workingDirectory, gitClient().topRevision(workingDirectory,
[=](const QString &ref, const QDateTime &dateTime) { [=](const QString &ref, const QDateTime &dateTime) {
d->currentSha = ref; d->currentSha = ref;
d->currentDateTime = dateTime; d->currentDateTime = dateTime;
@@ -430,7 +426,7 @@ void BranchModel::refresh(const FilePath &workingDirectory, ShowError showError)
"refs/remotes/**"}; "refs/remotes/**"};
if (settings().showTags()) if (settings().showTags())
args << "refs/tags/**"; args << "refs/tags/**";
d->client->setupCommand(process, workingDirectory, args); gitClient().setupCommand(process, workingDirectory, args);
}; };
const auto forEachRefDone = [=](const Process &process) { const auto forEachRefDone = [=](const Process &process) {
@@ -481,7 +477,7 @@ void BranchModel::refresh(const FilePath &workingDirectory, ShowError showError)
void BranchModel::setCurrentBranch() void BranchModel::setCurrentBranch()
{ {
const QString currentBranch = d->client->synchronousCurrentLocalBranch(d->workingDirectory); const QString currentBranch = gitClient().synchronousCurrentLocalBranch(d->workingDirectory);
if (currentBranch.isEmpty()) if (currentBranch.isEmpty())
return; return;
@@ -499,7 +495,7 @@ void BranchModel::renameBranch(const QString &oldName, const QString &newName)
{ {
QString errorMessage; QString errorMessage;
QString output; QString output;
if (!d->client->synchronousBranchCmd(d->workingDirectory, {"-m", oldName, newName}, if (!gitClient().synchronousBranchCmd(d->workingDirectory, {"-m", oldName, newName},
&output, &errorMessage)) &output, &errorMessage))
VcsOutputWindow::appendError(errorMessage); VcsOutputWindow::appendError(errorMessage);
else else
@@ -510,9 +506,9 @@ void BranchModel::renameTag(const QString &oldName, const QString &newName)
{ {
QString errorMessage; QString errorMessage;
QString output; QString output;
if (!d->client->synchronousTagCmd(d->workingDirectory, {newName, oldName}, if (!gitClient().synchronousTagCmd(d->workingDirectory, {newName, oldName},
&output, &errorMessage) &output, &errorMessage)
|| !d->client->synchronousTagCmd(d->workingDirectory, {"-d", oldName}, || !gitClient().synchronousTagCmd(d->workingDirectory, {"-d", oldName},
&output, &errorMessage)) { &output, &errorMessage)) {
VcsOutputWindow::appendError(errorMessage); VcsOutputWindow::appendError(errorMessage);
} else { } else {
@@ -610,7 +606,7 @@ void BranchModel::removeBranch(const QModelIndex &idx)
QString errorMessage; QString errorMessage;
QString output; QString output;
if (!d->client->synchronousBranchCmd(d->workingDirectory, {"-D", branch}, &output, &errorMessage)) { if (!gitClient().synchronousBranchCmd(d->workingDirectory, {"-D", branch}, &output, &errorMessage)) {
VcsOutputWindow::appendError(errorMessage); VcsOutputWindow::appendError(errorMessage);
return; return;
} }
@@ -626,7 +622,7 @@ void BranchModel::removeTag(const QModelIndex &idx)
QString errorMessage; QString errorMessage;
QString output; QString output;
if (!d->client->synchronousTagCmd(d->workingDirectory, {"-d", tag}, &output, &errorMessage)) { if (!gitClient().synchronousTagCmd(d->workingDirectory, {"-d", tag}, &output, &errorMessage)) {
VcsOutputWindow::appendError(errorMessage); VcsOutputWindow::appendError(errorMessage);
return; return;
} }
@@ -642,7 +638,7 @@ void BranchModel::checkoutBranch(const QModelIndex &idx, const QObject *context,
// No StashGuard since this function for now is only used with clean working dir. // 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 // If it is ever used from another place, please add StashGuard here
d->client->checkout(d->workingDirectory, branch, GitClient::StashMode::NoStash, gitClient().checkout(d->workingDirectory, branch, GitClient::StashMode::NoStash,
context, handler); context, handler);
} }
@@ -655,7 +651,7 @@ bool BranchModel::branchIsMerged(const QModelIndex &idx)
QString errorMessage; QString errorMessage;
QString output; QString output;
if (!d->client->synchronousBranchCmd(d->workingDirectory, {"-a", "--contains", sha(idx)}, if (!gitClient().synchronousBranchCmd(d->workingDirectory, {"-a", "--contains", sha(idx)},
&output, &errorMessage)) { &output, &errorMessage)) {
VcsOutputWindow::appendError(errorMessage); VcsOutputWindow::appendError(errorMessage);
} }
@@ -700,7 +696,7 @@ QModelIndex BranchModel::addBranch(const QString &name, bool track, const QModel
branchDateTime = dateTime(startPoint); branchDateTime = dateTime(startPoint);
} else { } else {
const QStringList arguments({"-n1", "--format=%H %ct"}); const QStringList arguments({"-n1", "--format=%H %ct"});
if (d->client->synchronousLog(d->workingDirectory, arguments, &output, &errorMessage, if (gitClient().synchronousLog(d->workingDirectory, arguments, &output, &errorMessage,
RunFlags::SuppressCommandLogging)) { RunFlags::SuppressCommandLogging)) {
const QStringList values = output.split(' '); const QStringList values = output.split(' ');
startSha = values[0]; startSha = values[0];
@@ -708,7 +704,7 @@ QModelIndex BranchModel::addBranch(const QString &name, bool track, const QModel
} }
} }
if (!d->client->synchronousBranchCmd(d->workingDirectory, args, &output, &errorMessage)) { if (!gitClient().synchronousBranchCmd(d->workingDirectory, args, &output, &errorMessage)) {
VcsOutputWindow::appendError(errorMessage); VcsOutputWindow::appendError(errorMessage);
return QModelIndex(); return QModelIndex();
} }
@@ -748,7 +744,7 @@ void BranchModel::setRemoteTracking(const QModelIndex &trackingIndex)
const QString currentName = fullName(current); const QString currentName = fullName(current);
const QString shortTracking = fullName(trackingIndex); const QString shortTracking = fullName(trackingIndex);
const QString tracking = fullName(trackingIndex, true); const QString tracking = fullName(trackingIndex, true);
d->client->synchronousSetTrackingBranch(d->workingDirectory, currentName, tracking); gitClient().synchronousSetTrackingBranch(d->workingDirectory, currentName, tracking);
d->currentBranch->tracking = shortTracking; d->currentBranch->tracking = shortTracking;
updateUpstreamStatus(d->currentBranch); updateUpstreamStatus(d->currentBranch);
emit dataChanged(current, current); emit dataChanged(current, current);
@@ -920,8 +916,8 @@ void BranchModel::updateUpstreamStatus(BranchNode *node)
return; return;
Process *process = new Process(node); Process *process = new Process(node);
process->setEnvironment(d->client->processEnvironment()); process->setEnvironment(gitClient().processEnvironment());
process->setCommand({d->client->vcsBinary(), {"rev-list", "--no-color", "--left-right", process->setCommand({gitClient().vcsBinary(), {"rev-list", "--no-color", "--left-right",
"--count", node->fullRef() + "..." + node->tracking}}); "--count", node->fullRef() + "..." + node->tracking}});
process->setWorkingDirectory(d->workingDirectory); process->setWorkingDirectory(d->workingDirectory);
connect(process, &Process::done, this, [this, process, node] { connect(process, &Process::done, this, [this, process, node] {
@@ -958,7 +954,7 @@ QString BranchModel::toolTip(const QString &sha) const
// Show the sha description excluding diff as toolTip // Show the sha description excluding diff as toolTip
QString output; QString output;
QString errorMessage; QString errorMessage;
if (!d->client->synchronousLog(d->workingDirectory, {"-n1", sha}, &output, &errorMessage, if (!gitClient().synchronousLog(d->workingDirectory, {"-n1", sha}, &output, &errorMessage,
RunFlags::SuppressCommandLogging)) { RunFlags::SuppressCommandLogging)) {
return errorMessage; return errorMessage;
} }

View File

@@ -16,12 +16,11 @@ class CommandResult;
namespace Git::Internal { namespace Git::Internal {
class BranchNode; class BranchNode;
class GitClient;
class BranchModel : public QAbstractItemModel class BranchModel : public QAbstractItemModel
{ {
public: public:
explicit BranchModel(GitClient *client, QObject *parent = nullptr); explicit BranchModel(QObject *parent = nullptr);
~BranchModel() override; ~BranchModel() override;
// QAbstractItemModel // QAbstractItemModel

View File

@@ -78,7 +78,7 @@ BranchView::BranchView()
, m_refreshAction(new QAction(this)) , m_refreshAction(new QAction(this))
, m_repositoryLabel(new ElidingLabel(this)) , m_repositoryLabel(new ElidingLabel(this))
, m_branchView(new NavigationTreeView(this)) , m_branchView(new NavigationTreeView(this))
, m_model(new BranchModel(GitClient::instance(), this)) , m_model(new BranchModel(this))
, m_filterModel(new BranchFilterModel(this)) , m_filterModel(new BranchFilterModel(this))
{ {
m_addAction->setIcon(Utils::Icons::PLUS_TOOLBAR.icon()); m_addAction->setIcon(Utils::Icons::PLUS_TOOLBAR.icon());
@@ -237,12 +237,12 @@ void BranchView::slotCustomContextMenu(const QPoint &point)
const std::optional<QString> remote = m_model->remoteName(index); const std::optional<QString> remote = m_model->remoteName(index);
if (remote.has_value()) { if (remote.has_value()) {
contextMenu.addAction(Tr::tr("&Fetch"), this, [this, &remote] { contextMenu.addAction(Tr::tr("&Fetch"), this, [this, &remote] {
GitClient::instance()->fetch(m_repository, *remote); gitClient().fetch(m_repository, *remote);
}); });
contextMenu.addSeparator(); contextMenu.addSeparator();
if (!remote->isEmpty()) { if (!remote->isEmpty()) {
contextMenu.addAction(Tr::tr("Remove &Stale Branches"), this, [this, &remote] { contextMenu.addAction(Tr::tr("Remove &Stale Branches"), this, [this, &remote] {
GitClient::instance()->removeStaleRemoteBranches(m_repository, *remote); gitClient().removeStaleRemoteBranches(m_repository, *remote);
}); });
contextMenu.addSeparator(); contextMenu.addSeparator();
} }
@@ -261,7 +261,7 @@ void BranchView::slotCustomContextMenu(const QPoint &point)
contextMenu.addAction(Tr::tr("&Diff"), this, [this] { contextMenu.addAction(Tr::tr("&Diff"), this, [this] {
const QString fullName = m_model->fullName(selectedIndex(), true); const QString fullName = m_model->fullName(selectedIndex(), true);
if (!fullName.isEmpty()) if (!fullName.isEmpty())
GitClient::instance()->diffBranch(m_repository, fullName); gitClient().diffBranch(m_repository, fullName);
}); });
contextMenu.addAction(Tr::tr("&Log"), this, [this] { log(selectedIndex()); }); contextMenu.addAction(Tr::tr("&Log"), this, [this] { log(selectedIndex()); });
contextMenu.addAction(Tr::tr("Reflo&g"), this, [this] { reflog(selectedIndex()); }); contextMenu.addAction(Tr::tr("Reflo&g"), this, [this] { reflog(selectedIndex()); });
@@ -394,13 +394,12 @@ bool BranchView::checkout()
' ' + nextBranch + "-AutoStash "; ' ' + nextBranch + "-AutoStash ";
BranchCheckoutDialog branchCheckoutDialog(this, currentBranch, nextBranch); BranchCheckoutDialog branchCheckoutDialog(this, currentBranch, nextBranch);
GitClient *client = GitClient::instance();
if (client->gitStatus(m_repository, StatusMode(NoUntracked | NoSubmodules)) != GitClient::StatusChanged) if (gitClient().gitStatus(m_repository, StatusMode(NoUntracked | NoSubmodules)) != GitClient::StatusChanged)
branchCheckoutDialog.foundNoLocalChanges(); branchCheckoutDialog.foundNoLocalChanges();
QList<Stash> stashes; QList<Stash> stashes;
client->synchronousStashList(m_repository, &stashes); gitClient().synchronousStashList(m_repository, &stashes);
for (const Stash &stash : std::as_const(stashes)) { for (const Stash &stash : std::as_const(stashes)) {
if (stash.message.startsWith(popMessageStart)) { if (stash.message.startsWith(popMessageStart)) {
branchCheckoutDialog.foundStashForNextBranch(); branchCheckoutDialog.foundStashForNextBranch();
@@ -415,13 +414,13 @@ bool BranchView::checkout()
} else if (branchCheckoutDialog.exec() == QDialog::Accepted) { } else if (branchCheckoutDialog.exec() == QDialog::Accepted) {
if (branchCheckoutDialog.makeStashOfCurrentBranch()) { if (branchCheckoutDialog.makeStashOfCurrentBranch()) {
if (client->synchronousStash(m_repository, currentBranch + "-AutoStash").isEmpty()) if (gitClient().synchronousStash(m_repository, currentBranch + "-AutoStash").isEmpty())
return false; return false;
} else if (branchCheckoutDialog.moveLocalChangesToNextBranch()) { } else if (branchCheckoutDialog.moveLocalChangesToNextBranch()) {
if (!client->beginStashScope(m_repository, "Checkout", NoPrompt)) if (!gitClient().beginStashScope(m_repository, "Checkout", NoPrompt))
return false; return false;
} else if (branchCheckoutDialog.discardLocalChanges()) { } else if (branchCheckoutDialog.discardLocalChanges()) {
if (!client->synchronousReset(m_repository)) if (!gitClient().synchronousReset(m_repository))
return false; return false;
} }
@@ -429,18 +428,18 @@ bool BranchView::checkout()
const bool popStash = branchCheckoutDialog.popStashOfNextBranch(); const bool popStash = branchCheckoutDialog.popStashOfNextBranch();
const auto commandHandler = [=](const CommandResult &) { const auto commandHandler = [=](const CommandResult &) {
if (moveChanges) { if (moveChanges) {
client->endStashScope(m_repository); gitClient().endStashScope(m_repository);
} else if (popStash) { } else if (popStash) {
QList<Stash> stashes; QList<Stash> stashes;
QString stashName; QString stashName;
client->synchronousStashList(m_repository, &stashes); gitClient().synchronousStashList(m_repository, &stashes);
for (const Stash &stash : std::as_const(stashes)) { for (const Stash &stash : std::as_const(stashes)) {
if (stash.message.startsWith(popMessageStart)) { if (stash.message.startsWith(popMessageStart)) {
stashName = stash.name; stashName = stash.name;
break; break;
} }
} }
client->synchronousStashRestore(m_repository, stashName, true); gitClient().synchronousStashRestore(m_repository, stashName, true);
} }
}; };
m_model->checkoutBranch(selected, this, commandHandler); m_model->checkoutBranch(selected, this, commandHandler);
@@ -526,7 +525,7 @@ bool BranchView::reset(const QByteArray &resetType)
if (QMessageBox::question(this, Tr::tr("Git Reset"), Tr::tr("Reset branch \"%1\" to \"%2\"?") if (QMessageBox::question(this, Tr::tr("Git Reset"), Tr::tr("Reset branch \"%1\" to \"%2\"?")
.arg(currentName, branchName), .arg(currentName, branchName),
QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) { QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
GitClient::instance()->reset(m_repository, QLatin1String("--" + resetType), branchName); gitClient().reset(m_repository, QLatin1String("--" + resetType), branchName);
return true; return true;
} }
return false; return false;
@@ -547,15 +546,14 @@ TaskTree *BranchView::onFastForwardMerge(const std::function<void()> &callback)
const TreeStorage<FastForwardStorage> storage; const TreeStorage<FastForwardStorage> storage;
GitClient *client = GitClient::instance();
const auto setupMergeBase = [=](Process &process) { const auto setupMergeBase = [=](Process &process) {
client->setupCommand(process, m_repository, {"merge-base", "HEAD", branch}); gitClient().setupCommand(process, m_repository, {"merge-base", "HEAD", branch});
}; };
const auto onMergeBaseDone = [storage](const Process &process) { const auto onMergeBaseDone = [storage](const Process &process) {
storage->mergeBase = process.cleanedStdOut().trimmed(); storage->mergeBase = process.cleanedStdOut().trimmed();
}; };
const ProcessTask topRevisionProc = client->topRevision( const ProcessTask topRevisionProc = gitClient().topRevision(
m_repository, m_repository,
[storage](const QString &revision, const QDateTime &) { [storage](const QString &revision, const QDateTime &) {
storage->topRevision = revision; storage->topRevision = revision;
@@ -584,9 +582,8 @@ bool BranchView::merge(bool allowFastForward)
QTC_CHECK(selected != m_model->currentBranch()); QTC_CHECK(selected != m_model->currentBranch());
const QString branch = m_model->fullName(selected, true); const QString branch = m_model->fullName(selected, true);
GitClient *client = GitClient::instance(); if (gitClient().beginStashScope(m_repository, "merge", AllowUnstashed))
if (client->beginStashScope(m_repository, "merge", AllowUnstashed)) return gitClient().synchronousMerge(m_repository, branch, allowFastForward);
return client->synchronousMerge(m_repository, branch, allowFastForward);
return false; return false;
} }
@@ -599,9 +596,8 @@ void BranchView::rebase()
QTC_CHECK(selected != m_model->currentBranch()); QTC_CHECK(selected != m_model->currentBranch());
const QString baseBranch = m_model->fullName(selected, true); const QString baseBranch = m_model->fullName(selected, true);
GitClient *client = GitClient::instance(); if (gitClient().beginStashScope(m_repository, "rebase"))
if (client->beginStashScope(m_repository, "rebase")) gitClient().rebase(m_repository, baseBranch);
client->rebase(m_repository, baseBranch);
} }
bool BranchView::cherryPick() bool BranchView::cherryPick()
@@ -612,7 +608,7 @@ bool BranchView::cherryPick()
QTC_CHECK(selected != m_model->currentBranch()); QTC_CHECK(selected != m_model->currentBranch());
const QString branch = m_model->fullName(selected, true); const QString branch = m_model->fullName(selected, true);
return GitClient::instance()->synchronousCherryPick(m_repository, branch); return gitClient().synchronousCherryPick(m_repository, branch);
} }
void BranchView::log(const QModelIndex &idx) void BranchView::log(const QModelIndex &idx)
@@ -621,7 +617,7 @@ void BranchView::log(const QModelIndex &idx)
if (branchName.isEmpty()) if (branchName.isEmpty())
return; return;
SetInContext block(m_blockRefresh); SetInContext block(m_blockRefresh);
GitClient::instance()->log(m_repository, QString(), false, {branchName}); gitClient().log(m_repository, QString(), false, {branchName});
} }
void BranchView::reflog(const QModelIndex &idx) void BranchView::reflog(const QModelIndex &idx)
@@ -630,7 +626,7 @@ void BranchView::reflog(const QModelIndex &idx)
if (branchName.isEmpty()) if (branchName.isEmpty())
return; return;
SetInContext block(m_blockRefresh); SetInContext block(m_blockRefresh);
GitClient::instance()->reflog(m_repository, branchName); gitClient().reflog(m_repository, branchName);
} }
void BranchView::push() void BranchView::push()
@@ -646,7 +642,7 @@ void BranchView::push()
const QString remoteBranch = fullTargetName.mid(pos + 1); const QString remoteBranch = fullTargetName.mid(pos + 1);
const QStringList pushArgs = {remoteName, localBranch + ':' + remoteBranch}; const QStringList pushArgs = {remoteName, localBranch + ':' + remoteBranch};
GitClient::instance()->push(m_repository, pushArgs); gitClient().push(m_repository, pushArgs);
} }
BranchViewFactory::BranchViewFactory() BranchViewFactory::BranchViewFactory()

View File

@@ -33,8 +33,8 @@ ChangeSelectionDialog::ChangeSelectionDialog(const FilePath &workingDirectory, I
QWidget *parent) : QWidget *parent) :
QDialog(parent) QDialog(parent)
{ {
m_gitExecutable = GitClient::instance()->vcsBinary(); m_gitExecutable = gitClient().vcsBinary();
m_gitEnvironment = GitClient::instance()->processEnvironment(); m_gitEnvironment = gitClient().processEnvironment();
resize(550, 350); resize(550, 350);
setWindowTitle(Tr::tr("Select a Git Commit")); setWindowTitle(Tr::tr("Select a Git Commit"));
@@ -208,10 +208,9 @@ void ChangeSelectionDialog::recalculateCompletion()
if (workingDir.isEmpty()) if (workingDir.isEmpty())
return; return;
GitClient *client = GitClient::instance();
Process *process = new Process(this); Process *process = new Process(this);
process->setEnvironment(client->processEnvironment()); process->setEnvironment(gitClient().processEnvironment());
process->setCommand({client->vcsBinary(), {"for-each-ref", "--format=%(refname:short)"}}); process->setCommand({gitClient().vcsBinary(), {"for-each-ref", "--format=%(refname:short)"}});
process->setWorkingDirectory(workingDir); process->setWorkingDirectory(workingDir);
process->setUseCtrlCStub(true); process->setUseCtrlCStub(true);
connect(process, &Process::done, this, [this, process] { connect(process, &Process::done, this, [this, process] {

View File

@@ -14,7 +14,7 @@ BranchComboBox::BranchComboBox(QWidget *parent) : QComboBox(parent)
void BranchComboBox::init(const FilePath &repository) void BranchComboBox::init(const FilePath &repository)
{ {
m_repository = repository; m_repository = repository;
QString currentBranch = GitClient::instance()->synchronousCurrentLocalBranch(repository); QString currentBranch = gitClient().synchronousCurrentLocalBranch(repository);
if (currentBranch.isEmpty()) { if (currentBranch.isEmpty()) {
m_detached = true; m_detached = true;
currentBranch = "HEAD"; currentBranch = "HEAD";
@@ -22,7 +22,7 @@ void BranchComboBox::init(const FilePath &repository)
} }
QString output; QString output;
const QString branchPrefix("refs/heads/"); const QString branchPrefix("refs/heads/");
if (!GitClient::instance()->synchronousForEachRefCmd( if (!gitClient().synchronousForEachRefCmd(
m_repository, {"--format=%(refname)", branchPrefix}, &output)) { m_repository, {"--format=%(refname)", branchPrefix}, &output)) {
return; return;
} }

View File

@@ -268,7 +268,7 @@ QueryContext::QueryContext(const QString &query,
m_output.append(m_process.readAllRawStandardOutput()); m_output.append(m_process.readAllRawStandardOutput());
}); });
connect(&m_process, &Process::done, this, &QueryContext::processDone); connect(&m_process, &Process::done, this, &QueryContext::processDone);
m_process.setEnvironment(Git::Internal::GitClient::instance()->processEnvironment()); m_process.setEnvironment(Git::Internal::gitClient().processEnvironment());
m_timer.setInterval(timeOutMS); m_timer.setInterval(timeOutMS);
m_timer.setSingleShot(true); m_timer.setSingleShot(true);

View File

@@ -101,7 +101,7 @@ FetchContext::FetchContext(const QSharedPointer<GerritChange> &change,
VcsBase::VcsOutputWindow::append(QString::fromLocal8Bit(m_process.readAllRawStandardOutput())); VcsBase::VcsOutputWindow::append(QString::fromLocal8Bit(m_process.readAllRawStandardOutput()));
}); });
m_process.setWorkingDirectory(repository); m_process.setWorkingDirectory(repository);
m_process.setEnvironment(GitClient::instance()->processEnvironment()); m_process.setEnvironment(gitClient().processEnvironment());
} }
void FetchContext::start() void FetchContext::start()
@@ -136,7 +136,7 @@ void FetchContext::show()
{ {
const QString title = QString::number(m_change->number) + '/' const QString title = QString::number(m_change->number) + '/'
+ QString::number(m_change->currentPatchSet.patchSetNumber); + QString::number(m_change->currentPatchSet.patchSetNumber);
GitClient::instance()->show(m_repository, "FETCH_HEAD", title); gitClient().show(m_repository, "FETCH_HEAD", title);
} }
void FetchContext::cherryPick() void FetchContext::cherryPick()
@@ -144,12 +144,12 @@ void FetchContext::cherryPick()
// Point user to errors. // Point user to errors.
VcsBase::VcsOutputWindow::instance()->popup(IOutputPane::ModeSwitch VcsBase::VcsOutputWindow::instance()->popup(IOutputPane::ModeSwitch
| IOutputPane::WithFocus); | IOutputPane::WithFocus);
GitClient::instance()->synchronousCherryPick(m_repository, "FETCH_HEAD"); gitClient().synchronousCherryPick(m_repository, "FETCH_HEAD");
} }
void FetchContext::checkout() void FetchContext::checkout()
{ {
GitClient::instance()->checkout(m_repository, "FETCH_HEAD"); gitClient().checkout(m_repository, "FETCH_HEAD");
} }
GerritPlugin::GerritPlugin() GerritPlugin::GerritPlugin()
@@ -219,7 +219,7 @@ void GerritPlugin::push(const FilePath &topLevel)
dialog.storeTopic(); dialog.storeTopic();
m_reviewers = dialog.reviewers(); m_reviewers = dialog.reviewers();
GitClient::instance()->push(topLevel, {dialog.selectedRemoteName(), dialog.pushTarget()}); gitClient().push(topLevel, {dialog.selectedRemoteName(), dialog.pushTarget()});
} }
static FilePath currentRepository() static FilePath currentRepository()
@@ -267,19 +267,19 @@ void GerritPlugin::push()
Utils::FilePath GerritPlugin::gitBinDirectory() Utils::FilePath GerritPlugin::gitBinDirectory()
{ {
return GitClient::instance()->gitBinDirectory(); return gitClient().gitBinDirectory();
} }
// Find the branch of a repository. // Find the branch of a repository.
QString GerritPlugin::branch(const FilePath &repository) QString GerritPlugin::branch(const FilePath &repository)
{ {
return GitClient::instance()->synchronousCurrentLocalBranch(repository); return gitClient().synchronousCurrentLocalBranch(repository);
} }
void GerritPlugin::fetch(const QSharedPointer<GerritChange> &change, int mode) void GerritPlugin::fetch(const QSharedPointer<GerritChange> &change, int mode)
{ {
// Locate git. // Locate git.
const Utils::FilePath git = GitClient::instance()->vcsBinary(); const Utils::FilePath git = gitClient().vcsBinary();
if (git.isEmpty()) { if (git.isEmpty()) {
VcsBase::VcsOutputWindow::appendError(Git::Tr::tr("Git is not available.")); VcsBase::VcsOutputWindow::appendError(Git::Tr::tr("Git is not available."));
return; return;
@@ -292,7 +292,7 @@ void GerritPlugin::fetch(const QSharedPointer<GerritChange> &change, int mode)
if (!repository.isEmpty()) { if (!repository.isEmpty()) {
// Check if remote from a working dir is the same as remote from patch // Check if remote from a working dir is the same as remote from patch
QMap<QString, QString> remotesList = GitClient::instance()->synchronousRemotesList(repository); QMap<QString, QString> remotesList = gitClient().synchronousRemotesList(repository);
if (!remotesList.isEmpty()) { if (!remotesList.isEmpty()) {
const QStringList remotes = remotesList.values(); const QStringList remotes = remotesList.values();
for (QString remote : remotes) { for (QString remote : remotes) {
@@ -305,7 +305,7 @@ void GerritPlugin::fetch(const QSharedPointer<GerritChange> &change, int mode)
} }
if (!verifiedRepository) { if (!verifiedRepository) {
const SubmoduleDataMap submodules = GitClient::instance()->submoduleList(repository); const SubmoduleDataMap submodules = gitClient().submoduleList(repository);
for (const SubmoduleData &submoduleData : submodules) { for (const SubmoduleData &submoduleData : submodules) {
QString remote = submoduleData.url; QString remote = submoduleData.url;
if (remote.endsWith(".git")) if (remote.endsWith(".git"))

View File

@@ -54,7 +54,7 @@ QString GerritPushDialog::determineRemoteBranch(const QString &localBranch)
QString output; QString output;
QString error; QString error;
if (!GitClient::instance()->synchronousBranchCmd( if (!gitClient().synchronousBranchCmd(
m_workingDir, {"-r", "--contains", earliestCommit + '^'}, &output, &error)) { m_workingDir, {"-r", "--contains", earliestCommit + '^'}, &output, &error)) {
return QString(); return QString();
} }
@@ -63,7 +63,7 @@ QString GerritPushDialog::determineRemoteBranch(const QString &localBranch)
QString remoteTrackingBranch; QString remoteTrackingBranch;
if (localBranch != "HEAD") if (localBranch != "HEAD")
remoteTrackingBranch = GitClient::instance()->synchronousTrackingBranch(m_workingDir, localBranch); remoteTrackingBranch = gitClient().synchronousTrackingBranch(m_workingDir, localBranch);
QString remoteBranch; QString remoteBranch;
for (const QString &reference : refs) { for (const QString &reference : refs) {
@@ -87,7 +87,7 @@ void GerritPushDialog::initRemoteBranches()
const QString head = "/HEAD"; const QString head = "/HEAD";
const QString remotesPrefix("refs/remotes/"); const QString remotesPrefix("refs/remotes/");
if (!GitClient::instance()->synchronousForEachRefCmd( if (!gitClient().synchronousForEachRefCmd(
m_workingDir, {"--format=%(refname)\t%(committerdate:raw)", remotesPrefix}, &output)) { m_workingDir, {"--format=%(refname)\t%(committerdate:raw)", remotesPrefix}, &output)) {
return; return;
} }
@@ -198,7 +198,7 @@ QString GerritPushDialog::calculateChangeRange(const QString &branch)
const QString remote = selectedRemoteName() + '/' + selectedRemoteBranchName(); const QString remote = selectedRemoteName() + '/' + selectedRemoteBranchName();
QString number; QString number;
QString error; QString error;
GitClient::instance()->synchronousRevListCmd( gitClient().synchronousRevListCmd(
m_workingDir, { remote + ".." + branch, "--count" }, &number, &error); m_workingDir, { remote + ".." + branch, "--count" }, &number, &error);
number.chop(1); number.chop(1);
return number; return number;
@@ -322,7 +322,7 @@ QString GerritPushDialog::pushTarget() const
void GerritPushDialog::storeTopic() void GerritPushDialog::storeTopic()
{ {
const QString branch = m_localBranchComboBox->currentText(); const QString branch = m_localBranchComboBox->currentText();
GitClient::instance()->setConfigValue( gitClient().setConfigValue(
m_workingDir, QString("branch.%1.topic").arg(branch), selectedTopic()); m_workingDir, QString("branch.%1.topic").arg(branch), selectedTopic());
} }
@@ -335,7 +335,7 @@ void GerritPushDialog::setRemoteBranches(bool includeOld)
const QString remoteName = selectedRemoteName(); const QString remoteName = selectedRemoteName();
if (!m_remoteBranches.contains(remoteName)) { if (!m_remoteBranches.contains(remoteName)) {
const QStringList remoteBranches = const QStringList remoteBranches =
GitClient::instance()->synchronousRepositoryBranches(remoteName, m_workingDir); gitClient().synchronousRepositoryBranches(remoteName, m_workingDir);
for (const QString &branch : remoteBranches) for (const QString &branch : remoteBranches)
m_remoteBranches.insertMulti(remoteName, {branch, {}}); m_remoteBranches.insertMulti(remoteName, {branch, {}});
if (remoteBranches.isEmpty()) { if (remoteBranches.isEmpty()) {
@@ -373,7 +373,7 @@ void GerritPushDialog::updateCommits(int index)
{ {
const QString branch = m_localBranchComboBox->itemText(index); const QString branch = m_localBranchComboBox->itemText(index);
m_hasLocalCommits = m_commitView->init(m_workingDir, branch, LogChangeWidget::Silent); m_hasLocalCommits = m_commitView->init(m_workingDir, branch, LogChangeWidget::Silent);
const QString topic = GitClient::instance()->readConfigValue( const QString topic = gitClient().readConfigValue(
m_workingDir, QString("branch.%1.topic").arg(branch)); m_workingDir, QString("branch.%1.topic").arg(branch));
if (!topic.isEmpty()) if (!topic.isEmpty())
m_topicLineEdit->setText(topic); m_topicLineEdit->setText(topic);

View File

@@ -85,7 +85,7 @@ bool GerritRemoteChooser::updateRemotes(bool forceReload)
m_remotes.clear(); m_remotes.clear();
QString errorMessage; // Mute errors. We'll just fallback to the defaults QString errorMessage; // Mute errors. We'll just fallback to the defaults
const QMap<QString, QString> remotesList = const QMap<QString, QString> remotesList =
Git::Internal::GitClient::instance()->synchronousRemotesList(m_repository, &errorMessage); Git::Internal::gitClient().synchronousRemotesList(m_repository, &errorMessage);
for (auto mapIt = remotesList.cbegin(), end = remotesList.cend(); mapIt != end; ++mapIt) { for (auto mapIt = remotesList.cbegin(), end = remotesList.cend(); mapIt != end; ++mapIt) {
GerritServer server; GerritServer server;
if (!server.fillFromRemote(mapIt.value(), *m_parameters, forceReload)) if (!server.fillFromRemote(mapIt.value(), *m_parameters, forceReload))

View File

@@ -1,9 +1,10 @@
// Copyright (C) 2017 Orgad Shaneh <orgads@gmail.com>. // Copyright (C) 2017 Orgad Shaneh <orgads@gmail.com>.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "gerritserver.h"
#include "authenticationdialog.h" #include "authenticationdialog.h"
#include "gerritparameters.h" #include "gerritparameters.h"
#include "gerritserver.h"
#include "../gitclient.h" #include "../gitclient.h"
#include "../gittr.h" #include "../gittr.h"
@@ -222,9 +223,8 @@ QStringList GerritServer::curlArguments() const
int GerritServer::testConnection() int GerritServer::testConnection()
{ {
static GitClient *const client = GitClient::instance();
const QStringList arguments = curlArguments() << (url(RestUrl) + accountUrlC); const QStringList arguments = curlArguments() << (url(RestUrl) + accountUrlC);
const CommandResult result = client->vcsSynchronousExec({}, {curlBinary, arguments}); const CommandResult result = gitClient().vcsSynchronousExec({}, {curlBinary, arguments});
if (result.result() == ProcessResult::FinishedWithSuccess) { if (result.result() == ProcessResult::FinishedWithSuccess) {
QString output = result.cleanedStdOut(); QString output = result.cleanedStdOut();
// Gerrit returns an empty response for /p/qt-creator/a/accounts/self // Gerrit returns an empty response for /p/qt-creator/a/accounts/self
@@ -310,7 +310,6 @@ bool GerritServer::resolveRoot()
bool GerritServer::resolveVersion(const GerritParameters &p, bool forceReload) bool GerritServer::resolveVersion(const GerritParameters &p, bool forceReload)
{ {
static GitClient *const client = GitClient::instance();
QSettings *settings = Core::ICore::settings(); QSettings *settings = Core::ICore::settings();
const QString fullVersionKey = "Gerrit/" + host + '/' + versionKey; const QString fullVersionKey = "Gerrit/" + host + '/' + versionKey;
version = settings->value(fullVersionKey).toString(); version = settings->value(fullVersionKey).toString();
@@ -321,7 +320,7 @@ bool GerritServer::resolveVersion(const GerritParameters &p, bool forceReload)
if (port) if (port)
arguments << p.portFlag << QString::number(port); arguments << p.portFlag << QString::number(port);
arguments << hostArgument() << "gerrit" << "version"; arguments << hostArgument() << "gerrit" << "version";
const CommandResult result = client->vcsSynchronousExec({}, {p.ssh, arguments}, const CommandResult result = gitClient().vcsSynchronousExec({}, {p.ssh, arguments},
RunFlags::NoOutput); RunFlags::NoOutput);
QString stdOut = result.cleanedStdOut().trimmed(); QString stdOut = result.cleanedStdOut().trimmed();
stdOut.remove("gerrit version "); stdOut.remove("gerrit version ");
@@ -330,7 +329,7 @@ bool GerritServer::resolveVersion(const GerritParameters &p, bool forceReload)
return false; return false;
} else { } else {
const QStringList arguments = curlArguments() << (url(RestUrl) + versionUrlC); const QStringList arguments = curlArguments() << (url(RestUrl) + versionUrlC);
const CommandResult result = client->vcsSynchronousExec({}, {curlBinary, arguments}, const CommandResult result = gitClient().vcsSynchronousExec({}, {curlBinary, arguments},
RunFlags::NoOutput); RunFlags::NoOutput);
// REST endpoint for version is only available from 2.8 and up. Do not consider invalid // REST endpoint for version is only available from 2.8 and up. Do not consider invalid
// if it fails. // if it fails.

View File

@@ -82,8 +82,6 @@ using namespace VcsBase;
namespace Git::Internal { namespace Git::Internal {
static GitClient *m_instance = nullptr;
static QString branchesDisplay(const QString &prefix, QStringList *branches, bool *first) static QString branchesDisplay(const QString &prefix, QStringList *branches, bool *first)
{ {
const int limit = 12; const int limit = 12;
@@ -128,7 +126,7 @@ static void stage(DiffEditorController *diffController, const QString &patch, bo
if (revert) if (revert)
args << "--reverse"; args << "--reverse";
QString errorMessage; QString errorMessage;
if (GitClient::instance()->synchronousApplyPatch(baseDir, patchFile.fileName(), if (gitClient().synchronousApplyPatch(baseDir, patchFile.fileName(),
&errorMessage, args)) { &errorMessage, args)) {
if (errorMessage.isEmpty()) { if (errorMessage.isEmpty()) {
if (revert) if (revert)
@@ -219,7 +217,7 @@ private:
auto fixRightCommit = [this](const QString &commit) { auto fixRightCommit = [this](const QString &commit) {
if (!commit.isEmpty()) if (!commit.isEmpty())
return commit; return commit;
if (m_instance->checkCommandInProgress(workingDirectory()) == GitClient::NoCommand) if (gitClient().checkCommandInProgress(workingDirectory()) == GitClient::NoCommand)
return QString(); return QString();
return QString(HEAD); return QString(HEAD);
}; };
@@ -399,7 +397,7 @@ ShowController::ShowController(IDocument *document, const QString &id)
}; };
const auto setupDescription = [this, id](Process &process) { const auto setupDescription = [this, id](Process &process) {
process.setCodec(m_instance->encoding(GitClient::EncodingCommit, workingDirectory())); process.setCodec(gitClient().encoding(GitClient::EncodingCommit, workingDirectory()));
setupCommand(process, {"show", "-s", noColorOption, showFormatC, id}); setupCommand(process, {"show", "-s", noColorOption, showFormatC, id});
VcsOutputWindow::appendCommand(process.workingDirectory(), process.commandLine()); VcsOutputWindow::appendCommand(process.workingDirectory(), process.commandLine());
setDescription(Tr::tr("Waiting for data...")); setDescription(Tr::tr("Waiting for data..."));
@@ -499,7 +497,7 @@ ShowController::ShowController(IDocument *document, const QString &id)
QStringList parents; QStringList parents;
QString errorMessage; QString errorMessage;
// TODO: it's trivial now to call below asynchonously, too // TODO: it's trivial now to call below asynchonously, too
m_instance->synchronousParentRevisions(workingDirectory(), data->m_commit, gitClient().synchronousParentRevisions(workingDirectory(), data->m_commit,
&parents, &errorMessage); &parents, &errorMessage);
data->m_follows = {busyMessage}; data->m_follows = {busyMessage};
data->m_follows.resize(parents.size()); data->m_follows.resize(parents.size());
@@ -638,7 +636,7 @@ public:
static bool gitHasRgbColors() static bool gitHasRgbColors()
{ {
const unsigned gitVersion = GitClient::instance()->gitVersion().result(); const unsigned gitVersion = gitClient().gitVersion().result();
return gitVersion >= 0x020300U; return gitVersion >= 0x020300U;
} }
@@ -754,10 +752,10 @@ static void handleConflictResponse(const VcsBase::CommandResult &result,
commit = errMatch.captured(1); commit = errMatch.captured(1);
if (commit.isEmpty() && files.isEmpty()) { if (commit.isEmpty() && files.isEmpty()) {
if (m_instance->checkCommandInProgress(workingDirectory) == GitClient::NoCommand) if (gitClient().checkCommandInProgress(workingDirectory) == GitClient::NoCommand)
m_instance->endStashScope(workingDirectory); gitClient().endStashScope(workingDirectory);
} else { } else {
m_instance->handleMergeConflicts(workingDirectory, commit, files, abortCommand); gitClient().handleMergeConflicts(workingDirectory, commit, files, abortCommand);
} }
} }
@@ -812,19 +810,21 @@ static inline void msgCannotRun(const QStringList &args, const FilePath &working
// ---------------- GitClient // ---------------- GitClient
GitClient &gitClient()
{
static GitClient client;
return client;
}
GitClient::GitClient() GitClient::GitClient()
: VcsBase::VcsBaseClientImpl(&Internal::settings()) : VcsBase::VcsBaseClientImpl(&Internal::settings())
{ {
m_instance = this;
m_gitQtcEditor = QString::fromLatin1("\"%1\" -client -block -pid %2") m_gitQtcEditor = QString::fromLatin1("\"%1\" -client -block -pid %2")
.arg(QCoreApplication::applicationFilePath()) .arg(QCoreApplication::applicationFilePath())
.arg(QCoreApplication::applicationPid()); .arg(QCoreApplication::applicationPid());
} }
GitClient *GitClient::instance() GitClient::~GitClient() = default;
{
return m_instance;
}
GitSettings &GitClient::settings() GitSettings &GitClient::settings()
{ {
@@ -3497,7 +3497,7 @@ bool GitClient::StashInfo::init(const FilePath &workingDirectory, const QString
m_pushAction = pushAction; m_pushAction = pushAction;
QString errorMessage; QString errorMessage;
QString statusOutput; QString statusOutput;
switch (m_instance->gitStatus(m_workingDir, StatusMode(NoUntracked | NoSubmodules), switch (gitClient().gitStatus(m_workingDir, StatusMode(NoUntracked | NoSubmodules),
&statusOutput, &errorMessage)) { &statusOutput, &errorMessage)) {
case GitClient::StatusChanged: case GitClient::StatusChanged:
if (m_flags & NoPrompt) if (m_flags & NoPrompt)
@@ -3550,14 +3550,14 @@ void GitClient::StashInfo::stashPrompt(const QString &command, const QString &st
msgBox.exec(); msgBox.exec();
if (msgBox.clickedButton() == discardButton) { if (msgBox.clickedButton() == discardButton) {
m_stashResult = m_instance->synchronousReset(m_workingDir, QStringList(), errorMessage) ? m_stashResult = gitClient().synchronousReset(m_workingDir, QStringList(), errorMessage) ?
StashUnchanged : StashFailed; StashUnchanged : StashFailed;
} else if (msgBox.clickedButton() == ignoreButton) { // At your own risk, so. } else if (msgBox.clickedButton() == ignoreButton) { // At your own risk, so.
m_stashResult = NotStashed; m_stashResult = NotStashed;
} else if (msgBox.clickedButton() == cancelButton) { } else if (msgBox.clickedButton() == cancelButton) {
m_stashResult = StashCanceled; m_stashResult = StashCanceled;
} else if (msgBox.clickedButton() == stashButton) { } else if (msgBox.clickedButton() == stashButton) {
const bool result = m_instance->executeSynchronousStash( const bool result = gitClient().executeSynchronousStash(
m_workingDir, creatorStashMessage(command), false, errorMessage); m_workingDir, creatorStashMessage(command), false, errorMessage);
m_stashResult = result ? StashUnchanged : StashFailed; m_stashResult = result ? StashUnchanged : StashFailed;
} else if (msgBox.clickedButton() == stashAndPopButton) { } else if (msgBox.clickedButton() == stashAndPopButton) {
@@ -3568,7 +3568,7 @@ void GitClient::StashInfo::stashPrompt(const QString &command, const QString &st
void GitClient::StashInfo::executeStash(const QString &command, QString *errorMessage) void GitClient::StashInfo::executeStash(const QString &command, QString *errorMessage)
{ {
m_message = creatorStashMessage(command); m_message = creatorStashMessage(command);
if (!m_instance->executeSynchronousStash(m_workingDir, m_message, false, errorMessage)) if (!gitClient().executeSynchronousStash(m_workingDir, m_message, false, errorMessage))
m_stashResult = StashFailed; m_stashResult = StashFailed;
else else
m_stashResult = Stashed; m_stashResult = Stashed;
@@ -3591,12 +3591,12 @@ void GitClient::StashInfo::end()
{ {
if (m_stashResult == Stashed) { if (m_stashResult == Stashed) {
QString stashName; QString stashName;
if (m_instance->stashNameFromMessage(m_workingDir, m_message, &stashName)) if (gitClient().stashNameFromMessage(m_workingDir, m_message, &stashName))
m_instance->stashPop(m_workingDir, stashName); gitClient().stashPop(m_workingDir, stashName);
} }
if (m_pushAction == NormalPush) if (m_pushAction == NormalPush)
m_instance->push(m_workingDir); gitClient().push(m_workingDir);
else if (m_pushAction == PushToGerrit) else if (m_pushAction == PushToGerrit)
GitPlugin::gerritPush(m_workingDir); GitPlugin::gerritPush(m_workingDir);
@@ -3621,7 +3621,7 @@ QString GitClient::suggestedLocalBranchName(
initialName = target.mid(target.lastIndexOf('/') + 1); initialName = target.mid(target.lastIndexOf('/') + 1);
} else { } else {
QString subject; QString subject;
instance()->synchronousLog(workingDirectory, {"-n", "1", "--format=%s", target}, gitClient().synchronousLog(workingDirectory, {"-n", "1", "--format=%s", target},
&subject, nullptr, RunFlags::NoOutput); &subject, nullptr, RunFlags::NoOutput);
initialName = subject.trimmed(); initialName = subject.trimmed();
} }
@@ -3641,14 +3641,14 @@ void GitClient::addChangeActions(QMenu *menu, const FilePath &source, const QStr
const FilePath &workingDir = fileWorkingDirectory(source); const FilePath &workingDir = fileWorkingDirectory(source);
const bool isRange = change.contains(".."); const bool isRange = change.contains("..");
menu->addAction(Tr::tr("Cherr&y-Pick %1").arg(change), [workingDir, change] { menu->addAction(Tr::tr("Cherr&y-Pick %1").arg(change), [workingDir, change] {
m_instance->synchronousCherryPick(workingDir, change); gitClient().synchronousCherryPick(workingDir, change);
}); });
menu->addAction(Tr::tr("Re&vert %1").arg(change), [workingDir, change] { menu->addAction(Tr::tr("Re&vert %1").arg(change), [workingDir, change] {
m_instance->synchronousRevert(workingDir, change); gitClient().synchronousRevert(workingDir, change);
}); });
if (!isRange) { if (!isRange) {
menu->addAction(Tr::tr("C&heckout %1").arg(change), [workingDir, change] { menu->addAction(Tr::tr("C&heckout %1").arg(change), [workingDir, change] {
m_instance->checkout(workingDir, change); gitClient().checkout(workingDir, change);
}); });
connect(menu->addAction(Tr::tr("&Interactive Rebase from %1...").arg(change)), connect(menu->addAction(Tr::tr("&Interactive Rebase from %1...").arg(change)),
&QAction::triggered, [workingDir, change] { &QAction::triggered, [workingDir, change] {
@@ -3656,7 +3656,7 @@ void GitClient::addChangeActions(QMenu *menu, const FilePath &source, const QStr
}); });
} }
QAction *logAction = menu->addAction(Tr::tr("&Log for %1").arg(change), [workingDir, change] { QAction *logAction = menu->addAction(Tr::tr("&Log for %1").arg(change), [workingDir, change] {
m_instance->log(workingDir, QString(), false, {change}); gitClient().log(workingDir, QString(), false, {change});
}); });
if (isRange) { if (isRange) {
menu->setDefaultAction(logAction); menu->setDefaultAction(logAction);
@@ -3665,13 +3665,13 @@ void GitClient::addChangeActions(QMenu *menu, const FilePath &source, const QStr
if (!filePath.isDir()) { if (!filePath.isDir()) {
menu->addAction(Tr::tr("Sh&ow file \"%1\" on revision %2").arg(filePath.fileName(), change), menu->addAction(Tr::tr("Sh&ow file \"%1\" on revision %2").arg(filePath.fileName(), change),
[workingDir, change, source] { [workingDir, change, source] {
m_instance->openShowEditor(workingDir, change, source); gitClient().openShowEditor(workingDir, change, source);
}); });
} }
menu->addAction(Tr::tr("Add &Tag for %1...").arg(change), [workingDir, change] { menu->addAction(Tr::tr("Add &Tag for %1...").arg(change), [workingDir, change] {
QString output; QString output;
QString errorMessage; QString errorMessage;
m_instance->synchronousTagCmd(workingDir, QStringList(), &output, &errorMessage); gitClient().synchronousTagCmd(workingDir, QStringList(), &output, &errorMessage);
const QStringList tags = output.split('\n'); const QStringList tags = output.split('\n');
BranchAddDialog dialog(tags, BranchAddDialog::Type::AddTag, Core::ICore::dialogParent()); BranchAddDialog dialog(tags, BranchAddDialog::Type::AddTag, Core::ICore::dialogParent());
@@ -3679,7 +3679,7 @@ void GitClient::addChangeActions(QMenu *menu, const FilePath &source, const QStr
if (dialog.exec() == QDialog::Rejected) if (dialog.exec() == QDialog::Rejected)
return; return;
m_instance->synchronousTagCmd(workingDir, {dialog.branchName(), change}, gitClient().synchronousTagCmd(workingDir, {dialog.branchName(), change},
&output, &errorMessage); &output, &errorMessage);
VcsOutputWindow::append(output); VcsOutputWindow::append(output);
if (!errorMessage.isEmpty()) if (!errorMessage.isEmpty())
@@ -3687,7 +3687,7 @@ void GitClient::addChangeActions(QMenu *menu, const FilePath &source, const QStr
}); });
auto resetChange = [workingDir, change](const QByteArray &resetType) { auto resetChange = [workingDir, change](const QByteArray &resetType) {
m_instance->reset(workingDir, QLatin1String("--" + resetType), change); gitClient().reset(workingDir, QLatin1String("--" + resetType), change);
}; };
auto resetMenu = new QMenu(Tr::tr("&Reset to Change %1").arg(change), menu); auto resetMenu = new QMenu(Tr::tr("&Reset to Change %1").arg(change), menu);
resetMenu->addAction(Tr::tr("&Hard"), std::bind(resetChange, "hard")); resetMenu->addAction(Tr::tr("&Hard"), std::bind(resetChange, "hard"));
@@ -3698,18 +3698,18 @@ void GitClient::addChangeActions(QMenu *menu, const FilePath &source, const QStr
menu->addAction((isRange ? Tr::tr("Di&ff %1") : Tr::tr("Di&ff Against %1")).arg(change), menu->addAction((isRange ? Tr::tr("Di&ff %1") : Tr::tr("Di&ff Against %1")).arg(change),
[workingDir, change] { [workingDir, change] {
m_instance->diffRepository(workingDir, change, {}); gitClient().diffRepository(workingDir, change, {});
}); });
if (!isRange) { if (!isRange) {
if (!m_instance->m_diffCommit.isEmpty()) { if (!gitClient().m_diffCommit.isEmpty()) {
menu->addAction(Tr::tr("Diff &Against Saved %1").arg(m_instance->m_diffCommit), menu->addAction(Tr::tr("Diff &Against Saved %1").arg(gitClient().m_diffCommit),
[workingDir, change] { [workingDir, change] {
m_instance->diffRepository(workingDir, m_instance->m_diffCommit, change); gitClient().diffRepository(workingDir, gitClient().m_diffCommit, change);
m_instance->m_diffCommit.clear(); gitClient().m_diffCommit.clear();
}); });
} }
menu->addAction(Tr::tr("&Save for Diff"), [change] { menu->addAction(Tr::tr("&Save for Diff"), [change] {
m_instance->m_diffCommit = change; gitClient().m_diffCommit = change;
}); });
} }
} }

View File

@@ -120,7 +120,7 @@ public:
}; };
GitClient(); GitClient();
static GitClient *instance(); ~GitClient();
Utils::FilePath vcsBinary() const override; Utils::FilePath vcsBinary() const override;
QFuture<unsigned> gitVersion() const; QFuture<unsigned> gitVersion() const;
@@ -406,6 +406,8 @@ private:
bool m_disableEditor = false; bool m_disableEditor = false;
}; };
GITSHARED_EXPORT GitClient &gitClient();
class GitRemote : public Core::IVersionControl::RepoUrl class GitRemote : public Core::IVersionControl::RepoUrl
{ {
public: public:

View File

@@ -224,7 +224,7 @@ void GitEditorWidget::applyDiffChunk(const DiffChunk& chunk, PatchAction patchAc
if (patchAction == PatchAction::Revert) if (patchAction == PatchAction::Revert)
args << "--reverse"; args << "--reverse";
QString errorMessage; QString errorMessage;
if (GitClient::instance()->synchronousApplyPatch(baseDir, patchFile.fileName(), &errorMessage, args)) { if (gitClient().synchronousApplyPatch(baseDir, patchFile.fileName(), &errorMessage, args)) {
if (errorMessage.isEmpty()) if (errorMessage.isEmpty())
VcsOutputWindow::append(Tr::tr("Chunk successfully staged")); VcsOutputWindow::append(Tr::tr("Chunk successfully staged"));
else else
@@ -244,7 +244,7 @@ void GitEditorWidget::init()
const bool isRebaseEditor = editorId == Git::Constants::GIT_REBASE_EDITOR_ID; const bool isRebaseEditor = editorId == Git::Constants::GIT_REBASE_EDITOR_ID;
if (!isCommitEditor && !isRebaseEditor) if (!isCommitEditor && !isRebaseEditor)
return; return;
const QChar commentChar = GitClient::instance()->commentChar(source()); const QChar commentChar = gitClient().commentChar(source());
if (isCommitEditor) if (isCommitEditor)
textDocument()->setSyntaxHighlighter(new GitSubmitHighlighter(commentChar)); textDocument()->setSyntaxHighlighter(new GitSubmitHighlighter(commentChar));
else if (isRebaseEditor) else if (isRebaseEditor)
@@ -274,14 +274,14 @@ void GitEditorWidget::aboutToOpen(const FilePath &filePath, const FilePath &real
|| editorId == Git::Constants::GIT_REBASE_EDITOR_ID) { || editorId == Git::Constants::GIT_REBASE_EDITOR_ID) {
const FilePath gitPath = filePath.absolutePath(); const FilePath gitPath = filePath.absolutePath();
setSource(gitPath); setSource(gitPath);
textDocument()->setCodec(GitClient::instance()->encoding(GitClient::EncodingCommit, gitPath)); textDocument()->setCodec(gitClient().encoding(GitClient::EncodingCommit, gitPath));
} }
} }
QString GitEditorWidget::decorateVersion(const QString &revision) const QString GitEditorWidget::decorateVersion(const QString &revision) const
{ {
// Format verbose, SHA1 being first token // Format verbose, SHA1 being first token
return GitClient::instance()->synchronousShortDescription(sourceWorkingDirectory(), revision); return gitClient().synchronousShortDescription(sourceWorkingDirectory(), revision);
} }
QStringList GitEditorWidget::annotationPreviousVersions(const QString &revision) const QStringList GitEditorWidget::annotationPreviousVersions(const QString &revision) const
@@ -289,7 +289,7 @@ QStringList GitEditorWidget::annotationPreviousVersions(const QString &revision)
QStringList revisions; QStringList revisions;
QString errorMessage; QString errorMessage;
// Get the SHA1's of the file. // Get the SHA1's of the file.
if (!GitClient::instance()->synchronousParentRevisions( if (!gitClient().synchronousParentRevisions(
sourceWorkingDirectory(), revision, &revisions, &errorMessage)) { sourceWorkingDirectory(), revision, &revisions, &errorMessage)) {
VcsOutputWindow::appendSilently(errorMessage); VcsOutputWindow::appendSilently(errorMessage);
return QStringList(); return QStringList();
@@ -299,7 +299,7 @@ QStringList GitEditorWidget::annotationPreviousVersions(const QString &revision)
bool GitEditorWidget::isValidRevision(const QString &revision) const bool GitEditorWidget::isValidRevision(const QString &revision) const
{ {
return GitClient::instance()->isValidRevision(revision); return gitClient().isValidRevision(revision);
} }
void GitEditorWidget::addChangeActions(QMenu *menu, const QString &change) void GitEditorWidget::addChangeActions(QMenu *menu, const QString &change)

View File

@@ -135,8 +135,8 @@ static void runGitGrep(QPromise<SearchResultItems> &promise, const FileFindParam
const GitGrepParameters &gitParameters) const GitGrepParameters &gitParameters)
{ {
const auto setupProcess = [&parameters, gitParameters](Process &process) { const auto setupProcess = [&parameters, gitParameters](Process &process) {
const FilePath vcsBinary = GitClient::instance()->vcsBinary(); const FilePath vcsBinary = gitClient().vcsBinary();
const Environment environment = GitClient::instance()->processEnvironment(); const Environment environment = gitClient().processEnvironment();
QStringList arguments = { QStringList arguments = {
"-c", "color.grep.match=bold red", "-c", "color.grep.match=bold red",
@@ -189,7 +189,7 @@ static bool isGitDirectory(const FilePath &path)
return gitVc == VcsManager::findVersionControlForDirectory(path); return gitVc == VcsManager::findVersionControlForDirectory(path);
} }
GitGrep::GitGrep(GitClient *client) GitGrep::GitGrep()
{ {
m_widget = new QWidget; m_widget = new QWidget;
auto layout = new QHBoxLayout(m_widget); auto layout = new QHBoxLayout(m_widget);
@@ -202,7 +202,7 @@ GitGrep::GitGrep(GitClient *client)
m_treeLineEdit->setValidator(new QRegularExpressionValidator(refExpression, this)); m_treeLineEdit->setValidator(new QRegularExpressionValidator(refExpression, this));
layout->addWidget(m_treeLineEdit); layout->addWidget(m_treeLineEdit);
// asynchronously check git version, add "recurse submodules" option if available // asynchronously check git version, add "recurse submodules" option if available
Utils::onResultReady(client->gitVersion(), this, Utils::onResultReady(gitClient().gitVersion(), this,
[this, pLayout = QPointer<QHBoxLayout>(layout)](unsigned version) { [this, pLayout = QPointer<QHBoxLayout>(layout)](unsigned version) {
if (version >= 0x021300 && pLayout) { if (version >= 0x021300 && pLayout) {
m_recurseSubmodules = new QCheckBox(Tr::tr("Recurse submodules")); m_recurseSubmodules = new QCheckBox(Tr::tr("Recurse submodules"));
@@ -271,7 +271,7 @@ EditorOpener GitGrep::editorOpener() const
if (params.ref.isEmpty() || itemPath.isEmpty()) if (params.ref.isEmpty() || itemPath.isEmpty())
return nullptr; return nullptr;
const FilePath path = FilePath::fromUserInput(itemPath.first()); const FilePath path = FilePath::fromUserInput(itemPath.first());
IEditor *editor = GitClient::instance()->openShowEditor( IEditor *editor = gitClient().openShowEditor(
parameters.searchDir, params.ref, path, GitClient::ShowEditor::OnlyIfDifferent); parameters.searchDir, params.ref, path, GitClient::ShowEditor::OnlyIfDifferent);
if (editor) if (editor)
editor->gotoLine(item.mainRange().begin.line, item.mainRange().begin.column); editor->gotoLine(item.mainRange().begin.line, item.mainRange().begin.column);

View File

@@ -13,13 +13,12 @@ namespace Utils { class FancyLineEdit; }
namespace Git::Internal { namespace Git::Internal {
class GitClient;
class GitGrepParameters; class GitGrepParameters;
class GitGrep : public TextEditor::SearchEngine class GitGrep : public TextEditor::SearchEngine
{ {
public: public:
explicit GitGrep(GitClient *client); GitGrep();
~GitGrep() override; ~GitGrep() override;
QString title() const override; QString title() const override;

View File

@@ -216,7 +216,7 @@ public:
showAction->setIcon(Utils::Icons::ZOOM.icon()); showAction->setIcon(Utils::Icons::ZOOM.icon());
showAction->setToolTip(TextEditor::Tr::tr("Show Commit %1").arg(info.sha1.left(8))); showAction->setToolTip(TextEditor::Tr::tr("Show Commit %1").arg(info.sha1.left(8)));
QObject::connect(showAction, &QAction::triggered, [info] { QObject::connect(showAction, &QAction::triggered, [info] {
GitClient::instance()->show(info.filePath, info.sha1); gitClient().show(info.filePath, info.sha1);
}); });
return QList<QAction *>{copyToClipboardAction, showAction}; return QList<QAction *>{copyToClipboardAction, showAction};
}); });
@@ -267,7 +267,7 @@ public:
bool vcsCreateRepository(const FilePath &directory) final; bool vcsCreateRepository(const FilePath &directory) final;
void vcsAnnotate(const FilePath &filePath, int line) final; void vcsAnnotate(const FilePath &filePath, int line) final;
void vcsDescribe(const FilePath &source, const QString &id) final { m_gitClient.show(source, id); }; void vcsDescribe(const FilePath &source, const QString &id) final { gitClient().show(source, id); }
QString vcsTopic(const FilePath &directory) final; QString vcsTopic(const FilePath &directory) final;
VcsCommand *createInitialCheckoutCommand(const QString &url, VcsCommand *createInitialCheckoutCommand(const QString &url,
@@ -290,9 +290,9 @@ public:
bool handleLink(const FilePath &workingDirectory, const QString &reference) final bool handleLink(const FilePath &workingDirectory, const QString &reference) final
{ {
if (reference.contains("..")) if (reference.contains(".."))
GitClient::instance()->log(workingDirectory, {}, false, {reference}); gitClient().log(workingDirectory, {}, false, {reference});
else else
GitClient::instance()->show(workingDirectory, reference); gitClient().show(workingDirectory, reference);
return true; return true;
} }
@@ -422,7 +422,6 @@ public:
ParameterAction *m_applyCurrentFilePatchAction = nullptr; ParameterAction *m_applyCurrentFilePatchAction = nullptr;
Gerrit::Internal::GerritPlugin m_gerritPlugin; Gerrit::Internal::GerritPlugin m_gerritPlugin;
GitClient m_gitClient;
QPointer<StashDialog> m_stashDialog; QPointer<StashDialog> m_stashDialog;
BranchViewFactory m_branchViewFactory; BranchViewFactory m_branchViewFactory;
QPointer<RemoteDialog> m_remoteDialog; QPointer<RemoteDialog> m_remoteDialog;
@@ -438,7 +437,7 @@ public:
QMetaObject::Connection m_blameCursorPosConn; QMetaObject::Connection m_blameCursorPosConn;
QMetaObject::Connection m_documentChangedConn; QMetaObject::Connection m_documentChangedConn;
GitGrep gitGrep{&m_gitClient}; GitGrep gitGrep;
VcsEditorFactory svnLogEditorFactory { VcsEditorFactory svnLogEditorFactory {
&svnLogEditorParameters, &svnLogEditorParameters,
@@ -488,25 +487,20 @@ static GitPluginPrivate *dd = nullptr;
class GitTopicCache : public IVersionControl::TopicCache class GitTopicCache : public IVersionControl::TopicCache
{ {
public: public:
GitTopicCache(GitClient *client) : GitTopicCache() {}
m_client(client)
{ }
protected: protected:
FilePath trackFile(const FilePath &repository) override FilePath trackFile(const FilePath &repository) override
{ {
const FilePath gitDir = m_client->findGitDirForRepository(repository); const FilePath gitDir = gitClient().findGitDirForRepository(repository);
return gitDir.isEmpty() ? FilePath() : gitDir / "HEAD"; return gitDir.isEmpty() ? FilePath() : gitDir / "HEAD";
} }
QString refreshTopic(const FilePath &repository) override QString refreshTopic(const FilePath &repository) override
{ {
emit dd->repositoryChanged(repository); emit dd->repositoryChanged(repository);
return m_client->synchronousTopic(repository); return gitClient().synchronousTopic(repository);
} }
private:
GitClient *m_client;
}; };
GitPluginPrivate::~GitPluginPrivate() GitPluginPrivate::~GitPluginPrivate()
@@ -547,11 +541,6 @@ bool GitPluginPrivate::isCommitEditorOpen() const
return !m_commitMessageFileName.isEmpty(); return !m_commitMessageFileName.isEmpty();
} }
GitClient *GitPlugin::client()
{
return &dd->m_gitClient;
}
IVersionControl *GitPlugin::versionControl() IVersionControl *GitPlugin::versionControl()
{ {
return dd; return dd;
@@ -670,7 +659,7 @@ QAction *GitPluginPrivate::createRepositoryAction(ActionContainer *ac, const QSt
{ {
auto cb = [this, func] { auto cb = [this, func] {
QTC_ASSERT(currentState().hasTopLevel(), return); QTC_ASSERT(currentState().hasTopLevel(), return);
(m_gitClient.*func)(currentState().topLevel()); (gitClient().*func)(currentState().topLevel());
}; };
// Set the member func as data and connect to GitClient method // Set the member func as data and connect to GitClient method
return createRepositoryAction(ac, text, id, context, addToLocator, cb, keys); return createRepositoryAction(ac, text, id, context, addToLocator, cb, keys);
@@ -701,12 +690,12 @@ GitPluginPrivate::GitPluginPrivate()
{ {
dd = this; dd = this;
setTopicCache(new GitTopicCache(&m_gitClient)); setTopicCache(new GitTopicCache);
m_fileActions.reserve(10); m_fileActions.reserve(10);
m_projectActions.reserve(10); m_projectActions.reserve(10);
m_repositoryActions.reserve(50); m_repositoryActions.reserve(50);
m_codec = GitClient::instance()->defaultCommitEncoding(); m_codec = gitClient().defaultCommitEncoding();
Context context(Constants::GIT_CONTEXT); Context context(Constants::GIT_CONTEXT);
@@ -861,28 +850,28 @@ GitPluginPrivate::GitPluginPrivate()
}; };
m_abortMergeAction = createAction(Tr::tr("Abort Merge", "Avoid translating \"Merge\""), "Git.MergeAbort", m_abortMergeAction = createAction(Tr::tr("Abort Merge", "Avoid translating \"Merge\""), "Git.MergeAbort",
std::bind(&GitClient::synchronousMerge, &m_gitClient, _1, QString("--abort"), true)); std::bind(&GitClient::synchronousMerge, &gitClient(), _1, QString("--abort"), true));
m_abortRebaseAction = createAction(Tr::tr("Abort Rebase", "Avoid translating \"Rebase\""), "Git.RebaseAbort", m_abortRebaseAction = createAction(Tr::tr("Abort Rebase", "Avoid translating \"Rebase\""), "Git.RebaseAbort",
std::bind(&GitClient::rebase, &m_gitClient, _1, QString("--abort"))); std::bind(&GitClient::rebase, &gitClient(), _1, QString("--abort")));
m_continueRebaseAction = createAction(Tr::tr("Continue Rebase"), "Git.RebaseContinue", m_continueRebaseAction = createAction(Tr::tr("Continue Rebase"), "Git.RebaseContinue",
std::bind(&GitClient::rebase, &m_gitClient, _1, QString("--continue"))); std::bind(&GitClient::rebase, &gitClient(), _1, QString("--continue")));
m_skipRebaseAction = createAction(Tr::tr("Skip Rebase"), "Git.RebaseSkip", m_skipRebaseAction = createAction(Tr::tr("Skip Rebase"), "Git.RebaseSkip",
std::bind(&GitClient::rebase, &m_gitClient, _1, QString("--skip"))); std::bind(&GitClient::rebase, &gitClient(), _1, QString("--skip")));
m_abortCherryPickAction = createAction(Tr::tr("Abort Cherry Pick", "Avoid translating \"Cherry Pick\""), "Git.CherryPickAbort", m_abortCherryPickAction = createAction(Tr::tr("Abort Cherry Pick", "Avoid translating \"Cherry Pick\""), "Git.CherryPickAbort",
std::bind(&GitClient::synchronousCherryPick, &m_gitClient, _1, QString("--abort"))); std::bind(&GitClient::synchronousCherryPick, &gitClient(), _1, QString("--abort")));
m_continueCherryPickAction = createAction(Tr::tr("Continue Cherry Pick"), "Git.CherryPickContinue", m_continueCherryPickAction = createAction(Tr::tr("Continue Cherry Pick"), "Git.CherryPickContinue",
std::bind(&GitClient::cherryPick, &m_gitClient, _1, QString("--continue"))); std::bind(&GitClient::cherryPick, &gitClient(), _1, QString("--continue")));
m_abortRevertAction = createAction(Tr::tr("Abort Revert", "Avoid translating \"Revert\""), "Git.RevertAbort", m_abortRevertAction = createAction(Tr::tr("Abort Revert", "Avoid translating \"Revert\""), "Git.RevertAbort",
std::bind(&GitClient::synchronousRevert, &m_gitClient, _1, QString("--abort"))); std::bind(&GitClient::synchronousRevert, &gitClient(), _1, QString("--abort")));
m_continueRevertAction = createAction(Tr::tr("Continue Revert"), "Git.RevertContinue", m_continueRevertAction = createAction(Tr::tr("Continue Revert"), "Git.RevertContinue",
std::bind(&GitClient::revert, &m_gitClient, _1, QString("--continue"))); std::bind(&GitClient::revert, &gitClient(), _1, QString("--continue")));
// -------------- // --------------
localRepositoryMenu->addSeparator(context); localRepositoryMenu->addSeparator(context);
@@ -1076,7 +1065,7 @@ void GitPluginPrivate::diffCurrentFile()
{ {
const VcsBasePluginState state = currentState(); const VcsBasePluginState state = currentState();
QTC_ASSERT(state.hasFile(), return); QTC_ASSERT(state.hasFile(), return);
m_gitClient.diffFile(state.currentFileTopLevel(), state.relativeCurrentFile()); gitClient().diffFile(state.currentFileTopLevel(), state.relativeCurrentFile());
} }
void GitPluginPrivate::diffCurrentProject() void GitPluginPrivate::diffCurrentProject()
@@ -1085,16 +1074,16 @@ void GitPluginPrivate::diffCurrentProject()
QTC_ASSERT(state.hasProject(), return); QTC_ASSERT(state.hasProject(), return);
const QString relativeProject = state.relativeCurrentProject(); const QString relativeProject = state.relativeCurrentProject();
if (relativeProject.isEmpty()) if (relativeProject.isEmpty())
m_gitClient.diffRepository(state.currentProjectTopLevel()); gitClient().diffRepository(state.currentProjectTopLevel());
else else
m_gitClient.diffProject(state.currentProjectTopLevel(), relativeProject); gitClient().diffProject(state.currentProjectTopLevel(), relativeProject);
} }
void GitPluginPrivate::logFile() void GitPluginPrivate::logFile()
{ {
const VcsBasePluginState state = currentState(); const VcsBasePluginState state = currentState();
QTC_ASSERT(state.hasFile(), return); QTC_ASSERT(state.hasFile(), return);
m_gitClient.log(state.currentFileTopLevel(), state.relativeCurrentFile(), true); gitClient().log(state.currentFileTopLevel(), state.relativeCurrentFile(), true);
} }
void GitPluginPrivate::blameFile() void GitPluginPrivate::blameFile()
@@ -1132,7 +1121,7 @@ void GitPluginPrivate::blameFile()
const FilePath fileName = state.currentFile().canonicalPath(); const FilePath fileName = state.currentFile().canonicalPath();
FilePath topLevel; FilePath topLevel;
VcsManager::findVersionControlForDirectory(fileName.parentDir(), &topLevel); VcsManager::findVersionControlForDirectory(fileName.parentDir(), &topLevel);
m_gitClient.annotate(topLevel, fileName.relativeChildPath(topLevel).toString(), gitClient().annotate(topLevel, fileName.relativeChildPath(topLevel).toString(),
lineNumber, {}, extraOptions, firstLine); lineNumber, {}, extraOptions, firstLine);
} }
@@ -1140,21 +1129,21 @@ void GitPluginPrivate::logProject()
{ {
const VcsBasePluginState state = currentState(); const VcsBasePluginState state = currentState();
QTC_ASSERT(state.hasProject(), return); QTC_ASSERT(state.hasProject(), return);
m_gitClient.log(state.currentProjectTopLevel(), state.relativeCurrentProject()); gitClient().log(state.currentProjectTopLevel(), state.relativeCurrentProject());
} }
void GitPluginPrivate::logRepository() void GitPluginPrivate::logRepository()
{ {
const VcsBasePluginState state = currentState(); const VcsBasePluginState state = currentState();
QTC_ASSERT(state.hasTopLevel(), return); QTC_ASSERT(state.hasTopLevel(), return);
m_gitClient.log(state.topLevel()); gitClient().log(state.topLevel());
} }
void GitPluginPrivate::reflogRepository() void GitPluginPrivate::reflogRepository()
{ {
const VcsBasePluginState state = currentState(); const VcsBasePluginState state = currentState();
QTC_ASSERT(state.hasTopLevel(), return); QTC_ASSERT(state.hasTopLevel(), return);
m_gitClient.reflog(state.topLevel()); gitClient().reflog(state.topLevel());
} }
void GitPluginPrivate::undoFileChanges(bool revertStaging) void GitPluginPrivate::undoFileChanges(bool revertStaging)
@@ -1166,7 +1155,7 @@ void GitPluginPrivate::undoFileChanges(bool revertStaging)
const VcsBasePluginState state = currentState(); const VcsBasePluginState state = currentState();
QTC_ASSERT(state.hasFile(), return); QTC_ASSERT(state.hasFile(), return);
FileChangeBlocker fcb(state.currentFile()); FileChangeBlocker fcb(state.currentFile());
m_gitClient.revertFiles({state.currentFile().toString()}, revertStaging); gitClient().revertFiles({state.currentFile().toString()}, revertStaging);
} }
class ResetItemDelegate : public LogItemDelegate class ResetItemDelegate : public LogItemDelegate
@@ -1208,7 +1197,7 @@ void GitPluginPrivate::resetRepository()
ResetItemDelegate delegate(dialog.widget()); ResetItemDelegate delegate(dialog.widget());
dialog.setWindowTitle(Tr::tr("Undo Changes to %1").arg(topLevel.toUserOutput())); dialog.setWindowTitle(Tr::tr("Undo Changes to %1").arg(topLevel.toUserOutput()));
if (dialog.runDialog(topLevel, {}, LogChangeWidget::IncludeRemotes)) if (dialog.runDialog(topLevel, {}, LogChangeWidget::IncludeRemotes))
m_gitClient.reset(topLevel, dialog.resetFlag(), dialog.commit()); gitClient().reset(topLevel, dialog.resetFlag(), dialog.commit());
} }
void GitPluginPrivate::recoverDeletedFiles() void GitPluginPrivate::recoverDeletedFiles()
@@ -1217,7 +1206,7 @@ void GitPluginPrivate::recoverDeletedFiles()
return; return;
const VcsBasePluginState state = currentState(); const VcsBasePluginState state = currentState();
QTC_ASSERT(state.hasTopLevel(), return); QTC_ASSERT(state.hasTopLevel(), return);
m_gitClient.recoverDeletedFiles(state.topLevel()); gitClient().recoverDeletedFiles(state.topLevel());
} }
void GitPluginPrivate::startRebase() void GitPluginPrivate::startRebase()
@@ -1233,7 +1222,7 @@ void GitPluginPrivate::startRebaseFromCommit(const FilePath &workingDirectory, Q
{ {
if (!DocumentManager::saveAllModifiedDocuments()) if (!DocumentManager::saveAllModifiedDocuments())
return; return;
if (workingDirectory.isEmpty() || !m_gitClient.canRebase(workingDirectory)) if (workingDirectory.isEmpty() || !gitClient().canRebase(workingDirectory))
return; return;
if (commit.isEmpty()) { if (commit.isEmpty()) {
@@ -1245,8 +1234,8 @@ void GitPluginPrivate::startRebaseFromCommit(const FilePath &workingDirectory, Q
commit = dialog.commit(); commit = dialog.commit();
} }
if (m_gitClient.beginStashScope(workingDirectory, "Rebase-i")) if (gitClient().beginStashScope(workingDirectory, "Rebase-i"))
m_gitClient.interactiveRebase(workingDirectory, commit, false); gitClient().interactiveRebase(workingDirectory, commit, false);
} }
void GitPluginPrivate::startChangeRelatedAction(const Id &id) void GitPluginPrivate::startChangeRelatedAction(const Id &id)
@@ -1271,15 +1260,15 @@ void GitPluginPrivate::startChangeRelatedAction(const Id &id)
const int colon = change.indexOf(':'); const int colon = change.indexOf(':');
if (colon > 0) { if (colon > 0) {
const FilePath path = workingDirectory.resolvePath(change.mid(colon + 1)); const FilePath path = workingDirectory.resolvePath(change.mid(colon + 1));
m_gitClient.openShowEditor(workingDirectory, change.left(colon), path); gitClient().openShowEditor(workingDirectory, change.left(colon), path);
} else { } else {
m_gitClient.show(workingDirectory, change); gitClient().show(workingDirectory, change);
} }
return; return;
} }
if (dialog.command() == Archive) { if (dialog.command() == Archive) {
m_gitClient.archive(workingDirectory, change); gitClient().archive(workingDirectory, change);
return; return;
} }
@@ -1288,13 +1277,13 @@ void GitPluginPrivate::startChangeRelatedAction(const Id &id)
switch (dialog.command()) { switch (dialog.command()) {
case CherryPick: case CherryPick:
m_gitClient.synchronousCherryPick(workingDirectory, change); gitClient().synchronousCherryPick(workingDirectory, change);
break; break;
case Revert: case Revert:
m_gitClient.synchronousRevert(workingDirectory, change); gitClient().synchronousRevert(workingDirectory, change);
break; break;
case Checkout: case Checkout:
m_gitClient.checkout(workingDirectory, change); gitClient().checkout(workingDirectory, change);
break; break;
default: default:
return; return;
@@ -1305,21 +1294,21 @@ void GitPluginPrivate::stageFile()
{ {
const VcsBasePluginState state = currentState(); const VcsBasePluginState state = currentState();
QTC_ASSERT(state.hasFile(), return); QTC_ASSERT(state.hasFile(), return);
m_gitClient.addFile(state.currentFileTopLevel(), state.relativeCurrentFile()); gitClient().addFile(state.currentFileTopLevel(), state.relativeCurrentFile());
} }
void GitPluginPrivate::unstageFile() void GitPluginPrivate::unstageFile()
{ {
const VcsBasePluginState state = currentState(); const VcsBasePluginState state = currentState();
QTC_ASSERT(state.hasFile(), return); QTC_ASSERT(state.hasFile(), return);
m_gitClient.synchronousReset(state.currentFileTopLevel(), {state.relativeCurrentFile()}); gitClient().synchronousReset(state.currentFileTopLevel(), {state.relativeCurrentFile()});
} }
void GitPluginPrivate::gitkForCurrentFile() void GitPluginPrivate::gitkForCurrentFile()
{ {
const VcsBasePluginState state = currentState(); const VcsBasePluginState state = currentState();
QTC_ASSERT(state.hasFile(), return); QTC_ASSERT(state.hasFile(), return);
m_gitClient.launchGitK(state.currentFileTopLevel(), state.relativeCurrentFile()); gitClient().launchGitK(state.currentFileTopLevel(), state.relativeCurrentFile());
} }
void GitPluginPrivate::gitkForCurrentFolder() void GitPluginPrivate::gitkForCurrentFolder()
@@ -1330,7 +1319,7 @@ void GitPluginPrivate::gitkForCurrentFolder()
/* /*
* entire lower part of the code can be easily replaced with one line: * entire lower part of the code can be easily replaced with one line:
* *
* m_gitClient.launchGitK(dir.currentFileDirectory(), "."); * gitClient().launchGitK(dir.currentFileDirectory(), ".");
* *
* However, there is a bug in gitk in version 1.7.9.5, and if you run above * However, there is a bug in gitk in version 1.7.9.5, and if you run above
* command, there will be no documents listed in lower right section. * command, there will be no documents listed in lower right section.
@@ -1343,12 +1332,12 @@ void GitPluginPrivate::gitkForCurrentFolder()
*/ */
QDir dir(state.currentFileDirectory().toString()); QDir dir(state.currentFileDirectory().toString());
if (QFileInfo(dir,".git").exists() || dir.cd(".git")) { if (QFileInfo(dir,".git").exists() || dir.cd(".git")) {
m_gitClient.launchGitK(state.currentFileDirectory()); gitClient().launchGitK(state.currentFileDirectory());
} else { } else {
QString folderName = dir.absolutePath(); QString folderName = dir.absolutePath();
dir.cdUp(); dir.cdUp();
folderName = folderName.remove(0, dir.absolutePath().length() + 1); folderName = folderName.remove(0, dir.absolutePath().length() + 1);
m_gitClient.launchGitK(FilePath::fromString(dir.absolutePath()), folderName); gitClient().launchGitK(FilePath::fromString(dir.absolutePath()), folderName);
} }
} }
@@ -1356,14 +1345,14 @@ void GitPluginPrivate::gitGui()
{ {
const VcsBasePluginState state = currentState(); const VcsBasePluginState state = currentState();
QTC_ASSERT(state.hasTopLevel(), return); QTC_ASSERT(state.hasTopLevel(), return);
m_gitClient.launchGitGui(state.topLevel()); gitClient().launchGitGui(state.topLevel());
} }
void GitPluginPrivate::gitBash() void GitPluginPrivate::gitBash()
{ {
const VcsBasePluginState state = currentState(); const VcsBasePluginState state = currentState();
QTC_ASSERT(state.hasTopLevel(), return); QTC_ASSERT(state.hasTopLevel(), return);
m_gitClient.launchGitBash(state.topLevel()); gitClient().launchGitBash(state.topLevel());
} }
void GitPluginPrivate::startCommit(CommitType commitType) void GitPluginPrivate::startCommit(CommitType commitType)
@@ -1383,7 +1372,7 @@ void GitPluginPrivate::startCommit(CommitType commitType)
QString errorMessage, commitTemplate; QString errorMessage, commitTemplate;
CommitData data(commitType); CommitData data(commitType);
if (!m_gitClient.getCommitData(state.topLevel(), &commitTemplate, data, &errorMessage)) { if (!gitClient().getCommitData(state.topLevel(), &commitTemplate, data, &errorMessage)) {
VcsOutputWindow::appendError(errorMessage); VcsOutputWindow::appendError(errorMessage);
return; return;
} }
@@ -1410,7 +1399,7 @@ void GitPluginPrivate::updateVersionWarning()
QPointer<IDocument> curDocument = EditorManager::currentDocument(); QPointer<IDocument> curDocument = EditorManager::currentDocument();
if (!curDocument) if (!curDocument)
return; return;
Utils::onResultReady(m_gitClient.gitVersion(), this, [curDocument](unsigned version) { Utils::onResultReady(gitClient().gitVersion(), this, [curDocument](unsigned version) {
if (!curDocument || !version || version >= minimumRequiredVersion) if (!curDocument || !version || version >= minimumRequiredVersion)
return; return;
InfoBar *infoBar = curDocument->infoBar(); InfoBar *infoBar = curDocument->infoBar();
@@ -1585,7 +1574,7 @@ void GitPluginPrivate::instantBlame()
const CommitInfo info = parseBlameOutput(output.split('\n'), filePath, m_author); const CommitInfo info = parseBlameOutput(output.split('\n'), filePath, m_author);
m_blameMark.reset(new BlameMark(filePath, line, info)); m_blameMark.reset(new BlameMark(filePath, line, info));
}; };
GitClient::instance()->vcsExecWithHandler(workingDirectory, gitClient().vcsExecWithHandler(workingDirectory,
{"blame", "-p", "-L", lineString, "--", filePath.toString()}, {"blame", "-p", "-L", lineString, "--", filePath.toString()},
this, commandHandler, RunFlags::NoOutput, m_codec); this, commandHandler, RunFlags::NoOutput, m_codec);
} }
@@ -1615,7 +1604,7 @@ bool GitPluginPrivate::refreshWorkingDirectory(const FilePath &workingDirectory)
const QString codecName = result.cleanedStdOut().trimmed(); const QString codecName = result.cleanedStdOut().trimmed();
codec = QTextCodec::codecForName(codecName.toUtf8()); codec = QTextCodec::codecForName(codecName.toUtf8());
} else { } else {
codec = GitClient::instance()->defaultCommitEncoding(); codec = gitClient().defaultCommitEncoding();
} }
if (m_codec != codec) { if (m_codec != codec) {
@@ -1623,13 +1612,13 @@ bool GitPluginPrivate::refreshWorkingDirectory(const FilePath &workingDirectory)
forceInstantBlame(); forceInstantBlame();
} }
}; };
GitClient::instance()->readConfigAsync(workingDirectory, {"config", "i18n.commitEncoding"}, gitClient().readConfigAsync(workingDirectory, {"config", "i18n.commitEncoding"},
commitCodecHandler); commitCodecHandler);
const auto authorHandler = [this, workingDirectory](const CommandResult &result) { const auto authorHandler = [this, workingDirectory](const CommandResult &result) {
if (result.result() == ProcessResult::FinishedWithSuccess) { if (result.result() == ProcessResult::FinishedWithSuccess) {
const QString authorInfo = result.cleanedStdOut().trimmed(); const QString authorInfo = result.cleanedStdOut().trimmed();
const Author author = GitClient::instance()->parseAuthor(authorInfo); const Author author = gitClient().parseAuthor(authorInfo);
if (m_author != author) { if (m_author != author) {
m_author = author; m_author = author;
@@ -1637,7 +1626,7 @@ bool GitPluginPrivate::refreshWorkingDirectory(const FilePath &workingDirectory)
} }
} }
}; };
GitClient::instance()->readConfigAsync(workingDirectory, {"var", "GIT_AUTHOR_IDENT"}, gitClient().readConfigAsync(workingDirectory, {"var", "GIT_AUTHOR_IDENT"},
authorHandler); authorHandler);
return true; return true;
@@ -1693,7 +1682,7 @@ bool GitPluginPrivate::activateCommit()
if (!DocumentManager::saveDocument(editorDocument)) if (!DocumentManager::saveDocument(editorDocument))
return false; return false;
if (!m_gitClient.addAndCommit(m_submitRepository, editor->panelData(), commitType, if (!gitClient().addAndCommit(m_submitRepository, editor->panelData(), commitType,
amendSHA1, m_commitMessageFileName, model)) { amendSHA1, m_commitMessageFileName, model)) {
editor->updateFileModel(); editor->updateFileModel();
return false; return false;
@@ -1701,15 +1690,15 @@ bool GitPluginPrivate::activateCommit()
} }
cleanCommitMessageFile(); cleanCommitMessageFile();
if (commitType == FixupCommit) { if (commitType == FixupCommit) {
if (!m_gitClient.beginStashScope(m_submitRepository, "Rebase-fixup", if (!gitClient().beginStashScope(m_submitRepository, "Rebase-fixup",
NoPrompt, editor->panelData().pushAction)) { NoPrompt, editor->panelData().pushAction)) {
return false; return false;
} }
m_gitClient.interactiveRebase(m_submitRepository, amendSHA1, true); gitClient().interactiveRebase(m_submitRepository, amendSHA1, true);
} else { } else {
m_gitClient.continueCommandIfNeeded(m_submitRepository); gitClient().continueCommandIfNeeded(m_submitRepository);
if (editor->panelData().pushAction == NormalPush) { if (editor->panelData().pushAction == NormalPush) {
m_gitClient.push(m_submitRepository); gitClient().push(m_submitRepository);
} else if (editor->panelData().pushAction == PushToGerrit) { } else if (editor->panelData().pushAction == PushToGerrit) {
connect(editor, &QObject::destroyed, this, &GitPluginPrivate::delayedPushToGerrit, connect(editor, &QObject::destroyed, this, &GitPluginPrivate::delayedPushToGerrit,
Qt::QueuedConnection); Qt::QueuedConnection);
@@ -1721,7 +1710,7 @@ bool GitPluginPrivate::activateCommit()
void GitPluginPrivate::fetch() void GitPluginPrivate::fetch()
{ {
m_gitClient.fetch(currentState().topLevel(), {}); gitClient().fetch(currentState().topLevel(), {});
} }
void GitPluginPrivate::pull() void GitPluginPrivate::pull()
@@ -1734,31 +1723,31 @@ void GitPluginPrivate::pull()
bool rebase = settings().pullRebase(); bool rebase = settings().pullRebase();
if (!rebase) { if (!rebase) {
QString currentBranch = m_gitClient.synchronousCurrentLocalBranch(topLevel); QString currentBranch = gitClient().synchronousCurrentLocalBranch(topLevel);
if (!currentBranch.isEmpty()) { if (!currentBranch.isEmpty()) {
currentBranch.prepend("branch."); currentBranch.prepend("branch.");
currentBranch.append(".rebase"); currentBranch.append(".rebase");
rebase = (m_gitClient.readConfigValue(topLevel, currentBranch) == "true"); rebase = (gitClient().readConfigValue(topLevel, currentBranch) == "true");
} }
} }
if (!m_gitClient.beginStashScope(topLevel, "Pull", rebase ? Default : AllowUnstashed)) if (!gitClient().beginStashScope(topLevel, "Pull", rebase ? Default : AllowUnstashed))
return; return;
m_gitClient.pull(topLevel, rebase); gitClient().pull(topLevel, rebase);
} }
void GitPluginPrivate::push() void GitPluginPrivate::push()
{ {
const VcsBasePluginState state = currentState(); const VcsBasePluginState state = currentState();
QTC_ASSERT(state.hasTopLevel(), return); QTC_ASSERT(state.hasTopLevel(), return);
m_gitClient.push(state.topLevel()); gitClient().push(state.topLevel());
} }
void GitPluginPrivate::startMergeTool() void GitPluginPrivate::startMergeTool()
{ {
const VcsBasePluginState state = currentState(); const VcsBasePluginState state = currentState();
QTC_ASSERT(state.hasTopLevel(), return); QTC_ASSERT(state.hasTopLevel(), return);
m_gitClient.merge(state.topLevel()); gitClient().merge(state.topLevel());
} }
void GitPluginPrivate::cleanProject() void GitPluginPrivate::cleanProject()
@@ -1782,7 +1771,7 @@ void GitPluginPrivate::cleanRepository(const FilePath &directory)
QStringList files; QStringList files;
QStringList ignoredFiles; QStringList ignoredFiles;
QApplication::setOverrideCursor(Qt::WaitCursor); QApplication::setOverrideCursor(Qt::WaitCursor);
const bool gotFiles = m_gitClient.synchronousCleanList(directory, {}, &files, &ignoredFiles, const bool gotFiles = gitClient().synchronousCleanList(directory, {}, &files, &ignoredFiles,
&errorMessage); &errorMessage);
QApplication::restoreOverrideCursor(); QApplication::restoreOverrideCursor();
@@ -1806,7 +1795,7 @@ void GitPluginPrivate::updateSubmodules()
{ {
const VcsBasePluginState state = currentState(); const VcsBasePluginState state = currentState();
QTC_ASSERT(state.hasTopLevel(), return); QTC_ASSERT(state.hasTopLevel(), return);
m_gitClient.updateSubmodulesIfNeeded(state.topLevel(), false); gitClient().updateSubmodulesIfNeeded(state.topLevel(), false);
} }
// If the file is modified in an editor, make sure it is saved. // If the file is modified in an editor, make sure it is saved.
@@ -1836,20 +1825,20 @@ void GitPluginPrivate::promptApplyPatch()
void GitPluginPrivate::applyPatch(const FilePath &workingDirectory, QString file) void GitPluginPrivate::applyPatch(const FilePath &workingDirectory, QString file)
{ {
// Ensure user has been notified about pending changes // Ensure user has been notified about pending changes
if (!m_gitClient.beginStashScope(workingDirectory, "Apply-Patch", AllowUnstashed)) if (!gitClient().beginStashScope(workingDirectory, "Apply-Patch", AllowUnstashed))
return; return;
// Prompt for file // Prompt for file
if (file.isEmpty()) { if (file.isEmpty()) {
const QString filter = Tr::tr("Patches (*.patch *.diff)"); const QString filter = Tr::tr("Patches (*.patch *.diff)");
file = QFileDialog::getOpenFileName(ICore::dialogParent(), Tr::tr("Choose Patch"), {}, filter); file = QFileDialog::getOpenFileName(ICore::dialogParent(), Tr::tr("Choose Patch"), {}, filter);
if (file.isEmpty()) { if (file.isEmpty()) {
m_gitClient.endStashScope(workingDirectory); gitClient().endStashScope(workingDirectory);
return; return;
} }
} }
// Run! // Run!
QString errorMessage; QString errorMessage;
if (m_gitClient.synchronousApplyPatch(workingDirectory, file, &errorMessage)) { if (gitClient().synchronousApplyPatch(workingDirectory, file, &errorMessage)) {
if (errorMessage.isEmpty()) if (errorMessage.isEmpty())
VcsOutputWindow::appendMessage(Tr::tr("Patch %1 successfully applied to %2") VcsOutputWindow::appendMessage(Tr::tr("Patch %1 successfully applied to %2")
.arg(file, workingDirectory.toUserOutput())); .arg(file, workingDirectory.toUserOutput()));
@@ -1858,7 +1847,7 @@ void GitPluginPrivate::applyPatch(const FilePath &workingDirectory, QString file
} else { } else {
VcsOutputWindow::appendError(errorMessage); VcsOutputWindow::appendError(errorMessage);
} }
m_gitClient.endStashScope(workingDirectory); gitClient().endStashScope(workingDirectory);
} }
void GitPluginPrivate::stash(bool unstagedOnly) void GitPluginPrivate::stash(bool unstagedOnly)
@@ -1870,7 +1859,7 @@ void GitPluginPrivate::stash(bool unstagedOnly)
QTC_ASSERT(state.hasTopLevel(), return); QTC_ASSERT(state.hasTopLevel(), return);
const FilePath topLevel = state.topLevel(); const FilePath topLevel = state.topLevel();
m_gitClient.executeSynchronousStash(topLevel, {}, unstagedOnly); gitClient().executeSynchronousStash(topLevel, {}, unstagedOnly);
if (m_stashDialog) if (m_stashDialog)
m_stashDialog->refresh(topLevel, true); m_stashDialog->refresh(topLevel, true);
} }
@@ -1885,7 +1874,7 @@ void GitPluginPrivate::stashSnapshot()
// Prompt for description, restore immediately and keep on working. // Prompt for description, restore immediately and keep on working.
const VcsBasePluginState state = currentState(); const VcsBasePluginState state = currentState();
QTC_ASSERT(state.hasTopLevel(), return); QTC_ASSERT(state.hasTopLevel(), return);
const QString id = m_gitClient.synchronousStash(state.topLevel(), {}, const QString id = gitClient().synchronousStash(state.topLevel(), {},
GitClient::StashImmediateRestore | GitClient::StashPromptDescription); GitClient::StashImmediateRestore | GitClient::StashPromptDescription);
if (!id.isEmpty() && m_stashDialog) if (!id.isEmpty() && m_stashDialog)
m_stashDialog->refresh(state.topLevel(), true); m_stashDialog->refresh(state.topLevel(), true);
@@ -1896,7 +1885,7 @@ void GitPluginPrivate::stashPop()
if (!DocumentManager::saveAllModifiedDocuments()) if (!DocumentManager::saveAllModifiedDocuments())
return; return;
const FilePath repository = currentState().topLevel(); const FilePath repository = currentState().topLevel();
m_gitClient.stashPop(repository); gitClient().stashPop(repository);
if (m_stashDialog) if (m_stashDialog)
m_stashDialog->refresh(repository, true); m_stashDialog->refresh(repository, true);
} }
@@ -1970,7 +1959,7 @@ void GitPluginPrivate::updateActions(VcsBasePluginPrivate::ActionState as)
repositoryAction->setEnabled(repositoryEnabled); repositoryAction->setEnabled(repositoryEnabled);
m_submoduleUpdateAction->setVisible(repositoryEnabled m_submoduleUpdateAction->setVisible(repositoryEnabled
&& !m_gitClient.submoduleList(state.topLevel()).isEmpty()); && !gitClient().submoduleList(state.topLevel()).isEmpty());
updateContinueAndAbortCommands(); updateContinueAndAbortCommands();
updateRepositoryBrowserAction(); updateRepositoryBrowserAction();
@@ -1982,7 +1971,7 @@ void GitPluginPrivate::updateContinueAndAbortCommands()
{ {
if (currentState().hasTopLevel()) { if (currentState().hasTopLevel()) {
GitClient::CommandInProgress gitCommandInProgress = GitClient::CommandInProgress gitCommandInProgress =
m_gitClient.checkCommandInProgress(currentState().topLevel()); gitClient().checkCommandInProgress(currentState().topLevel());
m_mergeToolAction->setVisible(gitCommandInProgress != GitClient::NoCommand); m_mergeToolAction->setVisible(gitCommandInProgress != GitClient::NoCommand);
m_abortMergeAction->setVisible(gitCommandInProgress == GitClient::Merge); m_abortMergeAction->setVisible(gitCommandInProgress == GitClient::Merge);
@@ -2035,7 +2024,7 @@ QObject *GitPlugin::remoteCommand(const QStringList &options, const QString &wor
return nullptr; return nullptr;
if (options.first() == "-git-show") if (options.first() == "-git-show")
dd->m_gitClient.show(FilePath::fromUserInput(workingDirectory), options.at(1)); gitClient().show(FilePath::fromUserInput(workingDirectory), options.at(1));
return nullptr; return nullptr;
} }
@@ -2070,7 +2059,7 @@ bool GitPluginPrivate::isVcsFileOrDirectory(const FilePath &filePath) const
bool GitPluginPrivate::isConfigured() const bool GitPluginPrivate::isConfigured() const
{ {
return !m_gitClient.vcsBinary().isEmpty(); return !gitClient().vcsBinary().isEmpty();
} }
bool GitPluginPrivate::supportsOperation(Operation operation) const bool GitPluginPrivate::supportsOperation(Operation operation) const
@@ -2098,30 +2087,30 @@ bool GitPluginPrivate::vcsOpen(const FilePath & /*filePath*/)
bool GitPluginPrivate::vcsAdd(const FilePath &filePath) bool GitPluginPrivate::vcsAdd(const FilePath &filePath)
{ {
return m_gitClient.synchronousAdd(filePath.parentDir(), {filePath.fileName()}, {"--intent-to-add"}); return gitClient().synchronousAdd(filePath.parentDir(), {filePath.fileName()}, {"--intent-to-add"});
} }
bool GitPluginPrivate::vcsDelete(const FilePath &filePath) bool GitPluginPrivate::vcsDelete(const FilePath &filePath)
{ {
return m_gitClient.synchronousDelete(filePath.absolutePath(), true, {filePath.fileName()}); return gitClient().synchronousDelete(filePath.absolutePath(), true, {filePath.fileName()});
} }
bool GitPluginPrivate::vcsMove(const FilePath &from, const FilePath &to) bool GitPluginPrivate::vcsMove(const FilePath &from, const FilePath &to)
{ {
const QFileInfo fromInfo = from.toFileInfo(); const QFileInfo fromInfo = from.toFileInfo();
const QFileInfo toInfo = to.toFileInfo(); const QFileInfo toInfo = to.toFileInfo();
return m_gitClient.synchronousMove(from.absolutePath(), fromInfo.absoluteFilePath(), toInfo.absoluteFilePath()); return gitClient().synchronousMove(from.absolutePath(), fromInfo.absoluteFilePath(), toInfo.absoluteFilePath());
} }
bool GitPluginPrivate::vcsCreateRepository(const FilePath &directory) bool GitPluginPrivate::vcsCreateRepository(const FilePath &directory)
{ {
return m_gitClient.synchronousInit(directory); return gitClient().synchronousInit(directory);
} }
QString GitPluginPrivate::vcsTopic(const FilePath &directory) QString GitPluginPrivate::vcsTopic(const FilePath &directory)
{ {
QString topic = IVersionControl::vcsTopic(directory); QString topic = IVersionControl::vcsTopic(directory);
const QString commandInProgress = m_gitClient.commandInProgressDescription(directory); const QString commandInProgress = gitClient().commandInProgressDescription(directory);
if (!commandInProgress.isEmpty()) if (!commandInProgress.isEmpty())
topic += " (" + commandInProgress + ')'; topic += " (" + commandInProgress + ')';
return topic; return topic;
@@ -2135,9 +2124,9 @@ VcsCommand *GitPluginPrivate::createInitialCheckoutCommand(const QString &url,
QStringList args = {"clone", "--progress"}; QStringList args = {"clone", "--progress"};
args << extraArgs << url << localName; args << extraArgs << url << localName;
auto command = VcsBaseClient::createVcsCommand(baseDirectory, m_gitClient.processEnvironment()); auto command = VcsBaseClient::createVcsCommand(baseDirectory, gitClient().processEnvironment());
command->addFlags(RunFlags::SuppressStdErr); command->addFlags(RunFlags::SuppressStdErr);
command->addJob({m_gitClient.vcsBinary(), args}, -1); command->addJob({gitClient().vcsBinary(), args}, -1);
return command; return command;
} }
@@ -2149,7 +2138,7 @@ GitPluginPrivate::RepoUrl GitPluginPrivate::getRepoUrl(const QString &location)
FilePaths GitPluginPrivate::additionalToolsPath() const FilePaths GitPluginPrivate::additionalToolsPath() const
{ {
FilePaths res = settings().searchPathList(); FilePaths res = settings().searchPathList();
const FilePath binaryPath = m_gitClient.gitBinDirectory(); const FilePath binaryPath = gitClient().gitBinDirectory();
if (!binaryPath.isEmpty() && !res.contains(binaryPath)) if (!binaryPath.isEmpty() && !res.contains(binaryPath))
res << binaryPath; res << binaryPath;
return res; return res;
@@ -2157,7 +2146,7 @@ FilePaths GitPluginPrivate::additionalToolsPath() const
bool GitPluginPrivate::managesDirectory(const FilePath &directory, FilePath *topLevel) const bool GitPluginPrivate::managesDirectory(const FilePath &directory, FilePath *topLevel) const
{ {
const FilePath topLevelFound = m_gitClient.findRepositoryForDirectory(directory); const FilePath topLevelFound = gitClient().findRepositoryForDirectory(directory);
if (topLevel) if (topLevel)
*topLevel = topLevelFound; *topLevel = topLevelFound;
return !topLevelFound.isEmpty(); return !topLevelFound.isEmpty();
@@ -2165,17 +2154,17 @@ bool GitPluginPrivate::managesDirectory(const FilePath &directory, FilePath *top
bool GitPluginPrivate::managesFile(const FilePath &workingDirectory, const QString &fileName) const bool GitPluginPrivate::managesFile(const FilePath &workingDirectory, const QString &fileName) const
{ {
return m_gitClient.managesFile(workingDirectory, fileName); return gitClient().managesFile(workingDirectory, fileName);
} }
FilePaths GitPluginPrivate::unmanagedFiles(const FilePaths &filePaths) const FilePaths GitPluginPrivate::unmanagedFiles(const FilePaths &filePaths) const
{ {
return m_gitClient.unmanagedFiles(filePaths); return gitClient().unmanagedFiles(filePaths);
} }
void GitPluginPrivate::vcsAnnotate(const FilePath &filePath, int line) void GitPluginPrivate::vcsAnnotate(const FilePath &filePath, int line)
{ {
m_gitClient.annotate(filePath.absolutePath(), filePath.fileName(), line); gitClient().annotate(filePath.absolutePath(), filePath.fileName(), line);
} }
void GitPlugin::emitFilesChanged(const QStringList &l) void GitPlugin::emitFilesChanged(const QStringList &l)

View File

@@ -17,8 +17,6 @@ namespace VcsBase { class VcsBasePluginState; }
namespace Git::Internal { namespace Git::Internal {
class GitClient;
class GITSHARED_EXPORT GitPlugin final : public ExtensionSystem::IPlugin class GITSHARED_EXPORT GitPlugin final : public ExtensionSystem::IPlugin
{ {
Q_OBJECT Q_OBJECT
@@ -33,7 +31,6 @@ public:
QObject *remoteCommand(const QStringList &options, const QString &workingDirectory, QObject *remoteCommand(const QStringList &options, const QString &workingDirectory,
const QStringList &args) final; const QStringList &args) final;
static GitClient *client();
static Core::IVersionControl *versionControl(); static Core::IVersionControl *versionControl();
static const VcsBase::VcsBasePluginState &currentState(); static const VcsBase::VcsBasePluginState &currentState();

View File

@@ -69,7 +69,7 @@ CommitDataFetchResult CommitDataFetchResult::fetch(CommitType commitType, const
CommitDataFetchResult result; CommitDataFetchResult result;
result.commitData.commitType = commitType; result.commitData.commitType = commitType;
QString commitTemplate; QString commitTemplate;
result.success = GitClient::instance()->getCommitData( result.success = gitClient().getCommitData(
workingDirectory, &commitTemplate, result.commitData, &result.errorMessage); workingDirectory, &commitTemplate, result.commitData, &result.errorMessage);
return result; return result;
} }
@@ -181,15 +181,15 @@ void GitSubmitEditor::slotDiffSelected(const QList<int> &rows)
} }
} }
if (!unstagedFiles.empty() || !stagedFiles.empty()) if (!unstagedFiles.empty() || !stagedFiles.empty())
GitClient::instance()->diffFiles(m_workingDirectory, unstagedFiles, stagedFiles); gitClient().diffFiles(m_workingDirectory, unstagedFiles, stagedFiles);
if (!unmergedFiles.empty()) if (!unmergedFiles.empty())
GitClient::instance()->merge(m_workingDirectory, unmergedFiles); gitClient().merge(m_workingDirectory, unmergedFiles);
} }
void GitSubmitEditor::showCommit(const QString &commit) void GitSubmitEditor::showCommit(const QString &commit)
{ {
if (!m_workingDirectory.isEmpty()) if (!m_workingDirectory.isEmpty())
GitClient::instance()->show(m_workingDirectory, commit); gitClient().show(m_workingDirectory, commit);
} }
void GitSubmitEditor::updateFileModel() void GitSubmitEditor::updateFileModel()

View File

@@ -47,7 +47,7 @@ public:
const auto it = m_descriptions.constFind(revision); const auto it = m_descriptions.constFind(revision);
if (it != m_descriptions.constEnd()) if (it != m_descriptions.constEnd())
return *it; return *it;
const QString desc = QString::fromUtf8(GitClient::instance()->synchronousShow( const QString desc = QString::fromUtf8(gitClient().synchronousShow(
m_workingDirectory, revision, RunFlags::NoOutput)); m_workingDirectory, revision, RunFlags::NoOutput));
m_descriptions[revision] = desc; m_descriptions[revision] = desc;
return desc; return desc;
@@ -170,7 +170,7 @@ bool LogChangeWidget::populateLog(const FilePath &repository, const QString &com
} }
arguments << "--"; arguments << "--";
QString output; QString output;
if (!GitClient::instance()->synchronousLog( if (!gitClient().synchronousLog(
repository, arguments, &output, nullptr, RunFlags::NoOutput)) { repository, arguments, &output, nullptr, RunFlags::NoOutput)) {
return false; return false;
} }

View File

@@ -37,7 +37,7 @@ void MergeTool::start(const FilePath &workingDirectory, const QStringList &files
{ {
QStringList arguments; QStringList arguments;
arguments << "mergetool" << "-y" << files; arguments << "mergetool" << "-y" << files;
const CommandLine cmd = {GitClient::instance()->vcsBinary(), arguments}; const CommandLine cmd = {gitClient().vcsBinary(), arguments};
VcsOutputWindow::appendCommand(workingDirectory, cmd); VcsOutputWindow::appendCommand(workingDirectory, cmd);
m_process.setCommand(cmd); m_process.setCommand(cmd);
m_process.setWorkingDirectory(workingDirectory); m_process.setWorkingDirectory(workingDirectory);
@@ -224,7 +224,7 @@ void MergeTool::done()
VcsOutputWindow::appendError(m_process.exitMessage()); VcsOutputWindow::appendError(m_process.exitMessage());
const FilePath workingDirectory = m_process.workingDirectory(); const FilePath workingDirectory = m_process.workingDirectory();
GitClient::instance()->continueCommandIfNeeded(workingDirectory, success); gitClient().continueCommandIfNeeded(workingDirectory, success);
GitPlugin::emitRepositoryChanged(workingDirectory); GitPlugin::emitRepositoryChanged(workingDirectory);
deleteLater(); deleteLater();
} }

View File

@@ -248,7 +248,7 @@ void RemoteDialog::pushToRemote()
const int row = indexList.at(0).row(); const int row = indexList.at(0).row();
const QString remoteName = m_remoteModel->remoteName(row); const QString remoteName = m_remoteModel->remoteName(row);
GitClient::instance()->push(m_remoteModel->workingDirectory(), {remoteName}); gitClient().push(m_remoteModel->workingDirectory(), {remoteName});
} }
void RemoteDialog::fetchFromRemote() void RemoteDialog::fetchFromRemote()
@@ -259,7 +259,7 @@ void RemoteDialog::fetchFromRemote()
int row = indexList.at(0).row(); int row = indexList.at(0).row();
const QString remoteName = m_remoteModel->remoteName(row); const QString remoteName = m_remoteModel->remoteName(row);
GitClient::instance()->fetch(m_remoteModel->workingDirectory(), remoteName); gitClient().fetch(m_remoteModel->workingDirectory(), remoteName);
} }
void RemoteDialog::updateButtonState() void RemoteDialog::updateButtonState()

View File

@@ -34,7 +34,7 @@ bool RemoteModel::removeRemote(int row)
{ {
QString output; QString output;
QString error; QString error;
bool success = GitClient::instance()->synchronousRemoteCmd( bool success = gitClient().synchronousRemoteCmd(
m_workingDirectory, {"rm", remoteName(row)}, &output, &error); m_workingDirectory, {"rm", remoteName(row)}, &output, &error);
if (success) if (success)
success = refresh(m_workingDirectory, &error); success = refresh(m_workingDirectory, &error);
@@ -48,7 +48,7 @@ bool RemoteModel::addRemote(const QString &name, const QString &url)
if (name.isEmpty() || url.isEmpty()) if (name.isEmpty() || url.isEmpty())
return false; return false;
bool success = GitClient::instance()->synchronousRemoteCmd( bool success = gitClient().synchronousRemoteCmd(
m_workingDirectory, {"add", name, url}, &output, &error); m_workingDirectory, {"add", name, url}, &output, &error);
if (success) if (success)
success = refresh(m_workingDirectory, &error); success = refresh(m_workingDirectory, &error);
@@ -59,7 +59,7 @@ bool RemoteModel::renameRemote(const QString &oldName, const QString &newName)
{ {
QString output; QString output;
QString error; QString error;
bool success = GitClient::instance()->synchronousRemoteCmd( bool success = gitClient().synchronousRemoteCmd(
m_workingDirectory, {"rename", oldName, newName}, &output, &error); m_workingDirectory, {"rename", oldName, newName}, &output, &error);
if (success) if (success)
success = refresh(m_workingDirectory, &error); success = refresh(m_workingDirectory, &error);
@@ -70,7 +70,7 @@ bool RemoteModel::updateUrl(const QString &name, const QString &newUrl)
{ {
QString output; QString output;
QString error; QString error;
bool success = GitClient::instance()->synchronousRemoteCmd( bool success = gitClient().synchronousRemoteCmd(
m_workingDirectory, {"set-url", name, newUrl}, &output, &error); m_workingDirectory, {"set-url", name, newUrl}, &output, &error);
if (success) if (success)
success = refresh(m_workingDirectory, &error); success = refresh(m_workingDirectory, &error);
@@ -165,7 +165,7 @@ bool RemoteModel::refresh(const FilePath &workingDirectory, QString *errorMessag
// get list of remotes. // get list of remotes.
QMap<QString,QString> remotesList QMap<QString,QString> remotesList
= GitClient::instance()->synchronousRemotesList(workingDirectory, errorMessage); = gitClient().synchronousRemotesList(workingDirectory, errorMessage);
beginResetModel(); beginResetModel();
m_remotes.clear(); m_remotes.clear();

View File

@@ -171,7 +171,7 @@ void StashDialog::refresh(const FilePath &repository, bool force)
m_model->setStashes(QList<Stash>()); m_model->setStashes(QList<Stash>());
} else { } else {
QList<Stash> stashes; QList<Stash> stashes;
GitClient::instance()->synchronousStashList(m_repository, &stashes); gitClient().synchronousStashList(m_repository, &stashes);
m_model->setStashes(stashes); m_model->setStashes(stashes);
if (!stashes.isEmpty()) { if (!stashes.isEmpty()) {
for (int c = 0; c < ColumnCount; c++) for (int c = 0; c < ColumnCount; c++)
@@ -187,7 +187,7 @@ void StashDialog::deleteAll()
if (!ask(title, Tr::tr("Do you want to delete all stashes?"))) if (!ask(title, Tr::tr("Do you want to delete all stashes?")))
return; return;
QString errorMessage; QString errorMessage;
if (GitClient::instance()->synchronousStashRemove(m_repository, QString(), &errorMessage)) if (gitClient().synchronousStashRemove(m_repository, QString(), &errorMessage))
refresh(m_repository, true); refresh(m_repository, true);
else else
warning(title, errorMessage); warning(title, errorMessage);
@@ -204,7 +204,7 @@ void StashDialog::deleteSelection()
QStringList errors; QStringList errors;
// Delete in reverse order as stashes rotate // Delete in reverse order as stashes rotate
for (int r = rows.size() - 1; r >= 0; r--) for (int r = rows.size() - 1; r >= 0; r--)
if (!GitClient::instance()->synchronousStashRemove(m_repository, m_model->at(rows.at(r)).name, &errorMessage)) if (!gitClient().synchronousStashRemove(m_repository, m_model->at(rows.at(r)).name, &errorMessage))
errors.push_back(errorMessage); errors.push_back(errorMessage);
refresh(m_repository, true); refresh(m_repository, true);
if (!errors.isEmpty()) if (!errors.isEmpty())
@@ -215,7 +215,7 @@ void StashDialog::showCurrent()
{ {
const int index = currentRow(); const int index = currentRow();
QTC_ASSERT(index >= 0, return); QTC_ASSERT(index >= 0, return);
GitClient::instance()->show(m_repository, QString(m_model->at(index).name)); gitClient().show(m_repository, QString(m_model->at(index).name));
} }
// Suggest Branch name to restore 'stash@{0}' -> 'stash0-date' // Suggest Branch name to restore 'stash@{0}' -> 'stash0-date'
@@ -276,7 +276,7 @@ bool StashDialog::promptForRestore(QString *stash,
{ {
const QString stashIn = *stash; const QString stashIn = *stash;
bool modifiedPromptShown = false; bool modifiedPromptShown = false;
switch (GitClient::instance()->gitStatus( switch (gitClient().gitStatus(
m_repository, StatusMode(NoUntracked | NoSubmodules), nullptr, errorMessage)) { m_repository, StatusMode(NoUntracked | NoSubmodules), nullptr, errorMessage)) {
case GitClient::StatusFailed: case GitClient::StatusFailed:
return false; return false;
@@ -285,7 +285,7 @@ bool StashDialog::promptForRestore(QString *stash,
case ModifiedRepositoryCancel: case ModifiedRepositoryCancel:
return false; return false;
case ModifiedRepositoryStash: case ModifiedRepositoryStash:
if (GitClient::instance()->synchronousStash( if (gitClient().synchronousStash(
m_repository, QString(), GitClient::StashPromptDescription).isEmpty()) { m_repository, QString(), GitClient::StashPromptDescription).isEmpty()) {
return false; return false;
} }
@@ -293,7 +293,7 @@ bool StashDialog::promptForRestore(QString *stash,
QTC_ASSERT(!stash->isEmpty(), return false); QTC_ASSERT(!stash->isEmpty(), return false);
break; break;
case ModifiedRepositoryDiscard: case ModifiedRepositoryDiscard:
if (!GitClient::instance()->synchronousReset(m_repository)) if (!gitClient().synchronousReset(m_repository))
return false; return false;
break; break;
} }
@@ -330,7 +330,7 @@ void StashDialog::restoreCurrent()
// Make sure repository is not modified, restore. The command will // Make sure repository is not modified, restore. The command will
// output to window on success. // output to window on success.
if (promptForRestore(&name, nullptr, &errorMessage) if (promptForRestore(&name, nullptr, &errorMessage)
&& GitClient::instance()->synchronousStashRestore(m_repository, name)) { && gitClient().synchronousStashRestore(m_repository, name)) {
refresh(m_repository, true); // Might have stashed away local changes. refresh(m_repository, true); // Might have stashed away local changes.
} else if (!errorMessage.isEmpty()) { } else if (!errorMessage.isEmpty()) {
warning(msgRestoreFailedTitle(name), errorMessage); warning(msgRestoreFailedTitle(name), errorMessage);
@@ -345,7 +345,7 @@ void StashDialog::restoreCurrentInBranch()
QString branch; QString branch;
QString name = m_model->at(index).name; QString name = m_model->at(index).name;
if (promptForRestore(&name, &branch, &errorMessage) if (promptForRestore(&name, &branch, &errorMessage)
&& GitClient::instance()->synchronousStashRestore(m_repository, name, false, branch)) { && gitClient().synchronousStashRestore(m_repository, name, false, branch)) {
refresh(m_repository, true); // git deletes the stash, unfortunately. refresh(m_repository, true); // git deletes the stash, unfortunately.
} else if (!errorMessage.isEmpty()) { } else if (!errorMessage.isEmpty()) {
warning(msgRestoreFailedTitle(name), errorMessage); warning(msgRestoreFailedTitle(name), errorMessage);

View File

@@ -246,13 +246,13 @@ void GitLabProjectSettingsWidget::updateUi()
} }
const Utils::FilePath projectDirectory = m_projectSettings->project()->projectDirectory(); const Utils::FilePath projectDirectory = m_projectSettings->project()->projectDirectory();
const auto *gitClient = Git::Internal::GitClient::instance(); const Utils::FilePath repository =
const Utils::FilePath repository = gitClient Git::Internal::gitClient().findRepositoryForDirectory(projectDirectory);
? gitClient->findRepositoryForDirectory(projectDirectory) : Utils::FilePath();
m_hostCB->clear(); m_hostCB->clear();
if (!repository.isEmpty()) { if (!repository.isEmpty()) {
const QMap<QString, QString> remotes = gitClient->synchronousRemotesList(repository); const QMap<QString, QString> remotes =
Git::Internal::gitClient().synchronousRemotesList(repository);
for (auto it = remotes.begin(), end = remotes.end(); it != end; ++it) { for (auto it = remotes.begin(), end = remotes.end(); it != end; ++it) {
const QString display = it.key() + " (" + it.value() + ')'; const QString display = it.key() + " (" + it.value() + ')';
m_hostCB->addItem(display, QVariant::fromValue(it.value())); m_hostCB->addItem(display, QVariant::fromValue(it.value()));
@@ -291,9 +291,8 @@ void GitLabProjectSettingsWidget::updateEnabledStates()
m_checkConnection->setEnabled(isGitRepository && hasGitLabServers); m_checkConnection->setEnabled(isGitRepository && hasGitLabServers);
if (!isGitRepository) { if (!isGitRepository) {
const Utils::FilePath projectDirectory = m_projectSettings->project()->projectDirectory(); const Utils::FilePath projectDirectory = m_projectSettings->project()->projectDirectory();
const auto *gitClient = Git::Internal::GitClient::instance(); const Utils::FilePath repository =
const Utils::FilePath repository = gitClient Git::Internal::gitClient().findRepositoryForDirectory(projectDirectory);
? gitClient->findRepositoryForDirectory(projectDirectory) : Utils::FilePath();
if (repository.isEmpty()) if (repository.isEmpty())
m_infoLabel->setText(Tr::tr("Not a git repository.")); m_infoLabel->setText(Tr::tr("Not a git repository."));
else else