Repository: godotengine/godot (language: cpp)

Issue:
.import / .uid file is not removed when original file is not in root directory and gets removed outside editor
### Tested versions

4.4 dev4
Likely earlier too.

### System information

Windows 10.0.19045 - Multi-window, 2 monitors - Vulkan (Forward+) - dedicated NVIDIA GeForce GTX 1060 (NVIDIA; 32.0.15.6603) - Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz (8 threads)

### Issue description

When you delete a file outside editor, Godot tries to delete corresponding .import/.uid file. However this only happens if the file is in the project's root directory. If it's in any subdirectory, the other file just stays there and you have to delete it manually.

### Steps to reproduce

1. Open project's root directory in OS' file manager
2. Delete icon.svg
3. Focus the editor
4. The engine will process FileSystem and automatically delete icon.svg.import.
5. Try again with icon.svg in a subfolder

### Minimal reproduction project (MRP)

N/A


Discussion / hints:
I am confused by a related question: 
Is it safe to copy one project's addons which contain some .uid files to another project? What if the uids are already exist in the target project?
Or do we need to add .uid into `.gitignore` file if we use a version control tool? Do we need to delete .uid files after we copy scripts from an old project into a new project?
Each generated .uid file is unique, so if you copy them between projects they will work as expected.
Thanks, I checked the code:
https://github.com/godotengine/godot/blob/cf038deb1033007167a05a4518a0e8b2dae5e93e/core/io/resource_uid.cpp#L88-L100

I can understand the newly generated uid won't be the same as existing uids in a project, but there are some chances that two projects generate the same uid, aren't there?

Imagine this situation:
Project A: `a.gd.uid` which content is `uid://4pmd34mck18a`, 
Project B: `b.gd.uid` which content is also `uid://4pmd34mck18a` ,
When copying `a.gd` and `a.gd.uid` into Project B, some error will occur.

In fact, for a long time, I have the same concern about copying files like `.tscn` from one project to another project because I fear that the resource ids in `.tscn` will accidentally be same as those in the target project. The newly introduced `.uid` file raised my concern again. 

I can't do much to `.tscn`, `.tres` files but I can add .uid into `.gitignore` especially for addons if I want to share them with others but I don't know if this is even necessary or a good idea. Do you have any suggestions?
> there are some chances that two projects generate the same uid, aren't there?

There are, but very very low. I think the editor can already deal with duplicate UIDs to some extent, but we can improve it. It's unlikely to be a problem though.

> I can add .uid into .gitignore especially for addons if I want to share them with others but I don't know if this is even necessary or a good idea.

It's not necessary, but it would work. Note however that scenes automatically refer to files by both path and UID, so if you don't provide script's UID and that script is referenced in a scene, you will get an error while loading. The editor is able to fix UID by checking the path, but the error (warning) is still being printed.

Fix patch:
diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp
index 42cd8632941d..6e76f06a3095 100644
--- a/editor/editor_file_system.cpp
+++ b/editor/editor_file_system.cpp
@@ -933,15 +933,16 @@ bool EditorFileSystem::_update_scan_actions() {
 				int idx = ia.dir->find_file_index(ia.file);
 				ERR_CONTINUE(idx == -1);
 
-				String class_name = ia.dir->files[idx]->class_info.name;
+				const String file_path = ia.dir->get_file_path(idx);
+				const String class_name = ia.dir->files[idx]->class_info.name;
 				if (ClassDB::is_parent_class(ia.dir->files[idx]->type, SNAME("Script"))) {
-					_queue_update_script_class(ia.dir->get_file_path(idx), ScriptClassInfoUpdate());
+					_queue_update_script_class(file_path, ScriptClassInfoUpdate());
 				}
 				if (ia.dir->files[idx]->type == SNAME("PackedScene")) {
-					_queue_update_scene_groups(ia.dir->get_file_path(idx));
+					_queue_update_scene_groups(file_path);
 				}
 
-				_delete_internal_files(ia.dir->files[idx]->file);
+				_delete_internal_files(file_path);
 				memdelete(ia.dir->files[idx]);
 				ia.dir->files.remove_at(idx);
 


Test patch: