diff options
author | Marcus Tillmanns <marcus.tillmanns@qt.io> | 2024-02-08 17:44:24 +0100 |
---|---|---|
committer | Marcus Tillmanns <marcus.tillmanns@qt.io> | 2024-02-12 11:25:06 +0000 |
commit | 291a893f5f5dbe0837ed145fb750417ee0f8475f (patch) | |
tree | 8736e228bff861cf60901dfd60ffbca023acb319 /src | |
parent | e21b8e0c1d845962b55287f7ff7742ff680383a6 (diff) |
VCS: Allow remote vcs operations
Both VcsBaseClient::vcsBinary() and VcsBaseClient::processEnvironment()
get an additional parameter "FilePath target" to allow selecting binaries
and environment based on where the repository is located.
This allows to select e.g. a git binary on a remote device, and the
environment of the remote device for each VCS operation.
A bunch of file path operations are either fixed or ported to actually use
FilePath correctly.
Change-Id: I6afc645772fde3dff3ec19c13efe538e5888e952
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/bazaar/bazaarplugin.cpp | 4 | ||||
-rw-r--r-- | src/plugins/fossil/fossilclient.cpp | 12 | ||||
-rw-r--r-- | src/plugins/fossil/fossilplugin.cpp | 13 | ||||
-rw-r--r-- | src/plugins/git/branchmodel.cpp | 4 | ||||
-rw-r--r-- | src/plugins/git/changeselectiondialog.cpp | 9 | ||||
-rw-r--r-- | src/plugins/git/gerrit/gerritmodel.cpp | 2 | ||||
-rw-r--r-- | src/plugins/git/gerrit/gerritplugin.cpp | 4 | ||||
-rw-r--r-- | src/plugins/git/gitclient.cpp | 54 | ||||
-rw-r--r-- | src/plugins/git/gitclient.h | 7 | ||||
-rw-r--r-- | src/plugins/git/gitgrep.cpp | 4 | ||||
-rw-r--r-- | src/plugins/git/gitplugin.cpp | 37 | ||||
-rw-r--r-- | src/plugins/git/mergetool.cpp | 2 | ||||
-rw-r--r-- | src/plugins/mercurial/mercurialclient.cpp | 5 | ||||
-rw-r--r-- | src/plugins/mercurial/mercurialplugin.cpp | 4 | ||||
-rw-r--r-- | src/plugins/subversion/subversionclient.cpp | 6 | ||||
-rw-r--r-- | src/plugins/subversion/subversionplugin.cpp | 4 | ||||
-rw-r--r-- | src/plugins/vcsbase/vcsbaseclient.cpp | 63 | ||||
-rw-r--r-- | src/plugins/vcsbase/vcsbaseclient.h | 8 | ||||
-rw-r--r-- | src/plugins/vcsbase/vcsbaseeditor.cpp | 2 | ||||
-rw-r--r-- | src/plugins/vcsbase/vcsbaseplugin.cpp | 2 | ||||
-rw-r--r-- | src/plugins/vcsbase/vcscommand.h | 8 |
21 files changed, 141 insertions, 113 deletions
diff --git a/src/plugins/bazaar/bazaarplugin.cpp b/src/plugins/bazaar/bazaarplugin.cpp index 8ca92f83a1..9a75fbf3b3 100644 --- a/src/plugins/bazaar/bazaarplugin.cpp +++ b/src/plugins/bazaar/bazaarplugin.cpp @@ -951,10 +951,10 @@ VcsCommand *BazaarPluginPrivate::createInitialCheckoutCommand(const QString &url args << m_client.vcsCommandString(BazaarClient::CloneCommand) << extraArgs << url << localName; - Environment env = m_client.processEnvironment(); + Environment env = m_client.processEnvironment(baseDirectory); env.set("BZR_PROGRESS_BAR", "text"); auto command = VcsBaseClient::createVcsCommand(baseDirectory, env); - command->addJob({m_client.vcsBinary(), args}, -1); + command->addJob({m_client.vcsBinary(baseDirectory), args}, -1); return command; } diff --git a/src/plugins/fossil/fossilclient.cpp b/src/plugins/fossil/fossilclient.cpp index e892978799..d24935595a 100644 --- a/src/plugins/fossil/fossilclient.cpp +++ b/src/plugins/fossil/fossilclient.cpp @@ -736,7 +736,7 @@ void FossilClient::annotate(const FilePath &workingDir, const QString &file, int lineNumber = -1; editor->setDefaultLineNumber(lineNumber); - enqueueJob(createCommand(workingDir, fossilEditor), args); + enqueueJob(createCommand(workingDir, fossilEditor), args, workingDir); } bool FossilClient::isVcsFileOrDirectory(const FilePath &filePath) const @@ -833,7 +833,7 @@ void FossilClient::view(const FilePath &source, const QString &id, const QString VcsBaseEditor::getCodec(source), "view", id); editor->setWorkingDirectory(workingDirectory); - enqueueJob(createCommand(workingDirectory, editor), args + extraOptions); + enqueueJob(createCommand(workingDirectory, editor), args + extraOptions, source); } class FossilLogHighlighter : QSyntaxHighlighter @@ -935,7 +935,7 @@ void FossilClient::log(const FilePath &workingDir, const QStringList &files, args << effectiveArgs; if (!files.isEmpty()) args << "--path" << files; - enqueueJob(createCommand(workingDir, fossilEditor), args); + enqueueJob(createCommand(workingDir, fossilEditor), args, workingDir); } void FossilClient::logCurrentFile(const FilePath &workingDir, const QStringList &files, @@ -989,7 +989,7 @@ void FossilClient::logCurrentFile(const FilePath &workingDir, const QStringList QStringList args(vcsCmdString); args << effectiveArgs << files; - enqueueJob(createCommand(workingDir, fossilEditor), args); + enqueueJob(createCommand(workingDir, fossilEditor), args, workingDir); } void FossilClient::revertFile(const FilePath &workingDir, @@ -1009,7 +1009,7 @@ void FossilClient::revertFile(const FilePath &workingDir, if (cmd->result() == ProcessResult::FinishedWithSuccess) emit changed(files); }); - enqueueJob(cmd, args); + enqueueJob(cmd, args, workingDir); } void FossilClient::revertAll(const FilePath &workingDir, const QString &revision, const QStringList &extraOptions) @@ -1033,7 +1033,7 @@ void FossilClient::revertAll(const FilePath &workingDir, const QString &revision if (cmd->result() == ProcessResult::FinishedWithSuccess) emit changed(files); }); - enqueueJob(createCommand(workingDir), args); + enqueueJob(createCommand(workingDir), args, workingDir); } QString FossilClient::sanitizeFossilOutput(const QString &output) const diff --git a/src/plugins/fossil/fossilplugin.cpp b/src/plugins/fossil/fossilplugin.cpp index 25fcdfa923..c4ea13b446 100644 --- a/src/plugins/fossil/fossilplugin.cpp +++ b/src/plugins/fossil/fossilplugin.cpp @@ -808,7 +808,7 @@ bool FossilPluginPrivate::managesFile(const FilePath &workingDirectory, const QS bool FossilPluginPrivate::isConfigured() const { - const FilePath binary = fossilClient().vcsBinary(); + const FilePath binary = fossilClient().vcsBinary({}); if (binary.isEmpty()) return false; @@ -927,7 +927,8 @@ VcsCommand *FossilPluginPrivate::createInitialCheckoutCommand(const QString &sou checkoutPath.createDir(); // Setup the wizard page command job - auto command = VcsBaseClient::createVcsCommand(checkoutPath, fossilClient().processEnvironment()); + auto command = VcsBaseClient::createVcsCommand(checkoutPath, + fossilClient().processEnvironment(checkoutPath)); if (!isLocalRepository && !cloneRepository.exists()) { @@ -963,7 +964,7 @@ VcsCommand *FossilPluginPrivate::createInitialCheckoutCommand(const QString &sou << extraOptions << sourceUrl << fossilFileNative; - command->addJob({fossilClient().vcsBinary(), args}, -1); + command->addJob({fossilClient().vcsBinary(checkoutPath), args}, -1); } // check out the cloned repository file into the working copy directory; @@ -972,20 +973,20 @@ VcsCommand *FossilPluginPrivate::createInitialCheckoutCommand(const QString &sou QStringList args({"open", fossilFileNative}); if (!checkoutBranch.isEmpty()) args << checkoutBranch; - command->addJob({fossilClient().vcsBinary(), args}, -1); + command->addJob({fossilClient().vcsBinary(checkoutPath), args}, -1); // set user default to admin user if specified if (!isLocalRepository && !adminUser.isEmpty()) { const QStringList args({ "user", "default", adminUser, "--user", adminUser}); - command->addJob({fossilClient().vcsBinary(), args}, -1); + command->addJob({fossilClient().vcsBinary(checkoutPath), args}, -1); } // turn-off autosync if requested if (!isLocalRepository && disableAutosync) { const QStringList args({"settings", "autosync", "off"}); - command->addJob({fossilClient().vcsBinary(), args}, -1); + command->addJob({fossilClient().vcsBinary(checkoutPath), args}, -1); } return command; diff --git a/src/plugins/git/branchmodel.cpp b/src/plugins/git/branchmodel.cpp index ed80feeb16..99e6e01005 100644 --- a/src/plugins/git/branchmodel.cpp +++ b/src/plugins/git/branchmodel.cpp @@ -914,13 +914,13 @@ void BranchModel::updateUpstreamStatus(BranchNode *node) return; Process *process = new Process(node); - process->setEnvironment(gitClient().processEnvironment()); + process->setEnvironment(gitClient().processEnvironment(d->workingDirectory)); QStringList parameters = {"rev-list", "--no-color", "--count"}; if (node->tracking.isEmpty()) parameters += {node->fullRef(), "--not", "--remotes"}; else parameters += {"--left-right", node->fullRef() + "..." + node->tracking}; - process->setCommand({gitClient().vcsBinary(), parameters}); + process->setCommand({gitClient().vcsBinary(d->workingDirectory), parameters}); process->setWorkingDirectory(d->workingDirectory); connect(process, &Process::done, this, [this, process, node] { process->deleteLater(); diff --git a/src/plugins/git/changeselectiondialog.cpp b/src/plugins/git/changeselectiondialog.cpp index cf991e6e93..12cc91eddb 100644 --- a/src/plugins/git/changeselectiondialog.cpp +++ b/src/plugins/git/changeselectiondialog.cpp @@ -33,8 +33,8 @@ ChangeSelectionDialog::ChangeSelectionDialog(const FilePath &workingDirectory, I QWidget *parent) : QDialog(parent) { - m_gitExecutable = gitClient().vcsBinary(); - m_gitEnvironment = gitClient().processEnvironment(); + m_gitExecutable = gitClient().vcsBinary(workingDirectory); + m_gitEnvironment = gitClient().processEnvironment(workingDirectory); resize(550, 350); setWindowTitle(Tr::tr("Select a Git Commit")); @@ -209,8 +209,9 @@ void ChangeSelectionDialog::recalculateCompletion() return; Process *process = new Process(this); - process->setEnvironment(gitClient().processEnvironment()); - process->setCommand({gitClient().vcsBinary(), {"for-each-ref", "--format=%(refname:short)"}}); + process->setEnvironment(gitClient().processEnvironment(workingDir)); + process->setCommand( + {gitClient().vcsBinary(workingDir), {"for-each-ref", "--format=%(refname:short)"}}); process->setWorkingDirectory(workingDir); process->setUseCtrlCStub(true); connect(process, &Process::done, this, [this, process] { diff --git a/src/plugins/git/gerrit/gerritmodel.cpp b/src/plugins/git/gerrit/gerritmodel.cpp index b11458393e..8af786ac5e 100644 --- a/src/plugins/git/gerrit/gerritmodel.cpp +++ b/src/plugins/git/gerrit/gerritmodel.cpp @@ -266,7 +266,6 @@ QueryContext::QueryContext(const QString &query, m_output.append(m_process.readAllRawStandardOutput()); }); connect(&m_process, &Process::done, this, &QueryContext::processDone); - m_process.setEnvironment(Git::Internal::gitClient().processEnvironment()); m_timer.setInterval(timeOutMS); m_timer.setSingleShot(true); @@ -286,6 +285,7 @@ void QueryContext::start() VcsOutputWindow::appendCommand(m_process.workingDirectory(), commandLine); m_timer.start(); m_process.setCommand(commandLine); + m_process.setEnvironment(Git::Internal::gitClient().processEnvironment(m_binary)); auto progress = new Core::ProcessProgress(&m_process); progress->setDisplayName(Git::Tr::tr("Querying Gerrit")); m_process.start(); diff --git a/src/plugins/git/gerrit/gerritplugin.cpp b/src/plugins/git/gerrit/gerritplugin.cpp index 802c921409..3ef90358b9 100644 --- a/src/plugins/git/gerrit/gerritplugin.cpp +++ b/src/plugins/git/gerrit/gerritplugin.cpp @@ -101,7 +101,7 @@ FetchContext::FetchContext(const std::shared_ptr<GerritChange> &change, VcsBase::VcsOutputWindow::append(QString::fromLocal8Bit(m_process.readAllRawStandardOutput())); }); m_process.setWorkingDirectory(repository); - m_process.setEnvironment(gitClient().processEnvironment()); + m_process.setEnvironment(gitClient().processEnvironment(repository)); } void FetchContext::start() @@ -279,7 +279,7 @@ QString GerritPlugin::branch(const FilePath &repository) void GerritPlugin::fetch(const std::shared_ptr<GerritChange> &change, int mode) { // Locate git. - const Utils::FilePath git = gitClient().vcsBinary(); + const Utils::FilePath git = gitClient().vcsBinary(m_dialog->repositoryPath()); if (git.isEmpty()) { VcsBase::VcsOutputWindow::appendError(Git::Tr::tr("Git is not available.")); return; diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 5523ba1b48..eb857c4685 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -827,15 +827,12 @@ FilePath GitClient::findRepositoryForDirectory(const FilePath &directory) const { if (directory.isEmpty() || directory.endsWith("/.git") || directory.path().contains("/.git/")) return {}; - // QFileInfo is outside loop, because it is faster this way - QFileInfo fileInfo; FilePath parent; for (FilePath dir = directory; !dir.isEmpty(); dir = dir.parentDir()) { const FilePath gitName = dir.pathAppended(GIT_DIRECTORY); if (!gitName.exists()) continue; // parent might exist - fileInfo.setFile(gitName.toString()); - if (fileInfo.isFile()) + if (gitName.isFile()) return dir; if (gitName.pathAppended("config").exists()) return dir; @@ -929,8 +926,8 @@ void GitClient::requestReload(const QString &documentId, const FilePath &source, QTC_ASSERT(document, return); GitBaseDiffEditorController *controller = factory(document); QTC_ASSERT(controller, return); - controller->setVcsBinary(settings().gitExecutable().value_or(FilePath{})); - controller->setProcessEnvironment(processEnvironment()); + controller->setVcsBinary(vcsBinary(workingDirectory)); + controller->setProcessEnvironment(processEnvironment(workingDirectory)); controller->setWorkingDirectory(workingDirectory); using namespace std::placeholders; @@ -1047,9 +1044,8 @@ void GitClient::log(const FilePath &workingDirectory, const QString &fileName, const QString title = Tr::tr("Git Log \"%1\"").arg(msgArg); const Id editorId = Git::Constants::GIT_LOG_EDITOR_ID; const FilePath sourceFile = VcsBaseEditor::getSource(workingDir, fileName); - GitEditorWidget *editor = static_cast<GitEditorWidget *>( - createVcsEditor(editorId, title, sourceFile, - encoding(EncodingLogOutput), "logTitle", msgArg)); + GitEditorWidget *editor = static_cast<GitEditorWidget *>(createVcsEditor( + editorId, title, sourceFile, encoding(EncodingLogOutput, sourceFile), "logTitle", msgArg)); VcsBaseEditorConfig *argWidget = editor->editorConfig(); if (!argWidget) { argWidget = new GitLogArgumentsWidget(!fileName.isEmpty(), editor); @@ -2089,9 +2085,9 @@ bool GitClient::synchronousApplyPatch(const FilePath &workingDirectory, return false; } -Environment GitClient::processEnvironment() const +Environment GitClient::processEnvironment(const FilePath &appliedTo) const { - Environment environment = VcsBaseClientImpl::processEnvironment(); + Environment environment; environment.prependOrSetPath(settings().path()); if (HostOsInfo::isWindowsHost() && settings().winSetHomeEnvironment()) { QString homePath; @@ -2103,7 +2099,7 @@ Environment GitClient::processEnvironment() const environment.set("HOME", homePath); } environment.set("GIT_EDITOR", m_disableEditor ? "true" : m_gitQtcEditor); - return environment; + return environment.appliedToEnvironment(appliedTo.deviceEnvironment()); } bool GitClient::beginStashScope(const FilePath &workingDirectory, const QString &command, @@ -2387,7 +2383,7 @@ QStringList GitClient::synchronousRepositoryBranches(const QString &repositoryUR void GitClient::launchGitK(const FilePath &workingDirectory, const QString &fileName) const { - tryLaunchingGitK(processEnvironment(), workingDirectory, fileName); + tryLaunchingGitK(processEnvironment(workingDirectory), workingDirectory, fileName); } void GitClient::launchRepositoryBrowser(const FilePath &workingDirectory) const @@ -2420,7 +2416,7 @@ void GitClient::tryLaunchingGitK(const Environment &env, const QString &fileName, GitClient::GitKLaunchTrial trial) const { - const FilePath gitBinDirectory = gitBinDir(trial, vcsBinary().parentDir()); + const FilePath gitBinDirectory = gitBinDir(trial, vcsBinary(workingDirectory).parentDir()); FilePath binary = gitBinDirectory.pathAppended("gitk").withExecutableSuffix(); QStringList arguments; if (HostOsInfo::isWindowsHost()) { @@ -2469,7 +2465,7 @@ void GitClient::handleGitKFailedToStart(const Environment &env, GitKLaunchTrial nextTrial = None; - if (oldTrial == Bin && vcsBinary().parentDir().fileName() == "bin") { + if (oldTrial == Bin && vcsBinary(workingDirectory).parentDir().fileName() == "bin") { nextTrial = ParentOfBin; } else if (oldTrial != SystemPath && !Environment::systemEnvironment().searchInPath("gitk").isEmpty()) { @@ -2486,7 +2482,7 @@ void GitClient::handleGitKFailedToStart(const Environment &env, bool GitClient::launchGitGui(const FilePath &workingDirectory) { bool success = true; - FilePath gitBinary = vcsBinary(); + FilePath gitBinary = vcsBinary(workingDirectory); if (gitBinary.isEmpty()) { success = false; } else { @@ -2501,7 +2497,7 @@ bool GitClient::launchGitGui(const FilePath &workingDirectory) { FilePath GitClient::gitBinDirectory() const { - const QString git = vcsBinary().toString(); + const QString git = vcsBinary({}).toString(); if (git.isEmpty()) return {}; @@ -2529,7 +2525,7 @@ FilePath GitClient::gitBinDirectory() const bool GitClient::launchGitBash(const FilePath &workingDirectory) { bool success = true; - const FilePath git = vcsBinary(); + const FilePath git = vcsBinary(workingDirectory); if (git.isEmpty()) { success = false; @@ -2544,8 +2540,18 @@ bool GitClient::launchGitBash(const FilePath &workingDirectory) return success; } -FilePath GitClient::vcsBinary() const +FilePath GitClient::vcsBinary(const FilePath &forDirectory) const { + if (forDirectory.needsDevice()) { + auto it = m_gitExecutableCache.find(forDirectory.withNewPath({})); + if (it == m_gitExecutableCache.end()) { + const FilePath gitBin = forDirectory.withNewPath("git").searchInPath(); + it = m_gitExecutableCache.insert(forDirectory.withNewPath({}), + gitBin.isExecutableFile() ? gitBin : FilePath{}); + } + + return it.value(); + } return settings().gitExecutable().value_or(FilePath{}); } @@ -2753,7 +2759,7 @@ bool GitClient::addAndCommit(const FilePath &repositoryDirectory, const GitSubmitEditorPanelData &data, CommitType commitType, const QString &amendSHA1, - const QString &messageFile, + const FilePath &messageFile, SubmitFileModel *model) { const QString renameSeparator = " -> "; @@ -2817,7 +2823,7 @@ bool GitClient::addAndCommit(const FilePath &repositoryDirectory, if (commitType == FixupCommit) { arguments << "--fixup" << amendSHA1; } else { - arguments << "-F" << QDir::toNativeSeparators(messageFile); + arguments << "-F" << messageFile.nativePath(); if (commitType == AmendCommit) arguments << "--amend"; const QString &authorString = data.authorString(); @@ -3243,7 +3249,7 @@ void GitClient::vcsExecAbortable(const FilePath &workingDirectory, const QString command->addFlags(RunFlags::ShowStdOut | RunFlags::ShowSuccessMessage); // For rebase, Git might request an editor (which means the process keeps running until the // user closes it), so run without timeout. - command->addJob({vcsBinary(), arguments}, isRebase ? 0 : vcsTimeoutS()); + command->addJob({vcsBinary(workingDirectory), arguments}, isRebase ? 0 : vcsTimeoutS()); const QObject *actualContext = context ? context : this; connect(command, &VcsCommand::done, actualContext, [=] { const CommandResult result = CommandResult(*command); @@ -3461,7 +3467,7 @@ QFuture<QVersionNumber> GitClient::gitVersion() const // Do not execute repeatedly if that fails (due to git // not being installed) until settings are changed. - const FilePath newGitBinary = vcsBinary(); + const FilePath newGitBinary = vcsBinary({}); const bool needToRunGit = m_gitVersionForBinary != newGitBinary && !newGitBinary.isEmpty(); if (needToRunGit) { auto proc = new Process(const_cast<GitClient *>(this)); @@ -3476,7 +3482,7 @@ QFuture<QVersionNumber> GitClient::gitVersion() const proc->deleteLater(); }); - proc->setEnvironment(processEnvironment()); + proc->setEnvironment(processEnvironment(newGitBinary)); proc->setCommand({newGitBinary, {"--version"}}); proc->start(); } else { diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index f0ed9ffc8e..823aae6736 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -123,7 +123,7 @@ public: GitClient(); ~GitClient(); - Utils::FilePath vcsBinary() const override; + Utils::FilePath vcsBinary(const Utils::FilePath &forDirectory) const override; QFuture<QVersionNumber> gitVersion() const; void vcsExecAbortable(const Utils::FilePath &workingDirectory, const QStringList &arguments, @@ -295,7 +295,7 @@ public: const GitSubmitEditorPanelData &data, CommitType commitType, const QString &amendSHA1, - const QString &messageFile, + const Utils::FilePath &messageFile, VcsBase::SubmitFileModel *model); enum StatusResult { StatusChanged, StatusUnchanged, StatusFailed }; @@ -318,7 +318,7 @@ public: QStringList synchronousRepositoryBranches(const QString &repositoryURL, const Utils::FilePath &workingDirectory = {}) const; - Utils::Environment processEnvironment() const override; + Utils::Environment processEnvironment(const Utils::FilePath &appliedTo) const override; bool beginStashScope(const Utils::FilePath &workingDirectory, const QString &command, StashFlag flag = Default, PushAction pushAction = NoPush); @@ -395,6 +395,7 @@ private: mutable Utils::FilePath m_gitVersionForBinary; mutable QVersionNumber m_cachedGitVersion; + mutable QMap<Utils::FilePath, Utils::FilePath> m_gitExecutableCache; QString m_gitQtcEditor; QMap<Utils::FilePath, StashInfo> m_stashInfo; diff --git a/src/plugins/git/gitgrep.cpp b/src/plugins/git/gitgrep.cpp index 2f1f0bda49..5675fe0f48 100644 --- a/src/plugins/git/gitgrep.cpp +++ b/src/plugins/git/gitgrep.cpp @@ -134,8 +134,8 @@ static void runGitGrep(QPromise<SearchResultItems> &promise, const FileFindParam const GitGrepParameters &gitParameters) { const auto setupProcess = [¶meters, gitParameters](Process &process) { - const FilePath vcsBinary = gitClient().vcsBinary(); - const Environment environment = gitClient().processEnvironment(); + const FilePath vcsBinary = gitClient().vcsBinary(parameters.searchDir); + const Environment environment = gitClient().processEnvironment(vcsBinary); QStringList arguments = { "-c", "color.grep.match=bold red", diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index 915796bdbf..966abc40b8 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -281,7 +281,7 @@ public: const Context &context); void updateRepositoryBrowserAction(); - IEditor *openSubmitEditor(const QString &fileName, const CommitData &cd); + IEditor *openSubmitEditor(const FilePath &fileName, const CommitData &cd); void cleanCommitMessageFile(); void cleanRepository(const FilePath &directory); void applyPatch(const FilePath &workingDirectory, QString file = {}); @@ -319,7 +319,7 @@ public: BranchViewFactory m_branchViewFactory; QPointer<RemoteDialog> m_remoteDialog; FilePath m_submitRepository; - QString m_commitMessageFileName; + FilePath m_commitMessageFileName; InstantBlame m_instantBlame; @@ -402,7 +402,7 @@ void GitPluginPrivate::onApplySettings() void GitPluginPrivate::cleanCommitMessageFile() { if (!m_commitMessageFileName.isEmpty()) { - QFile::remove(m_commitMessageFileName); + m_commitMessageFileName.removeFile(); m_commitMessageFileName.clear(); } } @@ -986,8 +986,12 @@ void GitPluginPrivate::blameFile() const FilePath fileName = state.currentFile().canonicalPath(); FilePath topLevel; VcsManager::findVersionControlForDirectory(fileName.parentDir(), &topLevel); - gitClient().annotate(topLevel, fileName.relativeChildPath(topLevel).toString(), - lineNumber, {}, extraOptions, firstLine); + gitClient().annotate(topLevel, + fileName.relativeChildPath(topLevel).path(), + lineNumber, + {}, + extraOptions, + firstLine); } void GitPluginPrivate::logProject() @@ -1247,7 +1251,9 @@ void GitPluginPrivate::startCommit(CommitType commitType) m_submitRepository = data.panelInfo.repository; // Start new temp file with message template - TempFileSaver saver; + TempFileSaver saver( + data.panelInfo.repository.tmpDir().value_or(data.panelInfo.repository.withNewPath("")) + / "commit-msg.XXXXXX"); // Keep the file alive, else it removes self and forgets its name saver.setAutoRemove(false); saver.write(commitTemplate.toLocal8Bit()); @@ -1255,7 +1261,7 @@ void GitPluginPrivate::startCommit(CommitType commitType) VcsOutputWindow::appendError(saver.errorString()); return; } - m_commitMessageFileName = saver.filePath().toString(); + m_commitMessageFileName = saver.filePath(); openSubmitEditor(m_commitMessageFileName, data); } @@ -1284,10 +1290,9 @@ void GitPluginPrivate::instantBlameOnce() m_instantBlame.once(); } -IEditor *GitPluginPrivate::openSubmitEditor(const QString &fileName, const CommitData &cd) +IEditor *GitPluginPrivate::openSubmitEditor(const FilePath &fileName, const CommitData &cd) { - IEditor *editor = EditorManager::openEditor(FilePath::fromString(fileName), - Constants::GITSUBMITEDITOR_ID); + IEditor *editor = EditorManager::openEditor(fileName, Constants::GITSUBMITEDITOR_ID); auto submitEditor = qobject_cast<GitSubmitEditor*>(editor); QTC_ASSERT(submitEditor, return nullptr); setSubmitEditor(submitEditor); @@ -1320,10 +1325,9 @@ bool GitPluginPrivate::activateCommit() QTC_ASSERT(editorDocument, return true); // Submit editor closing. Make it write out the commit message // and retrieve files - const QFileInfo editorFile = editorDocument->filePath().toFileInfo(); - const QFileInfo changeFile(m_commitMessageFileName); + // Paranoia! - if (editorFile.absoluteFilePath() != changeFile.absoluteFilePath()) + if (!editorDocument->filePath().isSameFile(m_commitMessageFileName)) return true; auto model = qobject_cast<SubmitFileModel *>(editor->fileModel()); @@ -1700,7 +1704,7 @@ bool GitPluginPrivate::isVcsFileOrDirectory(const FilePath &filePath) const bool GitPluginPrivate::isConfigured() const { - return !gitClient().vcsBinary().isEmpty(); + return !gitClient().vcsBinary({}).isEmpty(); } bool GitPluginPrivate::supportsOperation(Operation operation) const @@ -1765,9 +1769,10 @@ VcsCommand *GitPluginPrivate::createInitialCheckoutCommand(const QString &url, QStringList args = {"clone", "--progress"}; args << extraArgs << url << localName; - auto command = VcsBaseClient::createVcsCommand(baseDirectory, gitClient().processEnvironment()); + auto command = VcsBaseClient::createVcsCommand(baseDirectory, + gitClient().processEnvironment(baseDirectory)); command->addFlags(RunFlags::SuppressStdErr); - command->addJob({gitClient().vcsBinary(), args}, -1); + command->addJob({gitClient().vcsBinary(baseDirectory), args}, -1); return command; } diff --git a/src/plugins/git/mergetool.cpp b/src/plugins/git/mergetool.cpp index 8829c44518..d0a102c9df 100644 --- a/src/plugins/git/mergetool.cpp +++ b/src/plugins/git/mergetool.cpp @@ -37,7 +37,7 @@ void MergeTool::start(const FilePath &workingDirectory, const QStringList &files { QStringList arguments; arguments << "mergetool" << "-y" << files; - const CommandLine cmd = {gitClient().vcsBinary(), arguments}; + const CommandLine cmd = {gitClient().vcsBinary(workingDirectory), arguments}; VcsOutputWindow::appendCommand(workingDirectory, cmd); m_process.setCommand(cmd); m_process.setWorkingDirectory(workingDirectory); diff --git a/src/plugins/mercurial/mercurialclient.cpp b/src/plugins/mercurial/mercurialclient.cpp index 8122896422..fd568c9741 100644 --- a/src/plugins/mercurial/mercurialclient.cpp +++ b/src/plugins/mercurial/mercurialclient.cpp @@ -273,7 +273,7 @@ void MercurialClient::incoming(const FilePath &repositoryRoot, const QString &re VcsBaseEditorWidget *editor = createVcsEditor(Constants::DIFFLOG_ID, title, repositoryRoot, VcsBaseEditor::getCodec(repositoryRoot), "incoming", id); - enqueueJob(createCommand(FilePath::fromString(repository), editor), args); + enqueueJob(createCommand(FilePath::fromString(repository), editor), args, repositoryRoot); } void MercurialClient::outgoing(const FilePath &repositoryRoot) @@ -286,7 +286,7 @@ void MercurialClient::outgoing(const FilePath &repositoryRoot) VcsBaseEditorWidget *editor = createVcsEditor(Constants::DIFFLOG_ID, title, repositoryRoot, VcsBaseEditor::getCodec(repositoryRoot), "outgoing", repositoryRoot.toString()); - enqueueJob(createCommand(repositoryRoot, editor), args); + enqueueJob(createCommand(repositoryRoot, editor), args, repositoryRoot); } void MercurialClient::annotate(const Utils::FilePath &workingDir, const QString &file, @@ -424,7 +424,6 @@ void MercurialClient::requestReload(const QString &documentId, const FilePath &s QTC_ASSERT(document, return); auto controller = new MercurialDiffEditorController(document, args); controller->setVcsBinary(settings().binaryPath()); - controller->setProcessEnvironment(processEnvironment()); controller->setWorkingDirectory(workingDirectory); VcsBase::setSource(document, sourceCopy); diff --git a/src/plugins/mercurial/mercurialplugin.cpp b/src/plugins/mercurial/mercurialplugin.cpp index 91c25139d9..8e4d90f045 100644 --- a/src/plugins/mercurial/mercurialplugin.cpp +++ b/src/plugins/mercurial/mercurialplugin.cpp @@ -736,7 +736,9 @@ VcsCommand *MercurialPluginPrivate::createInitialCheckoutCommand(const QString & { QStringList args; args << QLatin1String("clone") << extraArgs << url << localName; - auto command = VcsBaseClient::createVcsCommand(baseDirectory, mercurialClient().processEnvironment()); + auto command = VcsBaseClient::createVcsCommand(baseDirectory, + mercurialClient().processEnvironment( + baseDirectory)); command->addJob({settings().binaryPath(), args}, -1); return command; } diff --git a/src/plugins/subversion/subversionclient.cpp b/src/plugins/subversion/subversionclient.cpp index 4f378731d4..e30abd5bc8 100644 --- a/src/plugins/subversion/subversionclient.cpp +++ b/src/plugins/subversion/subversionclient.cpp @@ -57,7 +57,7 @@ bool SubversionClient::doCommit(const FilePath &repositoryRoot, const QString &commitMessageFile, const QStringList &extraOptions) const { - CommandLine args{vcsBinary()}; + CommandLine args{vcsBinary(repositoryRoot)}; args << vcsCommandString(CommitCommand) << extraOptions << AddAuthOptions() @@ -117,7 +117,7 @@ QString SubversionClient::synchronousTopic(const FilePath &repository) const { QStringList args; - QString svnVersionBinary = vcsBinary().toString(); + QString svnVersionBinary = vcsBinary(repository).toString(); int pos = svnVersionBinary.lastIndexOf('/'); if (pos < 0) svnVersionBinary.clear(); @@ -237,7 +237,7 @@ SubversionDiffEditorController *SubversionClient::findOrCreateDiffEditor(const Q if (!controller) { controller = new SubversionDiffEditorController(document); controller->setVcsBinary(settings().binaryPath()); - controller->setProcessEnvironment(processEnvironment()); + controller->setProcessEnvironment(processEnvironment(workingDirectory)); controller->setWorkingDirectory(workingDirectory); } VcsBase::setSource(document, source); diff --git a/src/plugins/subversion/subversionplugin.cpp b/src/plugins/subversion/subversionplugin.cpp index cab80c64d0..fc9d5ed122 100644 --- a/src/plugins/subversion/subversionplugin.cpp +++ b/src/plugins/subversion/subversionplugin.cpp @@ -1135,7 +1135,9 @@ VcsCommand *SubversionPluginPrivate::createInitialCheckoutCommand(const QString args << SubversionClient::AddAuthOptions(); args << Subversion::Constants::NON_INTERACTIVE_OPTION << extraArgs << url << localName; - auto command = VcsBaseClient::createVcsCommand(baseDirectory, subversionClient().processEnvironment()); + auto command = VcsBaseClient::createVcsCommand(baseDirectory, + subversionClient().processEnvironment( + baseDirectory)); command->addJob(args, -1); return command; } diff --git a/src/plugins/vcsbase/vcsbaseclient.cpp b/src/plugins/vcsbase/vcsbaseclient.cpp index ea2ddcadc5..81a816c009 100644 --- a/src/plugins/vcsbase/vcsbaseclient.cpp +++ b/src/plugins/vcsbase/vcsbaseclient.cpp @@ -61,15 +61,18 @@ VcsBaseClientImpl::VcsBaseClientImpl(VcsBaseSettings *baseSettings) this, &VcsBaseClientImpl::saveSettings); } -FilePath VcsBaseClientImpl::vcsBinary() const +FilePath VcsBaseClientImpl::vcsBinary(const Utils::FilePath &forDirectory) const { + if (forDirectory.needsDevice()) + return {}; + return m_baseSettings->binaryPath(); } VcsCommand *VcsBaseClientImpl::createCommand(const FilePath &workingDirectory, VcsBaseEditorWidget *editor) const { - auto cmd = createVcsCommand(workingDirectory, processEnvironment()); + auto cmd = createVcsCommand(workingDirectory, processEnvironment(workingDirectory)); if (editor) { editor->setCommand(cmd); connect(cmd, &VcsCommand::done, editor, [editor, cmd] { @@ -88,24 +91,24 @@ void VcsBaseClientImpl::setupCommand(Utils::Process &process, const FilePath &workingDirectory, const QStringList &args) const { - process.setEnvironment(processEnvironment()); + process.setEnvironment(workingDirectory.deviceEnvironment()); process.setWorkingDirectory(workingDirectory); - process.setCommand({vcsBinary(), args}); + process.setCommand({vcsBinary(workingDirectory), args}); process.setUseCtrlCStub(true); } -void VcsBaseClientImpl::enqueueJob(VcsCommand *cmd, const QStringList &args, +void VcsBaseClientImpl::enqueueJob(VcsCommand *cmd, + const QStringList &args, + const Utils::FilePath &forDirectory, const ExitCodeInterpreter &interpreter) const { - cmd->addJob({vcsBinary(), args}, vcsTimeoutS(), {}, interpreter); + cmd->addJob({vcsBinary(forDirectory), args}, vcsTimeoutS(), {}, interpreter); cmd->start(); } -Environment VcsBaseClientImpl::processEnvironment() const +Environment VcsBaseClientImpl::processEnvironment(const FilePath &appliedTo) const { - Environment environment = Environment::systemEnvironment(); - VcsBase::setProcessEnvironment(&environment); - return environment; + return appliedTo.deviceEnvironment(); } QStringList VcsBaseClientImpl::splitLines(const QString &s) @@ -129,14 +132,18 @@ QString VcsBaseClientImpl::stripLastNewline(const QString &in) CommandResult VcsBaseClientImpl::vcsSynchronousExec(const FilePath &workingDir, const QStringList &args, RunFlags flags, int timeoutS, QTextCodec *codec) const { - return vcsSynchronousExec(workingDir, {vcsBinary(), args}, flags, timeoutS, codec); + return vcsSynchronousExec(workingDir, {vcsBinary(workingDir), args}, flags, timeoutS, codec); } CommandResult VcsBaseClientImpl::vcsSynchronousExec(const FilePath &workingDir, const CommandLine &cmdLine, RunFlags flags, int timeoutS, QTextCodec *codec) const { - return VcsCommand::runBlocking(workingDir, processEnvironment(), cmdLine, flags, - timeoutS > 0 ? timeoutS : vcsTimeoutS(), codec); + return VcsCommand::runBlocking(workingDir, + processEnvironment(workingDir), + cmdLine, + flags, + timeoutS > 0 ? timeoutS : vcsTimeoutS(), + codec); } void VcsBaseClientImpl::resetCachedVcsInfo(const FilePath &workingDir) @@ -166,7 +173,7 @@ void VcsBaseClientImpl::vcsExecWithHandler(const FilePath &workingDirectory, VcsCommand *command = createCommand(workingDirectory); command->addFlags(additionalFlags); command->setCodec(codec); - command->addJob({vcsBinary(), arguments}, vcsTimeoutS()); + command->addJob({vcsBinary(workingDirectory), arguments}, vcsTimeoutS()); if (handler) { const QObject *actualContext = context ? context : this; connect(command, &VcsCommand::done, actualContext, [command, handler] { @@ -182,7 +189,7 @@ void VcsBaseClientImpl::vcsExec(const FilePath &workingDirectory, { VcsCommand *command = createCommand(workingDirectory); command->addFlags(additionalFlags); - command->addJob({vcsBinary(), arguments}, vcsTimeoutS()); + command->addJob({vcsBinary(workingDirectory), arguments}, vcsTimeoutS()); command->start(); } @@ -192,7 +199,7 @@ void VcsBaseClientImpl::vcsExecWithEditor(const Utils::FilePath &workingDirector { VcsCommand *command = createCommand(workingDirectory, editor); command->setCodec(editor->codec()); - command->addJob({vcsBinary(), arguments}, vcsTimeoutS()); + command->addJob({vcsBinary(workingDirectory), arguments}, vcsTimeoutS()); command->start(); } @@ -350,7 +357,7 @@ void VcsBaseClient::annotate(const Utils::FilePath &workingDir, const QString &f VcsCommand *cmd = createCommand(workingDir, editor); editor->setDefaultLineNumber(lineNumber); - enqueueJob(cmd, args); + enqueueJob(cmd, args, workingDir); } void VcsBaseClient::diff(const FilePath &workingDir, const QStringList &files) @@ -387,7 +394,7 @@ void VcsBaseClient::diff(const FilePath &workingDir, const QStringList &files) : VcsBaseEditor::getCodec(source); VcsCommand *command = createCommand(workingDir, editor); command->setCodec(codec); - enqueueJob(command, args, exitCodeInterpreter(DiffCommand)); + enqueueJob(command, args, workingDir, exitCodeInterpreter(DiffCommand)); } void VcsBaseClient::log(const FilePath &workingDir, @@ -421,7 +428,7 @@ void VcsBaseClient::log(const FilePath &workingDir, } } - CommandLine args{vcsBinary(), {vcsCmdString}}; + CommandLine args{vcsBinary(workingDir), {vcsCmdString}}; if (addAuthOptions) addAuthOptions(args); if (editorConfig) @@ -448,7 +455,7 @@ void VcsBaseClient::revertFile(const FilePath &workingDir, if (cmd->result() == ProcessResult::FinishedWithSuccess) emit changed(files); }); - enqueueJob(cmd, args); + enqueueJob(cmd, args, workingDir); } void VcsBaseClient::revertAll(const FilePath &workingDir, @@ -464,7 +471,7 @@ void VcsBaseClient::revertAll(const FilePath &workingDir, if (cmd->result() == ProcessResult::FinishedWithSuccess) emit changed(files); }); - enqueueJob(cmd, args); + enqueueJob(cmd, args, workingDir); } void VcsBaseClient::status(const FilePath &workingDir, @@ -475,7 +482,7 @@ void VcsBaseClient::status(const FilePath &workingDir, args << extraOptions << file; VcsCommand *cmd = createCommand(workingDir); cmd->addFlags(RunFlags::ShowStdOut); - enqueueJob(cmd, args); + enqueueJob(cmd, args, workingDir); } void VcsBaseClient::emitParsedStatus(const FilePath &repository, const QStringList &extraOptions) @@ -484,7 +491,7 @@ void VcsBaseClient::emitParsedStatus(const FilePath &repository, const QStringLi args << extraOptions; VcsCommand *cmd = createCommand(repository); connect(cmd, &VcsCommand::done, this, [this, cmd] { statusParser(cmd->cleanedStdOut()); }); - enqueueJob(cmd, args); + enqueueJob(cmd, args, repository); } QString VcsBaseClient::vcsCommandString(VcsCommandTag cmd) const @@ -525,7 +532,7 @@ void VcsBaseClient::import(const FilePath &repositoryRoot, { QStringList args(vcsCommandString(ImportCommand)); args << extraOptions << files; - enqueueJob(createCommand(repositoryRoot), args); + enqueueJob(createCommand(repositoryRoot), args, repositoryRoot); } void VcsBaseClient::view(const FilePath &source, @@ -541,7 +548,7 @@ void VcsBaseClient::view(const FilePath &source, VcsBaseEditor::getCodec(source), "view", id); const FilePath workingDirPath = source.isFile() ? source.absolutePath() : source; - enqueueJob(createCommand(workingDirPath, editor), args); + enqueueJob(createCommand(workingDirPath, editor), args, source); } void VcsBaseClient::update(const FilePath &repositoryRoot, const QString &revision, @@ -554,7 +561,7 @@ void VcsBaseClient::update(const FilePath &repositoryRoot, const QString &revisi if (cmd->result() == ProcessResult::FinishedWithSuccess) emit changed(repositoryRoot.toString()); }); - enqueueJob(cmd, args); + enqueueJob(cmd, args, repositoryRoot); } void VcsBaseClient::commit(const FilePath &repositoryRoot, @@ -576,12 +583,12 @@ void VcsBaseClient::commit(const FilePath &repositoryRoot, cmd->addFlags(RunFlags::ShowStdOut); if (!commitMessageFile.isEmpty()) connect(cmd, &VcsCommand::done, [commitMessageFile] { QFile(commitMessageFile).remove(); }); - enqueueJob(cmd, args); + enqueueJob(cmd, args, repositoryRoot); } QString VcsBaseClient::vcsEditorTitle(const QString &vcsCmd, const QString &sourceId) const { - return vcsBinary().baseName() + QLatin1Char(' ') + vcsCmd + QLatin1Char(' ') + return vcsBinary({}).baseName() + QLatin1Char(' ') + vcsCmd + QLatin1Char(' ') + FilePath::fromString(sourceId).fileName(); } diff --git a/src/plugins/vcsbase/vcsbaseclient.h b/src/plugins/vcsbase/vcsbaseclient.h index f1db56ebeb..99b818b59b 100644 --- a/src/plugins/vcsbase/vcsbaseclient.h +++ b/src/plugins/vcsbase/vcsbaseclient.h @@ -41,7 +41,7 @@ public: explicit VcsBaseClientImpl(VcsBaseSettings *baseSettings); ~VcsBaseClientImpl() override = default; - virtual Utils::FilePath vcsBinary() const; + virtual Utils::FilePath vcsBinary(const Utils::FilePath &forDirectory) const; int vcsTimeoutS() const; static VcsCommand *createVcsCommand(const Utils::FilePath &defaultWorkingDir, @@ -59,10 +59,12 @@ public: const Utils::FilePath &workingDirectory, const QStringList &args) const; - void enqueueJob(VcsCommand *cmd, const QStringList &args, + void enqueueJob(VcsCommand *cmd, + const QStringList &args, + const Utils::FilePath &forDirectory, const ExitCodeInterpreter &interpreter = {}) const; - virtual Utils::Environment processEnvironment() const; + virtual Utils::Environment processEnvironment(const Utils::FilePath &appliedTo) const; // VCS functionality: virtual void annotate(const Utils::FilePath &workingDir, const QString &file, diff --git a/src/plugins/vcsbase/vcsbaseeditor.cpp b/src/plugins/vcsbase/vcsbaseeditor.cpp index d365be7156..b10758233a 100644 --- a/src/plugins/vcsbase/vcsbaseeditor.cpp +++ b/src/plugins/vcsbase/vcsbaseeditor.cpp @@ -1327,7 +1327,7 @@ bool VcsBaseEditor::gotoLineOfEditor(IEditor *e, int lineNumber) // ('git diff XX' -> 'XX' , 'git diff XX file' -> 'XX/file'). FilePath VcsBaseEditor::getSource(const FilePath &workingDirectory, const QString &fileName) { - return workingDirectory.pathAppended(fileName); + return workingDirectory.resolvePath(fileName); } FilePath VcsBaseEditor::getSource(const FilePath &workingDirectory, const QStringList &fileNames) diff --git a/src/plugins/vcsbase/vcsbaseplugin.cpp b/src/plugins/vcsbase/vcsbaseplugin.cpp index ee2ea42813..b506f0ed38 100644 --- a/src/plugins/vcsbase/vcsbaseplugin.cpp +++ b/src/plugins/vcsbase/vcsbaseplugin.cpp @@ -374,7 +374,7 @@ FilePath VcsBasePluginState::currentFileDirectory() const QString VcsBasePluginState::relativeCurrentFile() const { QTC_ASSERT(hasFile(), return {}); - return data->m_state.currentFile.relativeChildPath(data->m_state.currentFileTopLevel).toString(); + return data->m_state.currentFile.relativeChildPath(data->m_state.currentFileTopLevel).path(); } QString VcsBasePluginState::currentPatchFile() const diff --git a/src/plugins/vcsbase/vcscommand.h b/src/plugins/vcsbase/vcscommand.h index e9975dcb14..6271139544 100644 --- a/src/plugins/vcsbase/vcscommand.h +++ b/src/plugins/vcsbase/vcscommand.h @@ -82,9 +82,11 @@ public: void setProgressParser(const Core::ProgressParser &parser); static CommandResult runBlocking(const Utils::FilePath &workingDirectory, - const Utils::Environment &environmentconst, - const Utils::CommandLine &command, RunFlags flags, - int timeoutS, QTextCodec *codec); + const Utils::Environment &environment, + const Utils::CommandLine &command, + RunFlags flags, + int timeoutS, + QTextCodec *codec); void cancel(); QString cleanedStdOut() const; |