Commit c7b8e797 authored by Milian Wolff's avatar Milian Wolff

Delay handling of KDirWatch signals

This is a workaround for bug 404184, where KDirWatch only emits
a 'deleted' signal during a 'git stash' workflow, which never
gets paired by a 'created' signal, even though the file actually
exists before and after the 'git stash' operation.

By delaying the handling of the KDirWatch signals, we won't fall
into the trap of removing a file even though it actually exists.
Since it doesn't really matter how fast we react on such events,
it's in my opinion fine to delay it for a full second. Having a
correct state is much more important than having any state fast.

Without this patch, KDevelop frequently forgets about files from large
projects I work on after a `git stash`. This then fubars the C++
support completely, since it cannot find any include paths and
defines anymore.
parent 8933d890
......@@ -27,6 +27,7 @@
#include <QHashIterator>
#include <QFileInfo>
#include <QApplication>
#include <QTimer>
#include <QElapsedTimer>
......@@ -255,6 +256,10 @@ void AbstractFileManagerPluginPrivate::created(const QString& path_)
qCDebug(FILEMANAGER) << "created:" << path_;
QFileInfo info(path_);
if (!info.exists()) {
// we delay handling of the signal, so maybe the path actually got removed again
///FIXME: share memory with parent
const Path path(path_);
......@@ -310,7 +315,7 @@ void AbstractFileManagerPluginPrivate::created(const QString& path_)
void AbstractFileManagerPluginPrivate::deleted(const QString& path_)
if ( QFile::exists(path_) ) {
// stopDirScan...
// we delay handling of the signal, so maybe the path actually exists again
// ensure that the path is not inside a stopped folder
......@@ -470,10 +475,24 @@ ProjectFolderItem *AbstractFileManagerPlugin::import( IProject *project )
auto watcher = new KDirWatch( project );
// set up the signal handling
// NOTE: We delay handling of the creation/deletion events here by one second to prevent
// useless or even outright wrong handling of events during comming git workflows.
// I.e. sometimes we used to get a 'delete' event during a rebase which was never
// followed up by a 'created' signal, even though the file actually exists after
// the rebase.
// see also:
connect(watcher, &KDirWatch::created,
this, [&] (const QString& path_) { d->created(path_); });
this, [&] (const QString& path) {
QTimer::singleShot(1000, this, [this, path]() {
connect(watcher, &KDirWatch::deleted,
this, [&] (const QString& path_) { d->deleted(path_); });
this, [&] (const QString& path) {
QTimer::singleShot(1000, this, [this, path]() {
watcher->addDir(project->path().toLocalFile(), KDirWatch::WatchSubDirs | KDirWatch:: WatchFiles );
d->m_watchers[project] = watcher;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment