diff options
author | Jarek Kobus <[email protected]> | 2022-06-22 11:21:50 +0200 |
---|---|---|
committer | Jarek Kobus <[email protected]> | 2022-06-28 17:29:50 +0000 |
commit | a1ad64a50b57be8997b2f3578e949e423df65b86 (patch) | |
tree | 43baa5ebb61e14018cccfbc0f5bd526bdc3e23b0 /src/plugins/git/gitclient.cpp | |
parent | 14965f5792af8916fca9e0ba4eba51298ed0b9a6 (diff) |
GitClient: Don't call blocking waitForStarted()
Connect to done() signal in order to detect the start
failure and try to start a gitk from different path.
All trials of starting gitk are done sequentially
and non-blocking.
Give process a parent in order to avoid process leak
on shutdown.
Change-Id: I1d74bfeaca23d38643f3d2f262428732314aefe4
Reviewed-by: <[email protected]>
Reviewed-by: hjk <[email protected]>
Reviewed-by: Orgad Shaneh <[email protected]>
Diffstat (limited to 'src/plugins/git/gitclient.cpp')
-rw-r--r-- | src/plugins/git/gitclient.cpp | 98 |
1 files changed, 59 insertions, 39 deletions
diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 1a2b211156b..80623839459 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -2574,31 +2574,7 @@ QStringList GitClient::synchronousRepositoryBranches(const QString &repositoryUR void GitClient::launchGitK(const FilePath &workingDirectory, const QString &fileName) const { - FilePath foundBinDir = vcsBinary().parentDir(); - Environment env = processEnvironment(); - if (tryLauchingGitK(env, workingDirectory, fileName, foundBinDir)) - return; - - VcsOutputWindow::appendSilently(msgCannotLaunch(foundBinDir / "gitk")); - - if (foundBinDir.fileName() == "bin") { - foundBinDir = foundBinDir.parentDir(); - const QString binDirName = foundBinDir.fileName(); - if (binDirName == "usr" || binDirName.startsWith("mingw")) - foundBinDir = foundBinDir.parentDir(); - if (tryLauchingGitK(env, workingDirectory, fileName, foundBinDir / "cmd")) - return; - - VcsOutputWindow::appendSilently(msgCannotLaunch(foundBinDir / "cmd/gitk")); - } - - Environment sysEnv = Environment::systemEnvironment(); - const FilePath exec = sysEnv.searchInPath("gitk"); - - if (!exec.isEmpty() && tryLauchingGitK(env, workingDirectory, fileName, exec.parentDir())) - return; - - VcsOutputWindow::appendError(msgCannotLaunch("gitk")); + tryLaunchingGitK(processEnvironment(), workingDirectory, fileName); } void GitClient::launchRepositoryBrowser(const FilePath &workingDirectory) const @@ -2608,16 +2584,35 @@ void GitClient::launchRepositoryBrowser(const FilePath &workingDirectory) const QtcProcess::startDetached({repBrowserBinary, {workingDirectory.toString()}}, workingDirectory); } -bool GitClient::tryLauchingGitK(const Environment &env, - const FilePath &workingDirectory, - const QString &fileName, - const FilePath &gitBinDirectory) const +static FilePath gitBinDir(const GitClient::GitKLaunchTrial trial, const FilePath &parentDir) { + if (trial == GitClient::Bin) + return parentDir; + if (trial == GitClient::ParentOfBin) { + QTC_CHECK(parentDir.fileName() == "bin"); + FilePath foundBinDir = parentDir.parentDir(); + const QString binDirName = foundBinDir.fileName(); + if (binDirName == "usr" || binDirName.startsWith("mingw")) + foundBinDir = foundBinDir.parentDir(); + return foundBinDir / "cmd"; + } + if (trial == GitClient::SystemPath) + return Environment::systemEnvironment().searchInPath("gitk").parentDir(); + QTC_CHECK(false); + return FilePath(); +} + +void GitClient::tryLaunchingGitK(const Environment &env, + const FilePath &workingDirectory, + const QString &fileName, + GitClient::GitKLaunchTrial trial) const +{ + const FilePath gitBinDirectory = gitBinDir(trial, vcsBinary().parentDir()); FilePath binary = gitBinDirectory.pathAppended("gitk").withExecutableSuffix(); QStringList arguments; if (HostOsInfo::isWindowsHost()) { // If git/bin is in path, use 'wish' shell to run. Otherwise (git/cmd), directly run gitk - FilePath wish = gitBinDirectory.pathAppended("wish").withExecutableSuffix(); + const FilePath wish = gitBinDirectory.pathAppended("wish").withExecutableSuffix(); if (wish.withExecutableSuffix().exists()) { arguments << binary.toString(); binary = wish; @@ -2629,25 +2624,50 @@ bool GitClient::tryLauchingGitK(const Environment &env, if (!fileName.isEmpty()) arguments << "--" << fileName; VcsOutputWindow::appendCommand(workingDirectory, {binary, arguments}); + // This should always use QtcProcess::startDetached (as not to kill // the child), but that does not have an environment parameter. - bool success = false; if (!settings().path.value().isEmpty()) { - auto process = new QtcProcess; + auto process = new QtcProcess(const_cast<GitClient*>(this)); process->setWorkingDirectory(workingDirectory); process->setEnvironment(env); process->setCommand({binary, arguments}); + connect(process, &QtcProcess::done, this, [=] { + if (process->result() == ProcessResult::StartFailed) + handleGitKFailedToStart(env, workingDirectory, fileName, trial, gitBinDirectory); + process->deleteLater(); + }); process->start(); - success = process->waitForStarted(); - if (success) - connect(process, &QtcProcess::finished, process, &QObject::deleteLater); - else - delete process; } else { - success = QtcProcess::startDetached({binary, arguments}, workingDirectory); + if (!QtcProcess::startDetached({binary, arguments}, workingDirectory)) + handleGitKFailedToStart(env, workingDirectory, fileName, trial, gitBinDirectory); } +} - return success; +void GitClient::handleGitKFailedToStart(const Environment &env, + const FilePath &workingDirectory, + const QString &fileName, + const GitClient::GitKLaunchTrial oldTrial, + const FilePath &oldGitBinDir) const +{ + QTC_ASSERT(oldTrial != None, return); + VcsOutputWindow::appendSilently(msgCannotLaunch(oldGitBinDir / "gitk")); + + GitKLaunchTrial nextTrial = None; + + if (oldTrial == Bin && vcsBinary().parentDir().fileName() == "bin") { + nextTrial = ParentOfBin; + } else if (oldTrial != SystemPath + && !Environment::systemEnvironment().searchInPath("gitk").isEmpty()) { + nextTrial = SystemPath; + } + + if (nextTrial == None) { + VcsOutputWindow::appendError(msgCannotLaunch("gitk")); + return; + } + + tryLaunchingGitK(env, workingDirectory, fileName, nextTrial); } bool GitClient::launchGitGui(const FilePath &workingDirectory) { |