From 87e5ac74385ffcb8713510c9e243e2455cb17516 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Tue, 17 Jan 2023 13:10:21 +0200 Subject: [PATCH] Subversion: Mask credentials in command line everywhere Fixes: QTCREATORBUG-28413 Change-Id: I763c26944d89a8dcc7151e10b8eed5d9642fb982 Reviewed-by: Jarek Kobus --- src/libs/utils/commandline.cpp | 36 ++++++- src/libs/utils/commandline.h | 7 ++ src/plugins/subversion/subversionclient.cpp | 66 +++++++------ src/plugins/subversion/subversionclient.h | 10 +- src/plugins/subversion/subversionplugin.cpp | 103 +++++++++----------- src/plugins/vcsbase/vcsbaseclient.cpp | 20 +++- src/plugins/vcsbase/vcsbaseclient.h | 3 +- 7 files changed, 150 insertions(+), 95 deletions(-) diff --git a/src/libs/utils/commandline.cpp b/src/libs/utils/commandline.cpp index a23e9f96a13..6f8d4a4f5d9 100644 --- a/src/libs/utils/commandline.cpp +++ b/src/libs/utils/commandline.cpp @@ -622,6 +622,18 @@ void ProcessArgs::addArgs(QString *args, const QStringList &inArgs) addArg(args, arg); } +CommandLine &CommandLine::operator<<(const QString &arg) +{ + addArg(arg); + return *this; +} + +CommandLine &CommandLine::operator<<(const QStringList &args) +{ + addArgs(args); + return *this; +} + bool ProcessArgs::prepareCommand(const CommandLine &cmdLine, QString *outCmd, ProcessArgs *outArgs, const Environment *env, const FilePath *pwd) { @@ -1432,7 +1444,7 @@ CommandLine CommandLine::fromUserInput(const QString &cmdline, MacroExpander *ex void CommandLine::addArg(const QString &arg) { - ProcessArgs::addArg(&m_arguments, arg, m_executable.osType()); + addArg(arg, m_executable.osType()); } void CommandLine::addArg(const QString &arg, OsType osType) @@ -1440,6 +1452,20 @@ void CommandLine::addArg(const QString &arg, OsType osType) ProcessArgs::addArg(&m_arguments, arg, osType); } +void CommandLine::addMaskedArg(const QString &arg) +{ + addMaskedArg(arg, m_executable.osType()); +} + +void CommandLine::addMaskedArg(const QString &arg, OsType osType) +{ + int start = m_arguments.size(); + if (start > 0) + ++start; + addArg(arg, osType); + m_masked.push_back({start, m_arguments.size() - start}); +} + void CommandLine::addArgs(const QStringList &inArgs) { for (const QString &arg : inArgs) @@ -1509,8 +1535,12 @@ void CommandLine::prependArgs(const QString &inArgs, RawType) QString CommandLine::toUserOutput() const { QString res = m_executable.toUserOutput(); - if (!m_arguments.isEmpty()) - res += ' ' + m_arguments; + if (!m_arguments.isEmpty()) { + QString args = m_arguments; + for (auto it = m_masked.crbegin(), end = m_masked.crend(); it != end; ++it) + args.replace(it->first, it->second, "*******"); + res += ' ' + args; + } return res; } diff --git a/src/libs/utils/commandline.h b/src/libs/utils/commandline.h index caf4e0df002..23585adb8af 100644 --- a/src/libs/utils/commandline.h +++ b/src/libs/utils/commandline.h @@ -8,6 +8,8 @@ #include "filepath.h" #include "hostosinfo.h" +#include +#include #include namespace Utils { @@ -126,9 +128,13 @@ public: void addArg(const QString &arg); void addArg(const QString &arg, OsType osType); + void addMaskedArg(const QString &arg); + void addMaskedArg(const QString &arg, OsType osType); void addArgs(const QStringList &inArgs); void addArgs(const QStringList &inArgs, OsType osType); void addArgs(const QString &inArgs, RawType); + CommandLine &operator<<(const QString &arg); + CommandLine &operator<<(const QStringList &arg); void prependArgs(const QStringList &inArgs); void prependArgs(const QString &inArgs, RawType); @@ -158,6 +164,7 @@ private: FilePath m_executable; QString m_arguments; + QList> m_masked; }; } // Utils diff --git a/src/plugins/subversion/subversionclient.cpp b/src/plugins/subversion/subversionclient.cpp index ccfddccdcbc..d904255f28d 100644 --- a/src/plugins/subversion/subversionclient.cpp +++ b/src/plugins/subversion/subversionclient.cpp @@ -34,6 +34,8 @@ using namespace VcsBase; namespace Subversion { namespace Internal { +static SubversionSettings *s_settings = nullptr; + class SubversionLogConfig : public VcsBaseEditorConfig { Q_OBJECT @@ -49,6 +51,7 @@ public: SubversionClient::SubversionClient(SubversionSettings *settings) : VcsBaseClient(settings) { + s_settings = settings; setLogConfigCreator([settings](QToolBar *toolBar) { return new SubversionLogConfig(*settings, toolBar); }); @@ -59,10 +62,10 @@ bool SubversionClient::doCommit(const FilePath &repositoryRoot, const QString &commitMessageFile, const QStringList &extraOptions) const { - QStringList args; + CommandLine args{vcsBinary()}; args << vcsCommandString(CommitCommand) << extraOptions - << SubversionClient::addAuthenticationOptions(static_cast(settings())) + << AddAuthOptions() << QLatin1String(Constants::NON_INTERACTIVE_OPTION) << QLatin1String("--encoding") << QLatin1String("UTF-8") @@ -96,25 +99,23 @@ Id SubversionClient::vcsEditorKind(VcsCommandTag cmd) const } // Add authorization options to the command line arguments. -QStringList SubversionClient::addAuthenticationOptions(const SubversionSettings &settings) +CommandLine &operator<<(Utils::CommandLine &command, const SubversionClient::AddAuthOptions &addAuth) { - if (!settings.hasAuthentication()) - return QStringList(); + if (!s_settings->hasAuthentication()) + return command; - const QString userName = settings.userName.value(); - const QString password = settings.password.value(); + const QString userName = s_settings->userName.value(); + const QString password = s_settings->password.value(); if (userName.isEmpty()) - return QStringList(); + return command; - QStringList rc; - rc.push_back(QLatin1String("--username")); - rc.push_back(userName); + command << "--username" << userName; if (!password.isEmpty()) { - rc.push_back(QLatin1String("--password")); - rc.push_back(password); + command << "--password"; + command.addMaskedArg(password); } - return rc; + return command; } QString SubversionClient::synchronousTopic(const FilePath &repository) const @@ -149,7 +150,7 @@ class SubversionDiffEditorController : public VcsBaseDiffEditorController { Q_OBJECT public: - SubversionDiffEditorController(IDocument *document, const QStringList &authOptions); + SubversionDiffEditorController(IDocument *document); void setFilesList(const QStringList &filesList); void setChangeNumber(int changeNumber); @@ -159,8 +160,7 @@ private: int m_changeNumber = 0; }; -SubversionDiffEditorController::SubversionDiffEditorController(IDocument *document, - const QStringList &authOptions) +SubversionDiffEditorController::SubversionDiffEditorController(IDocument *document) : VcsBaseDiffEditorController(document) { setDisplayName("Svn Diff"); @@ -176,10 +176,11 @@ SubversionDiffEditorController::SubversionDiffEditorController(IDocument *docume return GroupConfig(); }; - const auto setupDescription = [this, authOptions](QtcProcess &process) { - const QStringList args = QStringList{"log"} << authOptions << "-r" - << QString::number(m_changeNumber); - setupCommand(process, args); + const auto setupDescription = [this](QtcProcess &process) { + setupCommand(process, {"log", "-r", QString::number(m_changeNumber)}); + CommandLine command = process.commandLine(); + command << SubversionClient::AddAuthOptions(); + process.setCommand(command); setDescription(tr("Waiting for data...")); }; const auto onDescriptionDone = [this](const QtcProcess &process) { @@ -189,8 +190,8 @@ SubversionDiffEditorController::SubversionDiffEditorController(IDocument *docume setDescription({}); }; - const auto setupDiff = [this, authOptions](QtcProcess &process) { - QStringList args = QStringList{"diff"} << authOptions << "--internal-diff"; + const auto setupDiff = [this](QtcProcess &process) { + QStringList args = QStringList{"diff"} << "--internal-diff"; if (ignoreWhitespace()) args << "-x" << "-uw"; if (m_changeNumber) @@ -199,6 +200,9 @@ SubversionDiffEditorController::SubversionDiffEditorController(IDocument *docume args << m_filesList; setupCommand(process, args); + CommandLine command = process.commandLine(); + command << SubversionClient::AddAuthOptions(); + process.setCommand(command); }; const auto onDiffDone = [diffInputStorage](const QtcProcess &process) { *diffInputStorage.activeStorage() = process.cleanedStdOut(); @@ -244,7 +248,7 @@ SubversionDiffEditorController *SubversionClient::findOrCreateDiffEditor(const Q auto controller = qobject_cast( DiffEditorController::controller(document)); if (!controller) { - controller = new SubversionDiffEditorController(document, addAuthenticationOptions(settings)); + controller = new SubversionDiffEditorController(document); controller->setVcsBinary(settings.binaryPath.filePath()); controller->setProcessEnvironment(processEnvironment()); controller->setWorkingDirectory(workingDirectory); @@ -270,19 +274,25 @@ void SubversionClient::diff(const FilePath &workingDirectory, const QStringList controller->requestReload(); } -void SubversionClient::log(const FilePath &workingDir, const QStringList &files, - const QStringList &extraOptions, bool enableAnnotationContextMenu) +void SubversionClient::log(const FilePath &workingDir, + const QStringList &files, + const QStringList &extraOptions, + bool enableAnnotationContextMenu, + const std::function &addAuthOptions) { auto &settings = static_cast(this->settings()); const int logCount = settings.logCount.value(); QStringList svnExtraOptions = extraOptions; - svnExtraOptions.append(SubversionClient::addAuthenticationOptions(settings)); if (logCount > 0) svnExtraOptions << QLatin1String("-l") << QString::number(logCount); // subversion stores log in UTF-8 and returns it back in user system locale. // So we do not need to encode it. - VcsBaseClient::log(workingDir, escapeFiles(files), svnExtraOptions, enableAnnotationContextMenu); + VcsBaseClient::log(workingDir, + escapeFiles(files), + svnExtraOptions, + enableAnnotationContextMenu, + addAuthOptions); } void SubversionClient::describe(const FilePath &workingDirectory, int changeNumber, diff --git a/src/plugins/subversion/subversionclient.h b/src/plugins/subversion/subversionclient.h index ca87e006170..5b0bdb230df 100644 --- a/src/plugins/subversion/subversionclient.h +++ b/src/plugins/subversion/subversionclient.h @@ -36,12 +36,13 @@ public: void log(const Utils::FilePath &workingDir, const QStringList &files = {}, const QStringList &extraOptions = {}, - bool enableAnnotationContextMenu = false) override; + bool enableAnnotationContextMenu = false, + const std::function &addAuthOptions = {}) override; void describe(const Utils::FilePath &workingDirectory, int changeNumber, const QString &title); - // Add authorization options to the command line arguments. - static QStringList addAuthenticationOptions(const SubversionSettings &settings); + // Add authentication options to the command line arguments. + struct AddAuthOptions {}; QString synchronousTopic(const Utils::FilePath &repository) const; @@ -59,5 +60,8 @@ private: mutable QString m_svnVersion; }; +Utils::CommandLine &operator<<(Utils::CommandLine &command, + const SubversionClient::AddAuthOptions &addAuth); + } // namespace Internal } // namespace Subversion diff --git a/src/plugins/subversion/subversionplugin.cpp b/src/plugins/subversion/subversionplugin.cpp index d928263e8a0..b6a506145cb 100644 --- a/src/plugins/subversion/subversionplugin.cpp +++ b/src/plugins/subversion/subversionplugin.cpp @@ -214,7 +214,7 @@ public: QString monitorFile(const FilePath &repository) const; QString synchronousTopic(const FilePath &repository) const; - CommandResult runSvn(const FilePath &workingDir, const QStringList &arguments, + CommandResult runSvn(const FilePath &workingDir, const CommandLine &command, RunFlags flags = RunFlags::None, QTextCodec *outputCodec = nullptr, int timeoutMutiplier = 1) const; void vcsAnnotateHelper(const FilePath &workingDir, const QString &file, @@ -643,9 +643,8 @@ void SubversionPluginPrivate::revertAll() QMessageBox::Yes, QMessageBox::No) == QMessageBox::No) return; // NoteL: Svn "revert ." doesn not work. - QStringList args; - args << QLatin1String("revert"); - args << SubversionClient::addAuthenticationOptions(m_settings); + CommandLine args{m_settings.binaryPath.filePath(), {"revert"}}; + args << SubversionClient::AddAuthOptions(); args << QLatin1String("--recursive") << state.topLevel().toString(); const auto revertResponse = runSvn(state.topLevel(), args, RunFlags::ShowStdOut); if (revertResponse.result() != ProcessResult::FinishedWithSuccess) { @@ -661,11 +660,11 @@ void SubversionPluginPrivate::revertCurrentFile() const VcsBasePluginState state = currentState(); QTC_ASSERT(state.hasFile(), return); - QStringList args(QLatin1String("diff")); - args << SubversionClient::addAuthenticationOptions(m_settings); - args.push_back(SubversionClient::escapeFile(state.relativeCurrentFile())); + CommandLine diffArgs{m_settings.binaryPath.filePath(), {"diff"}}; + diffArgs << SubversionClient::AddAuthOptions(); + diffArgs << SubversionClient::escapeFile(state.relativeCurrentFile()); - const auto diffResponse = runSvn(state.currentFileTopLevel(), args); + const auto diffResponse = runSvn(state.currentFileTopLevel(), diffArgs); if (diffResponse.result() != ProcessResult::FinishedWithSuccess) return; if (diffResponse.cleanedStdOut().isEmpty()) @@ -679,9 +678,8 @@ void SubversionPluginPrivate::revertCurrentFile() FileChangeBlocker fcb(FilePath::fromString(state.currentFile())); // revert - args.clear(); - args << QLatin1String("revert"); - args << SubversionClient::addAuthenticationOptions(m_settings); + CommandLine args{m_settings.binaryPath.filePath(), {"revert"}}; + args << SubversionClient::AddAuthOptions(); args << SubversionClient::escapeFile(state.relativeCurrentFile()); const auto revertResponse = runSvn(state.currentFileTopLevel(), args, RunFlags::ShowStdOut); @@ -741,9 +739,9 @@ void SubversionPluginPrivate::startCommit(const FilePath &workingDir, const QStr return; } - QStringList args(QLatin1String("status")); - args << SubversionClient::addAuthenticationOptions(m_settings); - args += SubversionClient::escapeFiles(files); + CommandLine args{m_settings.binaryPath.filePath(), {"status"}}; + args << SubversionClient::AddAuthOptions(); + args << SubversionClient::escapeFiles(files); const auto response = runSvn(workingDir, args); if (response.result() != ProcessResult::FinishedWithSuccess) @@ -820,10 +818,10 @@ void SubversionPluginPrivate::svnStatus(const FilePath &workingDir, const QStrin { const VcsBasePluginState state = currentState(); QTC_ASSERT(state.hasTopLevel(), return); - QStringList args(QLatin1String("status")); - args << SubversionClient::addAuthenticationOptions(m_settings); + CommandLine args{m_settings.binaryPath.filePath(), {"status"}}; + args << SubversionClient::AddAuthOptions(); if (!relativePath.isEmpty()) - args.append(SubversionClient::escapeFile(relativePath)); + args << SubversionClient::escapeFile(relativePath); VcsOutputWindow::setRepository(workingDir); runSvn(workingDir, args, RunFlags::ShowStdOut | RunFlags::ShowSuccessMessage); VcsOutputWindow::clearRepository(); @@ -833,7 +831,8 @@ void SubversionPluginPrivate::filelog(const FilePath &workingDir, const QString &file, bool enableAnnotationContextMenu) { - m_client->log(workingDir, QStringList(file), QStringList(), enableAnnotationContextMenu); + m_client->log(workingDir, QStringList(file), QStringList(), enableAnnotationContextMenu, + [](CommandLine &command) { command << SubversionClient::AddAuthOptions(); }); } void SubversionPluginPrivate::updateProject() @@ -845,11 +844,11 @@ void SubversionPluginPrivate::updateProject() void SubversionPluginPrivate::svnUpdate(const FilePath &workingDir, const QString &relativePath) { - QStringList args(QLatin1String("update")); - args << SubversionClient::addAuthenticationOptions(m_settings); - args.push_back(QLatin1String(Constants::NON_INTERACTIVE_OPTION)); + CommandLine args{m_settings.binaryPath.filePath(), {"update"}}; + args << SubversionClient::AddAuthOptions(); + args << Constants::NON_INTERACTIVE_OPTION; if (!relativePath.isEmpty()) - args.append(relativePath); + args << relativePath; const auto response = runSvn(workingDir, args, RunFlags::ShowStdOut, nullptr, 10); if (response.result() == ProcessResult::FinishedWithSuccess) emit repositoryChanged(workingDir); @@ -869,14 +868,13 @@ void SubversionPluginPrivate::vcsAnnotateHelper(const FilePath &workingDir, cons const QString source = VcsBaseEditor::getSource(workingDir, file); QTextCodec *codec = VcsBaseEditor::getCodec(source); - QStringList args(QLatin1String("annotate")); - args << SubversionClient::addAuthenticationOptions(m_settings); + CommandLine args{m_settings.binaryPath.filePath(), {"annotate"}}; + args << SubversionClient::AddAuthOptions(); if (m_settings.spaceIgnorantAnnotation.value()) - args << QLatin1String("-x") << QLatin1String("-uw"); + args << "-x" << "-uw"; if (!revision.isEmpty()) - args << QLatin1String("-r") << revision; - args.push_back(QLatin1String("-v")); - args.append(QDir::toNativeSeparators(SubversionClient::escapeFile(file))); + args << "-r" << revision; + args << "-v" << QDir::toNativeSeparators(SubversionClient::escapeFile(file)); const auto response = runSvn(workingDir, args, RunFlags::ForceCLocale, codec); if (response.result() != ProcessResult::FinishedWithSuccess) @@ -951,14 +949,14 @@ void SubversionPluginPrivate::slotDescribe() } CommandResult SubversionPluginPrivate::runSvn(const FilePath &workingDir, - const QStringList &arguments, RunFlags flags, + const CommandLine &command, RunFlags flags, QTextCodec *outputCodec, int timeoutMutiplier) const { if (m_settings.binaryPath.value().isEmpty()) return CommandResult(ProcessResult::StartFailed, tr("No subversion executable specified.")); const int timeoutS = m_settings.timeout.value() * timeoutMutiplier; - return m_client->vcsSynchronousExec(workingDir, arguments, flags, timeoutS, outputCodec); + return m_client->vcsSynchronousExec(workingDir, command, flags, timeoutS, outputCodec); } IEditor *SubversionPluginPrivate::showOutputInEditor(const QString &title, const QString &output, @@ -1013,10 +1011,8 @@ QString SubversionPluginPrivate::synchronousTopic(const FilePath &repository) co bool SubversionPluginPrivate::vcsAdd(const FilePath &workingDir, const QString &rawFileName) { const QString file = QDir::toNativeSeparators(SubversionClient::escapeFile(rawFileName)); - QStringList args; - args << QLatin1String("add") - << SubversionClient::addAuthenticationOptions(m_settings) - << QLatin1String("--parents") << file; + CommandLine args{m_settings.binaryPath.filePath()}; + args << "add" << SubversionClient::AddAuthOptions() << "--parents" << file; return runSvn(workingDir, args, RunFlags::ShowStdOut).result() == ProcessResult::FinishedWithSuccess; } @@ -1025,10 +1021,8 @@ bool SubversionPluginPrivate::vcsDelete(const FilePath &workingDir, const QStrin { const QString file = QDir::toNativeSeparators(SubversionClient::escapeFile(rawFileName)); - QStringList args; - args << QLatin1String("delete"); - args << SubversionClient::addAuthenticationOptions(m_settings) - << QLatin1String("--force") << file; + CommandLine args{m_settings.binaryPath.filePath()}; + args << "delete" << SubversionClient::AddAuthOptions() << "--force" << file; return runSvn(workingDir, args, RunFlags::ShowStdOut).result() == ProcessResult::FinishedWithSuccess; @@ -1036,9 +1030,9 @@ bool SubversionPluginPrivate::vcsDelete(const FilePath &workingDir, const QStrin bool SubversionPluginPrivate::vcsMove(const FilePath &workingDir, const QString &from, const QString &to) { - QStringList args(QLatin1String("move")); - args << SubversionClient::addAuthenticationOptions(m_settings); - args << QDir::toNativeSeparators(SubversionClient::escapeFile(from)) + CommandLine args{m_settings.binaryPath.filePath(), {"move"}}; + args << SubversionClient::AddAuthOptions() + << QDir::toNativeSeparators(SubversionClient::escapeFile(from)) << QDir::toNativeSeparators(SubversionClient::escapeFile(to)); return runSvn(workingDir, args, RunFlags::ShowStdOut).result() == ProcessResult::FinishedWithSuccess; @@ -1049,8 +1043,8 @@ bool SubversionPluginPrivate::vcsCheckout(const FilePath &directory, const QByte QUrl tempUrl = QUrl::fromEncoded(url); const QString username = tempUrl.userName(); const QString password = tempUrl.password(); - QStringList args = QStringList(QLatin1String("checkout")); - args << QLatin1String(Constants::NON_INTERACTIVE_OPTION) ; + CommandLine args{m_settings.binaryPath.filePath(), {"checkout"}}; + args << Constants::NON_INTERACTIVE_OPTION; if (!username.isEmpty()) { // If url contains username and password we have to use separate username and password @@ -1059,12 +1053,13 @@ bool SubversionPluginPrivate::vcsCheckout(const FilePath &directory, const QByte // if for example we are logging into a new host for the first time using svn. There seems to // be a bug in subversion, so this might get fixed in the future. tempUrl.setUserInfo({}); - args << QLatin1String("--username") << username; + args << "--username" << username; if (!password.isEmpty()) - args << QLatin1String("--password") << password; + args << "--password"; + args.addMaskedArg(password); } - args << QLatin1String(tempUrl.toEncoded()) << directory.toString(); + args << QString::fromLatin1(tempUrl.toEncoded()) << directory.toString(); return runSvn(directory, args, RunFlags::None, nullptr, 10).result() == ProcessResult::FinishedWithSuccess; @@ -1095,9 +1090,8 @@ bool SubversionPluginPrivate::managesDirectory(const FilePath &directory, FilePa bool SubversionPluginPrivate::managesFile(const FilePath &workingDirectory, const QString &fileName) const { - QStringList args; - args << QLatin1String("status"); - args << SubversionClient::addAuthenticationOptions(m_settings) + CommandLine args{m_settings.binaryPath.filePath()}; + args << "status" << SubversionClient::AddAuthOptions() << QDir::toNativeSeparators(SubversionClient::escapeFile(fileName)); const QString output = runSvn(workingDirectory, args).cleanedStdOut(); return output.isEmpty() || output.front() != QLatin1Char('?'); @@ -1198,14 +1192,13 @@ VcsCommand *SubversionPluginPrivate::createInitialCheckoutCommand(const QString const QString &localName, const QStringList &extraArgs) { - QStringList args; - args << QLatin1String("checkout"); - args << SubversionClient::addAuthenticationOptions(m_settings); - args << QLatin1String(Subversion::Constants::NON_INTERACTIVE_OPTION); - args << extraArgs << url << localName; + CommandLine args{m_settings.binaryPath.filePath()}; + args << "checkout"; + args << SubversionClient::AddAuthOptions(); + args << Subversion::Constants::NON_INTERACTIVE_OPTION << extraArgs << url << localName; auto command = VcsBaseClient::createVcsCommand(baseDirectory, m_client->processEnvironment()); - command->addJob({m_settings.binaryPath.filePath(), args}, -1); + command->addJob(args, -1); return command; } diff --git a/src/plugins/vcsbase/vcsbaseclient.cpp b/src/plugins/vcsbase/vcsbaseclient.cpp index 102c2ee2fb2..8493955cd15 100644 --- a/src/plugins/vcsbase/vcsbaseclient.cpp +++ b/src/plugins/vcsbase/vcsbaseclient.cpp @@ -390,7 +390,8 @@ void VcsBaseClient::diff(const FilePath &workingDir, const QStringList &files, void VcsBaseClient::log(const FilePath &workingDir, const QStringList &files, const QStringList &extraOptions, - bool enableAnnotationContextMenu) + bool enableAnnotationContextMenu, + const std::function &addAuthOptions) { const QString vcsCmdString = vcsCommandString(LogCommand); const Id kind = vcsEditorKind(LogCommand); @@ -409,19 +410,28 @@ void VcsBaseClient::log(const FilePath &workingDir, if (paramWidget) { paramWidget->setBaseArguments(extraOptions); // editor has been just created, createVcsEditor() didn't set a configuration widget yet - connect(paramWidget, &VcsBaseEditorConfig::commandExecutionRequested, this, - [=] { this->log(workingDir, files, extraOptions, enableAnnotationContextMenu); }); + connect(paramWidget, &VcsBaseEditorConfig::commandExecutionRequested, this, [=] { + this->log(workingDir, + files, + extraOptions, + enableAnnotationContextMenu, + addAuthOptions); + }); editor->setEditorConfig(paramWidget); } } - QStringList args = {vcsCmdString}; + CommandLine args{vcsBinary(), {vcsCmdString}}; + if (addAuthOptions) + addAuthOptions(args); if (paramWidget) args << paramWidget->arguments(); else args << extraOptions; args << files; - enqueueJob(createCommand(workingDir, editor), args); + VcsCommand *cmd = createCommand(workingDir, editor); + cmd->addJob(args, vcsTimeoutS()); + cmd->start(); } void VcsBaseClient::revertFile(const FilePath &workingDir, diff --git a/src/plugins/vcsbase/vcsbaseclient.h b/src/plugins/vcsbase/vcsbaseclient.h index 6eef0a7899e..804b690a7bc 100644 --- a/src/plugins/vcsbase/vcsbaseclient.h +++ b/src/plugins/vcsbase/vcsbaseclient.h @@ -147,7 +147,8 @@ public: virtual void log(const Utils::FilePath &workingDir, const QStringList &files = {}, const QStringList &extraOptions = {}, - bool enableAnnotationContextMenu = false); + bool enableAnnotationContextMenu = false, + const std::function &addAuthOptions = {}); virtual void status(const Utils::FilePath &workingDir, const QString &file = {}, const QStringList &extraOptions = {});