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>
This commit is contained in:
Marcus Tillmanns
2024-02-08 17:44:24 +01:00
parent e21b8e0c1d
commit 291a893f5f
21 changed files with 141 additions and 113 deletions

View File

@@ -951,10 +951,10 @@ VcsCommand *BazaarPluginPrivate::createInitialCheckoutCommand(const QString &url
args << m_client.vcsCommandString(BazaarClient::CloneCommand) args << m_client.vcsCommandString(BazaarClient::CloneCommand)
<< extraArgs << url << localName; << extraArgs << url << localName;
Environment env = m_client.processEnvironment(); Environment env = m_client.processEnvironment(baseDirectory);
env.set("BZR_PROGRESS_BAR", "text"); env.set("BZR_PROGRESS_BAR", "text");
auto command = VcsBaseClient::createVcsCommand(baseDirectory, env); auto command = VcsBaseClient::createVcsCommand(baseDirectory, env);
command->addJob({m_client.vcsBinary(), args}, -1); command->addJob({m_client.vcsBinary(baseDirectory), args}, -1);
return command; return command;
} }

View File

@@ -736,7 +736,7 @@ void FossilClient::annotate(const FilePath &workingDir, const QString &file, int
lineNumber = -1; lineNumber = -1;
editor->setDefaultLineNumber(lineNumber); editor->setDefaultLineNumber(lineNumber);
enqueueJob(createCommand(workingDir, fossilEditor), args); enqueueJob(createCommand(workingDir, fossilEditor), args, workingDir);
} }
bool FossilClient::isVcsFileOrDirectory(const FilePath &filePath) const 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); VcsBaseEditor::getCodec(source), "view", id);
editor->setWorkingDirectory(workingDirectory); editor->setWorkingDirectory(workingDirectory);
enqueueJob(createCommand(workingDirectory, editor), args + extraOptions); enqueueJob(createCommand(workingDirectory, editor), args + extraOptions, source);
} }
class FossilLogHighlighter : QSyntaxHighlighter class FossilLogHighlighter : QSyntaxHighlighter
@@ -935,7 +935,7 @@ void FossilClient::log(const FilePath &workingDir, const QStringList &files,
args << effectiveArgs; args << effectiveArgs;
if (!files.isEmpty()) if (!files.isEmpty())
args << "--path" << files; args << "--path" << files;
enqueueJob(createCommand(workingDir, fossilEditor), args); enqueueJob(createCommand(workingDir, fossilEditor), args, workingDir);
} }
void FossilClient::logCurrentFile(const FilePath &workingDir, const QStringList &files, void FossilClient::logCurrentFile(const FilePath &workingDir, const QStringList &files,
@@ -989,7 +989,7 @@ void FossilClient::logCurrentFile(const FilePath &workingDir, const QStringList
QStringList args(vcsCmdString); QStringList args(vcsCmdString);
args << effectiveArgs << files; args << effectiveArgs << files;
enqueueJob(createCommand(workingDir, fossilEditor), args); enqueueJob(createCommand(workingDir, fossilEditor), args, workingDir);
} }
void FossilClient::revertFile(const FilePath &workingDir, void FossilClient::revertFile(const FilePath &workingDir,
@@ -1009,7 +1009,7 @@ void FossilClient::revertFile(const FilePath &workingDir,
if (cmd->result() == ProcessResult::FinishedWithSuccess) if (cmd->result() == ProcessResult::FinishedWithSuccess)
emit changed(files); emit changed(files);
}); });
enqueueJob(cmd, args); enqueueJob(cmd, args, workingDir);
} }
void FossilClient::revertAll(const FilePath &workingDir, const QString &revision, const QStringList &extraOptions) 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) if (cmd->result() == ProcessResult::FinishedWithSuccess)
emit changed(files); emit changed(files);
}); });
enqueueJob(createCommand(workingDir), args); enqueueJob(createCommand(workingDir), args, workingDir);
} }
QString FossilClient::sanitizeFossilOutput(const QString &output) const QString FossilClient::sanitizeFossilOutput(const QString &output) const

View File

@@ -808,7 +808,7 @@ bool FossilPluginPrivate::managesFile(const FilePath &workingDirectory, const QS
bool FossilPluginPrivate::isConfigured() const bool FossilPluginPrivate::isConfigured() const
{ {
const FilePath binary = fossilClient().vcsBinary(); const FilePath binary = fossilClient().vcsBinary({});
if (binary.isEmpty()) if (binary.isEmpty())
return false; return false;
@@ -927,7 +927,8 @@ VcsCommand *FossilPluginPrivate::createInitialCheckoutCommand(const QString &sou
checkoutPath.createDir(); checkoutPath.createDir();
// Setup the wizard page command job // Setup the wizard page command job
auto command = VcsBaseClient::createVcsCommand(checkoutPath, fossilClient().processEnvironment()); auto command = VcsBaseClient::createVcsCommand(checkoutPath,
fossilClient().processEnvironment(checkoutPath));
if (!isLocalRepository if (!isLocalRepository
&& !cloneRepository.exists()) { && !cloneRepository.exists()) {
@@ -963,7 +964,7 @@ VcsCommand *FossilPluginPrivate::createInitialCheckoutCommand(const QString &sou
<< extraOptions << extraOptions
<< sourceUrl << sourceUrl
<< fossilFileNative; << 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; // 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}); QStringList args({"open", fossilFileNative});
if (!checkoutBranch.isEmpty()) if (!checkoutBranch.isEmpty())
args << checkoutBranch; args << checkoutBranch;
command->addJob({fossilClient().vcsBinary(), args}, -1); command->addJob({fossilClient().vcsBinary(checkoutPath), args}, -1);
// set user default to admin user if specified // set user default to admin user if specified
if (!isLocalRepository if (!isLocalRepository
&& !adminUser.isEmpty()) { && !adminUser.isEmpty()) {
const QStringList args({ "user", "default", adminUser, "--user", adminUser}); 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 // turn-off autosync if requested
if (!isLocalRepository if (!isLocalRepository
&& disableAutosync) { && disableAutosync) {
const QStringList args({"settings", "autosync", "off"}); const QStringList args({"settings", "autosync", "off"});
command->addJob({fossilClient().vcsBinary(), args}, -1); command->addJob({fossilClient().vcsBinary(checkoutPath), args}, -1);
} }
return command; return command;

View File

@@ -914,13 +914,13 @@ void BranchModel::updateUpstreamStatus(BranchNode *node)
return; return;
Process *process = new Process(node); Process *process = new Process(node);
process->setEnvironment(gitClient().processEnvironment()); process->setEnvironment(gitClient().processEnvironment(d->workingDirectory));
QStringList parameters = {"rev-list", "--no-color", "--count"}; QStringList parameters = {"rev-list", "--no-color", "--count"};
if (node->tracking.isEmpty()) if (node->tracking.isEmpty())
parameters += {node->fullRef(), "--not", "--remotes"}; parameters += {node->fullRef(), "--not", "--remotes"};
else else
parameters += {"--left-right", node->fullRef() + "..." + node->tracking}; parameters += {"--left-right", node->fullRef() + "..." + node->tracking};
process->setCommand({gitClient().vcsBinary(), parameters}); process->setCommand({gitClient().vcsBinary(d->workingDirectory), parameters});
process->setWorkingDirectory(d->workingDirectory); process->setWorkingDirectory(d->workingDirectory);
connect(process, &Process::done, this, [this, process, node] { connect(process, &Process::done, this, [this, process, node] {
process->deleteLater(); process->deleteLater();

View File

@@ -33,8 +33,8 @@ ChangeSelectionDialog::ChangeSelectionDialog(const FilePath &workingDirectory, I
QWidget *parent) : QWidget *parent) :
QDialog(parent) QDialog(parent)
{ {
m_gitExecutable = gitClient().vcsBinary(); m_gitExecutable = gitClient().vcsBinary(workingDirectory);
m_gitEnvironment = gitClient().processEnvironment(); m_gitEnvironment = gitClient().processEnvironment(workingDirectory);
resize(550, 350); resize(550, 350);
setWindowTitle(Tr::tr("Select a Git Commit")); setWindowTitle(Tr::tr("Select a Git Commit"));
@@ -209,8 +209,9 @@ void ChangeSelectionDialog::recalculateCompletion()
return; return;
Process *process = new Process(this); Process *process = new Process(this);
process->setEnvironment(gitClient().processEnvironment()); process->setEnvironment(gitClient().processEnvironment(workingDir));
process->setCommand({gitClient().vcsBinary(), {"for-each-ref", "--format=%(refname:short)"}}); process->setCommand(
{gitClient().vcsBinary(workingDir), {"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

@@ -266,7 +266,6 @@ 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().processEnvironment());
m_timer.setInterval(timeOutMS); m_timer.setInterval(timeOutMS);
m_timer.setSingleShot(true); m_timer.setSingleShot(true);
@@ -286,6 +285,7 @@ void QueryContext::start()
VcsOutputWindow::appendCommand(m_process.workingDirectory(), commandLine); VcsOutputWindow::appendCommand(m_process.workingDirectory(), commandLine);
m_timer.start(); m_timer.start();
m_process.setCommand(commandLine); m_process.setCommand(commandLine);
m_process.setEnvironment(Git::Internal::gitClient().processEnvironment(m_binary));
auto progress = new Core::ProcessProgress(&m_process); auto progress = new Core::ProcessProgress(&m_process);
progress->setDisplayName(Git::Tr::tr("Querying Gerrit")); progress->setDisplayName(Git::Tr::tr("Querying Gerrit"));
m_process.start(); m_process.start();

View File

@@ -101,7 +101,7 @@ FetchContext::FetchContext(const std::shared_ptr<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().processEnvironment()); m_process.setEnvironment(gitClient().processEnvironment(repository));
} }
void FetchContext::start() void FetchContext::start()
@@ -279,7 +279,7 @@ QString GerritPlugin::branch(const FilePath &repository)
void GerritPlugin::fetch(const std::shared_ptr<GerritChange> &change, int mode) void GerritPlugin::fetch(const std::shared_ptr<GerritChange> &change, int mode)
{ {
// Locate git. // Locate git.
const Utils::FilePath git = gitClient().vcsBinary(); const Utils::FilePath git = gitClient().vcsBinary(m_dialog->repositoryPath());
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;

View File

@@ -827,15 +827,12 @@ FilePath GitClient::findRepositoryForDirectory(const FilePath &directory) const
{ {
if (directory.isEmpty() || directory.endsWith("/.git") || directory.path().contains("/.git/")) if (directory.isEmpty() || directory.endsWith("/.git") || directory.path().contains("/.git/"))
return {}; return {};
// QFileInfo is outside loop, because it is faster this way
QFileInfo fileInfo;
FilePath parent; FilePath parent;
for (FilePath dir = directory; !dir.isEmpty(); dir = dir.parentDir()) { for (FilePath dir = directory; !dir.isEmpty(); dir = dir.parentDir()) {
const FilePath gitName = dir.pathAppended(GIT_DIRECTORY); const FilePath gitName = dir.pathAppended(GIT_DIRECTORY);
if (!gitName.exists()) if (!gitName.exists())
continue; // parent might exist continue; // parent might exist
fileInfo.setFile(gitName.toString()); if (gitName.isFile())
if (fileInfo.isFile())
return dir; return dir;
if (gitName.pathAppended("config").exists()) if (gitName.pathAppended("config").exists())
return dir; return dir;
@@ -929,8 +926,8 @@ void GitClient::requestReload(const QString &documentId, const FilePath &source,
QTC_ASSERT(document, return); QTC_ASSERT(document, return);
GitBaseDiffEditorController *controller = factory(document); GitBaseDiffEditorController *controller = factory(document);
QTC_ASSERT(controller, return); QTC_ASSERT(controller, return);
controller->setVcsBinary(settings().gitExecutable().value_or(FilePath{})); controller->setVcsBinary(vcsBinary(workingDirectory));
controller->setProcessEnvironment(processEnvironment()); controller->setProcessEnvironment(processEnvironment(workingDirectory));
controller->setWorkingDirectory(workingDirectory); controller->setWorkingDirectory(workingDirectory);
using namespace std::placeholders; 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 QString title = Tr::tr("Git Log \"%1\"").arg(msgArg);
const Id editorId = Git::Constants::GIT_LOG_EDITOR_ID; const Id editorId = Git::Constants::GIT_LOG_EDITOR_ID;
const FilePath sourceFile = VcsBaseEditor::getSource(workingDir, fileName); const FilePath sourceFile = VcsBaseEditor::getSource(workingDir, fileName);
GitEditorWidget *editor = static_cast<GitEditorWidget *>( GitEditorWidget *editor = static_cast<GitEditorWidget *>(createVcsEditor(
createVcsEditor(editorId, title, sourceFile, editorId, title, sourceFile, encoding(EncodingLogOutput, sourceFile), "logTitle", msgArg));
encoding(EncodingLogOutput), "logTitle", msgArg));
VcsBaseEditorConfig *argWidget = editor->editorConfig(); VcsBaseEditorConfig *argWidget = editor->editorConfig();
if (!argWidget) { if (!argWidget) {
argWidget = new GitLogArgumentsWidget(!fileName.isEmpty(), editor); argWidget = new GitLogArgumentsWidget(!fileName.isEmpty(), editor);
@@ -2089,9 +2085,9 @@ bool GitClient::synchronousApplyPatch(const FilePath &workingDirectory,
return false; return false;
} }
Environment GitClient::processEnvironment() const Environment GitClient::processEnvironment(const FilePath &appliedTo) const
{ {
Environment environment = VcsBaseClientImpl::processEnvironment(); Environment environment;
environment.prependOrSetPath(settings().path()); environment.prependOrSetPath(settings().path());
if (HostOsInfo::isWindowsHost() && settings().winSetHomeEnvironment()) { if (HostOsInfo::isWindowsHost() && settings().winSetHomeEnvironment()) {
QString homePath; QString homePath;
@@ -2103,7 +2099,7 @@ Environment GitClient::processEnvironment() const
environment.set("HOME", homePath); environment.set("HOME", homePath);
} }
environment.set("GIT_EDITOR", m_disableEditor ? "true" : m_gitQtcEditor); 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, 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 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 void GitClient::launchRepositoryBrowser(const FilePath &workingDirectory) const
@@ -2420,7 +2416,7 @@ void GitClient::tryLaunchingGitK(const Environment &env,
const QString &fileName, const QString &fileName,
GitClient::GitKLaunchTrial trial) const 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(); FilePath binary = gitBinDirectory.pathAppended("gitk").withExecutableSuffix();
QStringList arguments; QStringList arguments;
if (HostOsInfo::isWindowsHost()) { if (HostOsInfo::isWindowsHost()) {
@@ -2469,7 +2465,7 @@ void GitClient::handleGitKFailedToStart(const Environment &env,
GitKLaunchTrial nextTrial = None; GitKLaunchTrial nextTrial = None;
if (oldTrial == Bin && vcsBinary().parentDir().fileName() == "bin") { if (oldTrial == Bin && vcsBinary(workingDirectory).parentDir().fileName() == "bin") {
nextTrial = ParentOfBin; nextTrial = ParentOfBin;
} else if (oldTrial != SystemPath } else if (oldTrial != SystemPath
&& !Environment::systemEnvironment().searchInPath("gitk").isEmpty()) { && !Environment::systemEnvironment().searchInPath("gitk").isEmpty()) {
@@ -2486,7 +2482,7 @@ void GitClient::handleGitKFailedToStart(const Environment &env,
bool GitClient::launchGitGui(const FilePath &workingDirectory) { bool GitClient::launchGitGui(const FilePath &workingDirectory) {
bool success = true; bool success = true;
FilePath gitBinary = vcsBinary(); FilePath gitBinary = vcsBinary(workingDirectory);
if (gitBinary.isEmpty()) { if (gitBinary.isEmpty()) {
success = false; success = false;
} else { } else {
@@ -2501,7 +2497,7 @@ bool GitClient::launchGitGui(const FilePath &workingDirectory) {
FilePath GitClient::gitBinDirectory() const FilePath GitClient::gitBinDirectory() const
{ {
const QString git = vcsBinary().toString(); const QString git = vcsBinary({}).toString();
if (git.isEmpty()) if (git.isEmpty())
return {}; return {};
@@ -2529,7 +2525,7 @@ FilePath GitClient::gitBinDirectory() const
bool GitClient::launchGitBash(const FilePath &workingDirectory) bool GitClient::launchGitBash(const FilePath &workingDirectory)
{ {
bool success = true; bool success = true;
const FilePath git = vcsBinary(); const FilePath git = vcsBinary(workingDirectory);
if (git.isEmpty()) { if (git.isEmpty()) {
success = false; success = false;
@@ -2544,8 +2540,18 @@ bool GitClient::launchGitBash(const FilePath &workingDirectory)
return success; 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{}); return settings().gitExecutable().value_or(FilePath{});
} }
@@ -2753,7 +2759,7 @@ bool GitClient::addAndCommit(const FilePath &repositoryDirectory,
const GitSubmitEditorPanelData &data, const GitSubmitEditorPanelData &data,
CommitType commitType, CommitType commitType,
const QString &amendSHA1, const QString &amendSHA1,
const QString &messageFile, const FilePath &messageFile,
SubmitFileModel *model) SubmitFileModel *model)
{ {
const QString renameSeparator = " -> "; const QString renameSeparator = " -> ";
@@ -2817,7 +2823,7 @@ bool GitClient::addAndCommit(const FilePath &repositoryDirectory,
if (commitType == FixupCommit) { if (commitType == FixupCommit) {
arguments << "--fixup" << amendSHA1; arguments << "--fixup" << amendSHA1;
} else { } else {
arguments << "-F" << QDir::toNativeSeparators(messageFile); arguments << "-F" << messageFile.nativePath();
if (commitType == AmendCommit) if (commitType == AmendCommit)
arguments << "--amend"; arguments << "--amend";
const QString &authorString = data.authorString(); const QString &authorString = data.authorString();
@@ -3243,7 +3249,7 @@ void GitClient::vcsExecAbortable(const FilePath &workingDirectory, const QString
command->addFlags(RunFlags::ShowStdOut | RunFlags::ShowSuccessMessage); command->addFlags(RunFlags::ShowStdOut | RunFlags::ShowSuccessMessage);
// For rebase, Git might request an editor (which means the process keeps running until the // For rebase, Git might request an editor (which means the process keeps running until the
// user closes it), so run without timeout. // 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; const QObject *actualContext = context ? context : this;
connect(command, &VcsCommand::done, actualContext, [=] { connect(command, &VcsCommand::done, actualContext, [=] {
const CommandResult result = CommandResult(*command); const CommandResult result = CommandResult(*command);
@@ -3461,7 +3467,7 @@ QFuture<QVersionNumber> GitClient::gitVersion() const
// Do not execute repeatedly if that fails (due to git // Do not execute repeatedly if that fails (due to git
// not being installed) until settings are changed. // not being installed) until settings are changed.
const FilePath newGitBinary = vcsBinary(); const FilePath newGitBinary = vcsBinary({});
const bool needToRunGit = m_gitVersionForBinary != newGitBinary && !newGitBinary.isEmpty(); const bool needToRunGit = m_gitVersionForBinary != newGitBinary && !newGitBinary.isEmpty();
if (needToRunGit) { if (needToRunGit) {
auto proc = new Process(const_cast<GitClient *>(this)); auto proc = new Process(const_cast<GitClient *>(this));
@@ -3476,7 +3482,7 @@ QFuture<QVersionNumber> GitClient::gitVersion() const
proc->deleteLater(); proc->deleteLater();
}); });
proc->setEnvironment(processEnvironment()); proc->setEnvironment(processEnvironment(newGitBinary));
proc->setCommand({newGitBinary, {"--version"}}); proc->setCommand({newGitBinary, {"--version"}});
proc->start(); proc->start();
} else { } else {

View File

@@ -123,7 +123,7 @@ public:
GitClient(); GitClient();
~GitClient(); ~GitClient();
Utils::FilePath vcsBinary() const override; Utils::FilePath vcsBinary(const Utils::FilePath &forDirectory) const override;
QFuture<QVersionNumber> gitVersion() const; QFuture<QVersionNumber> gitVersion() const;
void vcsExecAbortable(const Utils::FilePath &workingDirectory, const QStringList &arguments, void vcsExecAbortable(const Utils::FilePath &workingDirectory, const QStringList &arguments,
@@ -295,7 +295,7 @@ public:
const GitSubmitEditorPanelData &data, const GitSubmitEditorPanelData &data,
CommitType commitType, CommitType commitType,
const QString &amendSHA1, const QString &amendSHA1,
const QString &messageFile, const Utils::FilePath &messageFile,
VcsBase::SubmitFileModel *model); VcsBase::SubmitFileModel *model);
enum StatusResult { StatusChanged, StatusUnchanged, StatusFailed }; enum StatusResult { StatusChanged, StatusUnchanged, StatusFailed };
@@ -318,7 +318,7 @@ public:
QStringList synchronousRepositoryBranches(const QString &repositoryURL, QStringList synchronousRepositoryBranches(const QString &repositoryURL,
const Utils::FilePath &workingDirectory = {}) const; 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, bool beginStashScope(const Utils::FilePath &workingDirectory, const QString &command,
StashFlag flag = Default, PushAction pushAction = NoPush); StashFlag flag = Default, PushAction pushAction = NoPush);
@@ -395,6 +395,7 @@ private:
mutable Utils::FilePath m_gitVersionForBinary; mutable Utils::FilePath m_gitVersionForBinary;
mutable QVersionNumber m_cachedGitVersion; mutable QVersionNumber m_cachedGitVersion;
mutable QMap<Utils::FilePath, Utils::FilePath> m_gitExecutableCache;
QString m_gitQtcEditor; QString m_gitQtcEditor;
QMap<Utils::FilePath, StashInfo> m_stashInfo; QMap<Utils::FilePath, StashInfo> m_stashInfo;

View File

@@ -134,8 +134,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().vcsBinary(); const FilePath vcsBinary = gitClient().vcsBinary(parameters.searchDir);
const Environment environment = gitClient().processEnvironment(); const Environment environment = gitClient().processEnvironment(vcsBinary);
QStringList arguments = { QStringList arguments = {
"-c", "color.grep.match=bold red", "-c", "color.grep.match=bold red",

View File

@@ -281,7 +281,7 @@ public:
const Context &context); const Context &context);
void updateRepositoryBrowserAction(); void updateRepositoryBrowserAction();
IEditor *openSubmitEditor(const QString &fileName, const CommitData &cd); IEditor *openSubmitEditor(const FilePath &fileName, const CommitData &cd);
void cleanCommitMessageFile(); void cleanCommitMessageFile();
void cleanRepository(const FilePath &directory); void cleanRepository(const FilePath &directory);
void applyPatch(const FilePath &workingDirectory, QString file = {}); void applyPatch(const FilePath &workingDirectory, QString file = {});
@@ -319,7 +319,7 @@ public:
BranchViewFactory m_branchViewFactory; BranchViewFactory m_branchViewFactory;
QPointer<RemoteDialog> m_remoteDialog; QPointer<RemoteDialog> m_remoteDialog;
FilePath m_submitRepository; FilePath m_submitRepository;
QString m_commitMessageFileName; FilePath m_commitMessageFileName;
InstantBlame m_instantBlame; InstantBlame m_instantBlame;
@@ -402,7 +402,7 @@ void GitPluginPrivate::onApplySettings()
void GitPluginPrivate::cleanCommitMessageFile() void GitPluginPrivate::cleanCommitMessageFile()
{ {
if (!m_commitMessageFileName.isEmpty()) { if (!m_commitMessageFileName.isEmpty()) {
QFile::remove(m_commitMessageFileName); m_commitMessageFileName.removeFile();
m_commitMessageFileName.clear(); m_commitMessageFileName.clear();
} }
} }
@@ -986,8 +986,12 @@ 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);
gitClient().annotate(topLevel, fileName.relativeChildPath(topLevel).toString(), gitClient().annotate(topLevel,
lineNumber, {}, extraOptions, firstLine); fileName.relativeChildPath(topLevel).path(),
lineNumber,
{},
extraOptions,
firstLine);
} }
void GitPluginPrivate::logProject() void GitPluginPrivate::logProject()
@@ -1247,7 +1251,9 @@ void GitPluginPrivate::startCommit(CommitType commitType)
m_submitRepository = data.panelInfo.repository; m_submitRepository = data.panelInfo.repository;
// Start new temp file with message template // 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 // Keep the file alive, else it removes self and forgets its name
saver.setAutoRemove(false); saver.setAutoRemove(false);
saver.write(commitTemplate.toLocal8Bit()); saver.write(commitTemplate.toLocal8Bit());
@@ -1255,7 +1261,7 @@ void GitPluginPrivate::startCommit(CommitType commitType)
VcsOutputWindow::appendError(saver.errorString()); VcsOutputWindow::appendError(saver.errorString());
return; return;
} }
m_commitMessageFileName = saver.filePath().toString(); m_commitMessageFileName = saver.filePath();
openSubmitEditor(m_commitMessageFileName, data); openSubmitEditor(m_commitMessageFileName, data);
} }
@@ -1284,10 +1290,9 @@ void GitPluginPrivate::instantBlameOnce()
m_instantBlame.once(); 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), IEditor *editor = EditorManager::openEditor(fileName, Constants::GITSUBMITEDITOR_ID);
Constants::GITSUBMITEDITOR_ID);
auto submitEditor = qobject_cast<GitSubmitEditor*>(editor); auto submitEditor = qobject_cast<GitSubmitEditor*>(editor);
QTC_ASSERT(submitEditor, return nullptr); QTC_ASSERT(submitEditor, return nullptr);
setSubmitEditor(submitEditor); setSubmitEditor(submitEditor);
@@ -1320,10 +1325,9 @@ bool GitPluginPrivate::activateCommit()
QTC_ASSERT(editorDocument, return true); QTC_ASSERT(editorDocument, return true);
// Submit editor closing. Make it write out the commit message // Submit editor closing. Make it write out the commit message
// and retrieve files // and retrieve files
const QFileInfo editorFile = editorDocument->filePath().toFileInfo();
const QFileInfo changeFile(m_commitMessageFileName);
// Paranoia! // Paranoia!
if (editorFile.absoluteFilePath() != changeFile.absoluteFilePath()) if (!editorDocument->filePath().isSameFile(m_commitMessageFileName))
return true; return true;
auto model = qobject_cast<SubmitFileModel *>(editor->fileModel()); auto model = qobject_cast<SubmitFileModel *>(editor->fileModel());
@@ -1700,7 +1704,7 @@ bool GitPluginPrivate::isVcsFileOrDirectory(const FilePath &filePath) const
bool GitPluginPrivate::isConfigured() const bool GitPluginPrivate::isConfigured() const
{ {
return !gitClient().vcsBinary().isEmpty(); return !gitClient().vcsBinary({}).isEmpty();
} }
bool GitPluginPrivate::supportsOperation(Operation operation) const bool GitPluginPrivate::supportsOperation(Operation operation) const
@@ -1765,9 +1769,10 @@ 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, gitClient().processEnvironment()); auto command = VcsBaseClient::createVcsCommand(baseDirectory,
gitClient().processEnvironment(baseDirectory));
command->addFlags(RunFlags::SuppressStdErr); command->addFlags(RunFlags::SuppressStdErr);
command->addJob({gitClient().vcsBinary(), args}, -1); command->addJob({gitClient().vcsBinary(baseDirectory), args}, -1);
return command; return command;
} }

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().vcsBinary(), arguments}; const CommandLine cmd = {gitClient().vcsBinary(workingDirectory), 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);

View File

@@ -273,7 +273,7 @@ void MercurialClient::incoming(const FilePath &repositoryRoot, const QString &re
VcsBaseEditorWidget *editor = createVcsEditor(Constants::DIFFLOG_ID, title, repositoryRoot, VcsBaseEditorWidget *editor = createVcsEditor(Constants::DIFFLOG_ID, title, repositoryRoot,
VcsBaseEditor::getCodec(repositoryRoot), VcsBaseEditor::getCodec(repositoryRoot),
"incoming", id); "incoming", id);
enqueueJob(createCommand(FilePath::fromString(repository), editor), args); enqueueJob(createCommand(FilePath::fromString(repository), editor), args, repositoryRoot);
} }
void MercurialClient::outgoing(const FilePath &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, VcsBaseEditorWidget *editor = createVcsEditor(Constants::DIFFLOG_ID, title, repositoryRoot,
VcsBaseEditor::getCodec(repositoryRoot), VcsBaseEditor::getCodec(repositoryRoot),
"outgoing", repositoryRoot.toString()); "outgoing", repositoryRoot.toString());
enqueueJob(createCommand(repositoryRoot, editor), args); enqueueJob(createCommand(repositoryRoot, editor), args, repositoryRoot);
} }
void MercurialClient::annotate(const Utils::FilePath &workingDir, const QString &file, 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); QTC_ASSERT(document, return);
auto controller = new MercurialDiffEditorController(document, args); auto controller = new MercurialDiffEditorController(document, args);
controller->setVcsBinary(settings().binaryPath()); controller->setVcsBinary(settings().binaryPath());
controller->setProcessEnvironment(processEnvironment());
controller->setWorkingDirectory(workingDirectory); controller->setWorkingDirectory(workingDirectory);
VcsBase::setSource(document, sourceCopy); VcsBase::setSource(document, sourceCopy);

View File

@@ -736,7 +736,9 @@ VcsCommand *MercurialPluginPrivate::createInitialCheckoutCommand(const QString &
{ {
QStringList args; QStringList args;
args << QLatin1String("clone") << extraArgs << url << localName; 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); command->addJob({settings().binaryPath(), args}, -1);
return command; return command;
} }

View File

@@ -57,7 +57,7 @@ bool SubversionClient::doCommit(const FilePath &repositoryRoot,
const QString &commitMessageFile, const QString &commitMessageFile,
const QStringList &extraOptions) const const QStringList &extraOptions) const
{ {
CommandLine args{vcsBinary()}; CommandLine args{vcsBinary(repositoryRoot)};
args << vcsCommandString(CommitCommand) args << vcsCommandString(CommitCommand)
<< extraOptions << extraOptions
<< AddAuthOptions() << AddAuthOptions()
@@ -117,7 +117,7 @@ QString SubversionClient::synchronousTopic(const FilePath &repository) const
{ {
QStringList args; QStringList args;
QString svnVersionBinary = vcsBinary().toString(); QString svnVersionBinary = vcsBinary(repository).toString();
int pos = svnVersionBinary.lastIndexOf('/'); int pos = svnVersionBinary.lastIndexOf('/');
if (pos < 0) if (pos < 0)
svnVersionBinary.clear(); svnVersionBinary.clear();
@@ -237,7 +237,7 @@ SubversionDiffEditorController *SubversionClient::findOrCreateDiffEditor(const Q
if (!controller) { if (!controller) {
controller = new SubversionDiffEditorController(document); controller = new SubversionDiffEditorController(document);
controller->setVcsBinary(settings().binaryPath()); controller->setVcsBinary(settings().binaryPath());
controller->setProcessEnvironment(processEnvironment()); controller->setProcessEnvironment(processEnvironment(workingDirectory));
controller->setWorkingDirectory(workingDirectory); controller->setWorkingDirectory(workingDirectory);
} }
VcsBase::setSource(document, source); VcsBase::setSource(document, source);

View File

@@ -1135,7 +1135,9 @@ VcsCommand *SubversionPluginPrivate::createInitialCheckoutCommand(const QString
args << SubversionClient::AddAuthOptions(); args << SubversionClient::AddAuthOptions();
args << Subversion::Constants::NON_INTERACTIVE_OPTION << extraArgs << url << localName; 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); command->addJob(args, -1);
return command; return command;
} }

View File

@@ -61,15 +61,18 @@ VcsBaseClientImpl::VcsBaseClientImpl(VcsBaseSettings *baseSettings)
this, &VcsBaseClientImpl::saveSettings); this, &VcsBaseClientImpl::saveSettings);
} }
FilePath VcsBaseClientImpl::vcsBinary() const FilePath VcsBaseClientImpl::vcsBinary(const Utils::FilePath &forDirectory) const
{ {
if (forDirectory.needsDevice())
return {};
return m_baseSettings->binaryPath(); return m_baseSettings->binaryPath();
} }
VcsCommand *VcsBaseClientImpl::createCommand(const FilePath &workingDirectory, VcsCommand *VcsBaseClientImpl::createCommand(const FilePath &workingDirectory,
VcsBaseEditorWidget *editor) const VcsBaseEditorWidget *editor) const
{ {
auto cmd = createVcsCommand(workingDirectory, processEnvironment()); auto cmd = createVcsCommand(workingDirectory, processEnvironment(workingDirectory));
if (editor) { if (editor) {
editor->setCommand(cmd); editor->setCommand(cmd);
connect(cmd, &VcsCommand::done, editor, [editor, cmd] { connect(cmd, &VcsCommand::done, editor, [editor, cmd] {
@@ -88,24 +91,24 @@ void VcsBaseClientImpl::setupCommand(Utils::Process &process,
const FilePath &workingDirectory, const FilePath &workingDirectory,
const QStringList &args) const const QStringList &args) const
{ {
process.setEnvironment(processEnvironment()); process.setEnvironment(workingDirectory.deviceEnvironment());
process.setWorkingDirectory(workingDirectory); process.setWorkingDirectory(workingDirectory);
process.setCommand({vcsBinary(), args}); process.setCommand({vcsBinary(workingDirectory), args});
process.setUseCtrlCStub(true); 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 const ExitCodeInterpreter &interpreter) const
{ {
cmd->addJob({vcsBinary(), args}, vcsTimeoutS(), {}, interpreter); cmd->addJob({vcsBinary(forDirectory), args}, vcsTimeoutS(), {}, interpreter);
cmd->start(); cmd->start();
} }
Environment VcsBaseClientImpl::processEnvironment() const Environment VcsBaseClientImpl::processEnvironment(const FilePath &appliedTo) const
{ {
Environment environment = Environment::systemEnvironment(); return appliedTo.deviceEnvironment();
VcsBase::setProcessEnvironment(&environment);
return environment;
} }
QStringList VcsBaseClientImpl::splitLines(const QString &s) QStringList VcsBaseClientImpl::splitLines(const QString &s)
@@ -129,14 +132,18 @@ QString VcsBaseClientImpl::stripLastNewline(const QString &in)
CommandResult VcsBaseClientImpl::vcsSynchronousExec(const FilePath &workingDir, CommandResult VcsBaseClientImpl::vcsSynchronousExec(const FilePath &workingDir,
const QStringList &args, RunFlags flags, int timeoutS, QTextCodec *codec) const 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, CommandResult VcsBaseClientImpl::vcsSynchronousExec(const FilePath &workingDir,
const CommandLine &cmdLine, RunFlags flags, int timeoutS, QTextCodec *codec) const const CommandLine &cmdLine, RunFlags flags, int timeoutS, QTextCodec *codec) const
{ {
return VcsCommand::runBlocking(workingDir, processEnvironment(), cmdLine, flags, return VcsCommand::runBlocking(workingDir,
timeoutS > 0 ? timeoutS : vcsTimeoutS(), codec); processEnvironment(workingDir),
cmdLine,
flags,
timeoutS > 0 ? timeoutS : vcsTimeoutS(),
codec);
} }
void VcsBaseClientImpl::resetCachedVcsInfo(const FilePath &workingDir) void VcsBaseClientImpl::resetCachedVcsInfo(const FilePath &workingDir)
@@ -166,7 +173,7 @@ void VcsBaseClientImpl::vcsExecWithHandler(const FilePath &workingDirectory,
VcsCommand *command = createCommand(workingDirectory); VcsCommand *command = createCommand(workingDirectory);
command->addFlags(additionalFlags); command->addFlags(additionalFlags);
command->setCodec(codec); command->setCodec(codec);
command->addJob({vcsBinary(), arguments}, vcsTimeoutS()); command->addJob({vcsBinary(workingDirectory), arguments}, vcsTimeoutS());
if (handler) { if (handler) {
const QObject *actualContext = context ? context : this; const QObject *actualContext = context ? context : this;
connect(command, &VcsCommand::done, actualContext, [command, handler] { connect(command, &VcsCommand::done, actualContext, [command, handler] {
@@ -182,7 +189,7 @@ void VcsBaseClientImpl::vcsExec(const FilePath &workingDirectory,
{ {
VcsCommand *command = createCommand(workingDirectory); VcsCommand *command = createCommand(workingDirectory);
command->addFlags(additionalFlags); command->addFlags(additionalFlags);
command->addJob({vcsBinary(), arguments}, vcsTimeoutS()); command->addJob({vcsBinary(workingDirectory), arguments}, vcsTimeoutS());
command->start(); command->start();
} }
@@ -192,7 +199,7 @@ void VcsBaseClientImpl::vcsExecWithEditor(const Utils::FilePath &workingDirector
{ {
VcsCommand *command = createCommand(workingDirectory, editor); VcsCommand *command = createCommand(workingDirectory, editor);
command->setCodec(editor->codec()); command->setCodec(editor->codec());
command->addJob({vcsBinary(), arguments}, vcsTimeoutS()); command->addJob({vcsBinary(workingDirectory), arguments}, vcsTimeoutS());
command->start(); command->start();
} }
@@ -350,7 +357,7 @@ void VcsBaseClient::annotate(const Utils::FilePath &workingDir, const QString &f
VcsCommand *cmd = createCommand(workingDir, editor); VcsCommand *cmd = createCommand(workingDir, editor);
editor->setDefaultLineNumber(lineNumber); editor->setDefaultLineNumber(lineNumber);
enqueueJob(cmd, args); enqueueJob(cmd, args, workingDir);
} }
void VcsBaseClient::diff(const FilePath &workingDir, const QStringList &files) 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); : VcsBaseEditor::getCodec(source);
VcsCommand *command = createCommand(workingDir, editor); VcsCommand *command = createCommand(workingDir, editor);
command->setCodec(codec); command->setCodec(codec);
enqueueJob(command, args, exitCodeInterpreter(DiffCommand)); enqueueJob(command, args, workingDir, exitCodeInterpreter(DiffCommand));
} }
void VcsBaseClient::log(const FilePath &workingDir, 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) if (addAuthOptions)
addAuthOptions(args); addAuthOptions(args);
if (editorConfig) if (editorConfig)
@@ -448,7 +455,7 @@ void VcsBaseClient::revertFile(const FilePath &workingDir,
if (cmd->result() == ProcessResult::FinishedWithSuccess) if (cmd->result() == ProcessResult::FinishedWithSuccess)
emit changed(files); emit changed(files);
}); });
enqueueJob(cmd, args); enqueueJob(cmd, args, workingDir);
} }
void VcsBaseClient::revertAll(const FilePath &workingDir, void VcsBaseClient::revertAll(const FilePath &workingDir,
@@ -464,7 +471,7 @@ void VcsBaseClient::revertAll(const FilePath &workingDir,
if (cmd->result() == ProcessResult::FinishedWithSuccess) if (cmd->result() == ProcessResult::FinishedWithSuccess)
emit changed(files); emit changed(files);
}); });
enqueueJob(cmd, args); enqueueJob(cmd, args, workingDir);
} }
void VcsBaseClient::status(const FilePath &workingDir, void VcsBaseClient::status(const FilePath &workingDir,
@@ -475,7 +482,7 @@ void VcsBaseClient::status(const FilePath &workingDir,
args << extraOptions << file; args << extraOptions << file;
VcsCommand *cmd = createCommand(workingDir); VcsCommand *cmd = createCommand(workingDir);
cmd->addFlags(RunFlags::ShowStdOut); cmd->addFlags(RunFlags::ShowStdOut);
enqueueJob(cmd, args); enqueueJob(cmd, args, workingDir);
} }
void VcsBaseClient::emitParsedStatus(const FilePath &repository, const QStringList &extraOptions) void VcsBaseClient::emitParsedStatus(const FilePath &repository, const QStringList &extraOptions)
@@ -484,7 +491,7 @@ void VcsBaseClient::emitParsedStatus(const FilePath &repository, const QStringLi
args << extraOptions; args << extraOptions;
VcsCommand *cmd = createCommand(repository); VcsCommand *cmd = createCommand(repository);
connect(cmd, &VcsCommand::done, this, [this, cmd] { statusParser(cmd->cleanedStdOut()); }); connect(cmd, &VcsCommand::done, this, [this, cmd] { statusParser(cmd->cleanedStdOut()); });
enqueueJob(cmd, args); enqueueJob(cmd, args, repository);
} }
QString VcsBaseClient::vcsCommandString(VcsCommandTag cmd) const QString VcsBaseClient::vcsCommandString(VcsCommandTag cmd) const
@@ -525,7 +532,7 @@ void VcsBaseClient::import(const FilePath &repositoryRoot,
{ {
QStringList args(vcsCommandString(ImportCommand)); QStringList args(vcsCommandString(ImportCommand));
args << extraOptions << files; args << extraOptions << files;
enqueueJob(createCommand(repositoryRoot), args); enqueueJob(createCommand(repositoryRoot), args, repositoryRoot);
} }
void VcsBaseClient::view(const FilePath &source, void VcsBaseClient::view(const FilePath &source,
@@ -541,7 +548,7 @@ void VcsBaseClient::view(const FilePath &source,
VcsBaseEditor::getCodec(source), "view", id); VcsBaseEditor::getCodec(source), "view", id);
const FilePath workingDirPath = source.isFile() ? source.absolutePath() : source; 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, 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) if (cmd->result() == ProcessResult::FinishedWithSuccess)
emit changed(repositoryRoot.toString()); emit changed(repositoryRoot.toString());
}); });
enqueueJob(cmd, args); enqueueJob(cmd, args, repositoryRoot);
} }
void VcsBaseClient::commit(const FilePath &repositoryRoot, void VcsBaseClient::commit(const FilePath &repositoryRoot,
@@ -576,12 +583,12 @@ void VcsBaseClient::commit(const FilePath &repositoryRoot,
cmd->addFlags(RunFlags::ShowStdOut); cmd->addFlags(RunFlags::ShowStdOut);
if (!commitMessageFile.isEmpty()) if (!commitMessageFile.isEmpty())
connect(cmd, &VcsCommand::done, [commitMessageFile] { QFile(commitMessageFile).remove(); }); 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 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(); + FilePath::fromString(sourceId).fileName();
} }

View File

@@ -41,7 +41,7 @@ public:
explicit VcsBaseClientImpl(VcsBaseSettings *baseSettings); explicit VcsBaseClientImpl(VcsBaseSettings *baseSettings);
~VcsBaseClientImpl() override = default; ~VcsBaseClientImpl() override = default;
virtual Utils::FilePath vcsBinary() const; virtual Utils::FilePath vcsBinary(const Utils::FilePath &forDirectory) const;
int vcsTimeoutS() const; int vcsTimeoutS() const;
static VcsCommand *createVcsCommand(const Utils::FilePath &defaultWorkingDir, static VcsCommand *createVcsCommand(const Utils::FilePath &defaultWorkingDir,
@@ -59,10 +59,12 @@ public:
const Utils::FilePath &workingDirectory, const Utils::FilePath &workingDirectory,
const QStringList &args) const; 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; const ExitCodeInterpreter &interpreter = {}) const;
virtual Utils::Environment processEnvironment() const; virtual Utils::Environment processEnvironment(const Utils::FilePath &appliedTo) const;
// VCS functionality: // VCS functionality:
virtual void annotate(const Utils::FilePath &workingDir, const QString &file, virtual void annotate(const Utils::FilePath &workingDir, const QString &file,

View File

@@ -1327,7 +1327,7 @@ bool VcsBaseEditor::gotoLineOfEditor(IEditor *e, int lineNumber)
// ('git diff XX' -> 'XX' , 'git diff XX file' -> 'XX/file'). // ('git diff XX' -> 'XX' , 'git diff XX file' -> 'XX/file').
FilePath VcsBaseEditor::getSource(const FilePath &workingDirectory, const QString &fileName) 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) FilePath VcsBaseEditor::getSource(const FilePath &workingDirectory, const QStringList &fileNames)

View File

@@ -374,7 +374,7 @@ FilePath VcsBasePluginState::currentFileDirectory() const
QString VcsBasePluginState::relativeCurrentFile() const QString VcsBasePluginState::relativeCurrentFile() const
{ {
QTC_ASSERT(hasFile(), return {}); 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 QString VcsBasePluginState::currentPatchFile() const

View File

@@ -82,9 +82,11 @@ public:
void setProgressParser(const Core::ProgressParser &parser); void setProgressParser(const Core::ProgressParser &parser);
static CommandResult runBlocking(const Utils::FilePath &workingDirectory, static CommandResult runBlocking(const Utils::FilePath &workingDirectory,
const Utils::Environment &environmentconst, const Utils::Environment &environment,
const Utils::CommandLine &command, RunFlags flags, const Utils::CommandLine &command,
int timeoutS, QTextCodec *codec); RunFlags flags,
int timeoutS,
QTextCodec *codec);
void cancel(); void cancel();
QString cleanedStdOut() const; QString cleanedStdOut() const;