X Tutup
Skip to content

Improve determinism of UIDs#111858

Merged
akien-mga merged 1 commit intogodotengine:masterfrom
KoBeWi:IcOn.SvG
Jan 6, 2026
Merged

Improve determinism of UIDs#111858
akien-mga merged 1 commit intogodotengine:masterfrom
KoBeWi:IcOn.SvG

Conversation

@KoBeWi
Copy link
Member

@KoBeWi KoBeWi commented Oct 20, 2025

This makes path-based UID generation case-insensitive, which improves consistency on case-insensitive systems. For example if 2 people generate UID for a file, but the file has different casing on each side (just Windows things), the UID will be the same.

Also fixes UID not being deterministic when duplicating files (regression (?) from #106763).

@KoBeWi KoBeWi added this to the 4.6 milestone Oct 20, 2025
@KoBeWi KoBeWi requested a review from a team October 20, 2025 21:50
@KoBeWi KoBeWi requested a review from a team as a code owner October 20, 2025 21:50
@KoBeWi KoBeWi added enhancement topic:core cherrypick:4.5 Considered for cherry-picking into a future 4.5.x release labels Oct 20, 2025
@AThousandShips
Copy link
Member

This feels unsafe, this will make res://foo/bar.gd and res://Foo/bar.gd have the same UID if the files are identical in content, that might make sense on case-insensitive filesystems but not in general

I'm not sure this "fixes" anything and just helps in cases where users violate best practices as documented etc.

@KoBeWi
Copy link
Member Author

KoBeWi commented Oct 20, 2025

This feels unsafe, this will make res://foo/bar.gd and res://Foo/bar.gd have the same UID if the files are identical in content, that might make sense on case-insensitive filesystems but not in general

Do people keep multiple files where only casing is different? Yes, this can happen, it sounds unlikely, even if it's technically allowed in case-sensitive filesystems.

Either way, the UID system is able to deal with collisions, so no duplicate UID will be created.

@AThousandShips
Copy link
Member

I'd say it's about as likely or as reasonable as mixing casing across platforms/users in a shared project

@coppolaemilio
Copy link
Member

@AThousandShips this is addressing a report Godot users that are making games are having, the having two files: res://foo/bar.gd and res://Foo/bar.gd is a completely hypothetical you are creating, so I don't think it is a good argument against it

@AThousandShips
Copy link
Member

I didn't refute it happening, but the fact remains that the error comes from breaking best practices, which I think should at least be considered hence bringing it up

@coppolaemilio
Copy link
Member

unfortunately, windows will some times make it seem like you renamed the file but you actually didn't, so users think they are submitting files with the correct casing and it is not how they are stored internally. You can of course notice this in GitHub before pushing a change, but an artist working on a game might not :(

@AThousandShips
Copy link
Member

That casing difference will cause other bugs though and issues with git, hence not best practices

But if the UID system handles conflicts then I guess it'd be safe to account for this incorrect usage, and hopefully things won't be more confusing for such users more if the UID system is more lenient

(Also, no need to tag when I'm right in the conversation, it just sounds like you're calling me out rather than just bringing to my attention)

@coppolaemilio
Copy link
Member

sorry for the tag, rocketchat ptsd from people not getting notified 😅

@AThousandShips
Copy link
Member

That is very relatable! The internet is a weird place with the extremes of Facebook with the worst tags, and RC of never getting the tags you're actually interested in

AThousandShips
AThousandShips previously approved these changes Oct 21, 2025
Copy link
Member

@AThousandShips AThousandShips left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can safely go ahead with this, but I think it's only a band-aid for a more serious problem of the editor not helping users to follow proper best practices, I'd say a more proper solution to prevent these issues would involve:

  • Warning, or even throwing an error, when renaming a file just changing the casing on a case-insensitive OS, something like "cannot rename file on a case-insensitive system, file will not be moved", alternatively adding some system on these OSes to move a file properly by moving to a temporary and then moving back Realized this has actually been fixed already
  • Warning on case-sensitive systems when renaming in the same way, saying that "these changes will have no effect when running on a case-insensitive operating system" or similar to warn that renaming them and updating VCS won't work on those OSes and will be confusing
  • More proactive detection in the editor for case errors, like in load("res://foo/bar.gd) if there is a file res://Foo/bar.gd, not just when running but as a warning in the editor

Edit: Opened a proposal for usability improvements with respect to casing

@AThousandShips AThousandShips dismissed their stale review October 21, 2025 14:09

Retracting approval until this has been confirmed to fix existing bugs, as opposed to hypothetical issues

@AThousandShips
Copy link
Member

Just to confirm: this does not cause any already assigned UIDs to be changed, i.e. for any files with .import or .uid files or for any .(t)res or .(t)scn files?

@KoBeWi
Copy link
Member Author

KoBeWi commented Oct 22, 2025

No, it's only for new UIDs.

@Mickeon

This comment was marked as resolved.

Copy link
Member

@Calinou Calinou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally on Linux (case-sensitive btrfs filesystem), it doesn't seem to work on my end:

$ cat touch.gd.uid TOUCH.gd.uid 
uid://bxr365upoga6i
uid://b320arqlsxif0

Both files have the same content:

extends CanvasLayer


func _ready() -> void:
	hide()
	if DisplayServer.is_touchscreen_available():
		show()

I've removed both .uid files beforehand to force them to be regenerated.

@coppolaemilio
Copy link
Member

Tested locally on Linux (case-sensitive btrfs filesystem), it doesn't seem to work on my end:

I believe that is intended? to test this you would have to generate one, and then remove it and try with the other one. Kobewi said that there is already a failsafe to generate a new code if the current one exists

@KoBeWi
Copy link
Member Author

KoBeWi commented Oct 28, 2025

Yes, you can test it like this:

  • Create icon.svg
  • Delete it
  • Create ICON.svg (or any different casing variation)

The UID should be the same for both files.

@Calinou
Copy link
Member

Calinou commented Oct 28, 2025

Yes, you can test it like this:

* Create icon.svg

* Delete it

* Create ICON.svg (or any different casing variation)

The UID should be the same for both files.

That makes sense. I've tested it again following these steps, and it works as expected.

Copy link
Member

@bruvzg bruvzg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. Cases with two files that are only different in the name case are non-portable, and should be avoided regardless of this change.

Copy link
Member

@akien-mga akien-mga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this makes sense, this is a common source of issue for cross-platform teams that leads to UID regeneration churn and diff noise.

@akien-mga akien-mga merged commit 5acd0c0 into godotengine:master Jan 6, 2026
20 checks passed
@akien-mga
Copy link
Member

Thanks!

@KoBeWi KoBeWi deleted the IcOn.SvG branch January 6, 2026 10:35
@gnat
Copy link

gnat commented Jan 8, 2026

For the record, another scenario where this PR is good: Programs which switch the case of extensions between lower or upper case (ex: .png vs .PNG, .psd vs .PSD).

@akien-mga
Copy link
Member

Cherry-picked for 4.5.2.

@akien-mga akien-mga removed the cherrypick:4.5 Considered for cherry-picking into a future 4.5.x release label Jan 8, 2026
rivie13 pushed a commit to rivie13/Phoenix-Agentic-Engine that referenced this pull request Feb 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants

X Tutup