Race condition storing git config (detects presence of command-line Git)
Dev Home version
No response
Windows build number
No response
Other software
No response
Steps to reproduce the bug
Running with a debugger attached, I can see multiple nullreference exceptions hitting in the helpers package, trying to obtain the local repository.
I've narrowed this down somewhat, and it seems we have some contention on the configuration file storing the Git config, resulting in System.IO.IOException being thrown in the Git extension when attempting to write the config. This ends up causing GetRepository() to fail, causing SourceControlProvider.GetProvider to return null, and SourceControlProvider.GetProperties to throw an ArgumentException.
(Also noticed while I was there, property filtering was recently applied to RootFolderPropertyProvider.GetProperties but not SourceControlProvider.GetProperties. Looks like an oversight but needs to be fixed as RootFolderPropertyProvider should eventually go away.
Expected result
The very first call to GetRepository and GetProperties should succeed, with the Git extension being able to handle multiple inbound threads trying to detect git simultaneously.
Actual result
The first several calls to GetRepository and GetProperties fail. After a few seconds, when the contention on the git extension's config file settle down, the calls begin succeeding.
The Git extension likely needs some sort of singleton/global locking in the GitDetect functionality.
Included System Information
No response
Included Extensions Information
No response
As part of this fix, we should consider whether or not we want this sort of failure to propagate out to File Explorer.
Seems that a null check in the Helpers package to the result of GetProvider is warranted at least. That way we can either translate into a more useful error on subsequent calls to GetProperties, or silently return an empty dictionary.
Similarly, we should consider whether SourceControlProvider.GetProperties should null check the result of GetLocalProvider, and possibly return a different error type, or return an empty propertyset.