This is the issue that motivated the Metro 0.73.7 hotfix release - filing it here from a Discord discussion for posterity. Thanks @tido64 for the initial report.
The find crawler (which Metro runs as a first fallback to Watchman) runs a command like spawn('find', ['-iname', '*.js']) and then parses stdout.
We try a dummy execution of that command against a known directory inside node_modules to verify that the (non-POSIX, extended) expression syntax is supported, before running the real thing against the project root. If it fails, we fall back to an fs.opendir recursive walk.
On Windows, the find check normally fails because the FIND command is nothing like GNU find, so we fall back as designed.
On Git Bash (MinGW), which has a GNU find , it turns out that the *.js expression gets glob expanded to all of the JavaScript that happens to be in the CWD. So if there are two or more JS files in the directory we end up trying find <root> ( -iname foo.js bar.js ), which is invalid - the capability check fails (by accident) and we fall back (hooray). That used to happen up to Metro 0.72.
Since 9df188f where I moved watchman.js to watchman/index.js, there was exactly one remaining file - node.js - left in the relevant directory, and the find check started passing because find <root> ( -iname node.js ) is a valid expression. The same bogus expansion then causes the real command to return no results, and Metro gets an empty file map.
This is the issue that motivated the Metro 0.73.7 hotfix release - filing it here from a Discord discussion for posterity. Thanks @tido64 for the initial report.