[sdk/dolphin-plugins] git: git: wait for git processes to finish so QProcess is not destroyed while running

Méven Car <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit df3b62db1521ab3685c2fd18ccabb71c0e1f5651 by Méven Car.
Committed on 23/07/2026 at 09:17.
Pushed by meven into branch 'master'.

git: wait for git processes to finish so QProcess is not destroyed while running

Several helpers started a git QProcess and read its output with a
while (waitForReadyRead()) loop, then let the QProcess go out of scope.
waitForReadyRead() returns false on stdout EOF, which can happen a moment
before the process actually terminates, so the QProcess was destroyed while
the child was still running and printed "QProcess: Destroyed while process is
still running." (and in checkout()/createTag() exitCode() was read before the
process had finished).

Wait for the process to finish after each read loop so it is reaped first.
This is most noticeable for localRepositoryRoot() and beginRetrieval(), which
run every time a folder is entered.

M  +9    -2    git/fileviewgitplugin.cpp
M  +1    -0    git/gitwrapper.cpp

https://invent.kde.org/sdk/dolphin-plugins/-/commit/df3b62db1521ab3685c2fd18ccabb71c0e1f5651

diff --git a/git/fileviewgitplugin.cpp b/git/fileviewgitplugin.cpp
index 4a5508b0..394b8e1e 100644
--- a/git/fileviewgitplugin.cpp
+++ b/git/fileviewgitplugin.cpp
@@ -128,8 +128,8 @@ QString FileViewGitPlugin::localRepositoryRoot(const QString &directory) const
     QProcess process;
     process.setWorkingDirectory(directory);
     process.start(QStringLiteral("git"), {QStringLiteral("rev-parse"), QStringLiteral("--show-toplevel")});
-    if (process.waitForReadyRead(100) && process.exitCode() == 0) {
-        return QString::fromUtf8(process.readAll().chopped(1));
+    if (process.waitForFinished() && process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0) {
+        return QString::fromUtf8(process.readAllStandardOutput().chopped(1));
     }
     return QString();
 }
@@ -178,6 +178,8 @@ bool FileViewGitPlugin::beginRetrieval(const QString &directory)
             dirBelowBaseDir = QString::fromLocal8Bit(buffer).trimmed(); // ends in "/" or is empty
         }
     }
+    // Reap the process before reusing it for the next command.
+    process.waitForFinished();
 
     m_versionInfoHash.clear();
 
@@ -265,6 +267,8 @@ bool FileViewGitPlugin::beginRetrieval(const QString &directory)
             }
         }
     }
+    // Reap the process so it is not destroyed while still running.
+    process.waitForFinished();
 
     const auto untracked = GitWrapper::instance()->listUntracked();
     for (auto &i : std::as_const(untracked)) {
@@ -652,6 +656,7 @@ void FileViewGitPlugin::checkout()
                 }
             }
         }
+        process.waitForFinished();
         if (process.exitCode() == 0 && process.exitStatus() == QProcess::NormalExit) {
             if (!completedMessage.isEmpty()) {
                 Q_EMIT operationCompletedMessage(completedMessage);
@@ -692,6 +697,7 @@ void FileViewGitPlugin::commit()
                 }
             }
         }
+        process.waitForFinished();
         if (!completedMessage.isEmpty()) {
             Q_EMIT operationCompletedMessage(completedMessage);
             Q_EMIT itemVersionsChanged();
@@ -724,6 +730,7 @@ void FileViewGitPlugin::createTag()
                 }
             }
         }
+        process.waitForFinished();
         if (process.exitCode() == 0 && process.exitStatus() == QProcess::NormalExit) {
             completedMessage = xi18nd("@info:status", "Successfully created tag '%1'", dialog.tagName());
             Q_EMIT operationCompletedMessage(completedMessage);
diff --git a/git/gitwrapper.cpp b/git/gitwrapper.cpp
index 71cd2f73..f048f0d9 100644
--- a/git/gitwrapper.cpp
+++ b/git/gitwrapper.cpp
@@ -103,6 +103,7 @@ void GitWrapper::remoteBranches(const QString &remote)
             }
         }
     }
+    process.waitForFinished();
 
     Q_EMIT foundRemoteBranches(remotes);
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.