aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/git/gitclient.cpp
diff options
context:
space:
mode:
authorJarek Kobus <[email protected]>2022-06-22 11:21:50 +0200
committerJarek Kobus <[email protected]>2022-06-28 17:29:50 +0000
commita1ad64a50b57be8997b2f3578e949e423df65b86 (patch)
tree43baa5ebb61e14018cccfbc0f5bd526bdc3e23b0 /src/plugins/git/gitclient.cpp
parent14965f5792af8916fca9e0ba4eba51298ed0b9a6 (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.cpp98
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) {