Improve Git monorepo performance with a file system monitor
github.blog
github.blog
Seams like quite a complex solution though. I guess some big company (Microsoft?) implemented it internally for their own use and later tried to move it to upstream git. I wonder if there was some pushback from git maintainers from having this functionality built-in.
Also why for Windows they use named pipes when in theory Windows also supports it? (https://devblogs.microsoft.com/commandline/af_unix-comes-to-...)
BTW, to the author of this article. It is very good. It was an interesting read. The are some small issues:
- "markdown" link didn't get converted to html: "[core.untrackedcache](https://git-scm.com/docs/git-config#Documentation/git-config...)"
- the link to "philosophy" of Scalar doesn't work: https://github.com/microsoft/git/blob/HEAD/contrib/scalar/do...
Named pipes are fine, the semantics are basically identical, and you can guarantee there is a separate namespace versus the filesystem (for AF_UNIX, \x00 prefixes work on Linux but not on macOS).
Are there any other git features with this limitation? Wild to me that we're here.
Thankfully the article covers the semi-longstanding "hooks" that existing (& very high performance) tools like Watchman (which are cross platform) can use.
Great in depth read. Good stuff! From the 2.37 release[1].
[1] https://github.blog/2022-06-27-highlights-from-git-2-37/ https://news.ycombinator.com/item?id=31898261 (34 points, 2 days ago, 7 comments)
Of course, in a large enough monorepo Linux performance would also suffer, but to a much lesser degree.
Also, conveniently, both Windows and macOS have an API for recursive directory watch, whereas Linux doesn't (in Vanilla kernel). Inotify can only watch the immediate directory you're observing + there's a pretty low default limit on the number of inotify descriptors that you're allowed to have on top of that
$ time git status
real 0m0.324s
user 0m0.197s
sys 0m0.425s
That's on a working tree with 314,708 files and no watchman.inotify has a number of other relevant limitations, like not being able to create recursive notifications or handle "move" operations. Implementation effort is going to be way higher for an inotify-based system, and of course that's made far worse by the numerous file systems in linux - I imagine any implementation would probably start first with ext4.
I suspect an ideal solution would be via ebpf, but I'm not sure.
Apparently an older implementation using inotify was dropped because inotify does not work recursively, so you would have to do an inotify call for all directories of the hierarchy which is obviously very inefficient. There are system wide limits in the number of directories you can listen to, and even if you increase the limit you would probably cause a lot of overhead.
Newer linuxes support the fanotify system call, which does allow recursive listening. They haven't implemented something using fanotify yet however.
https://lore.kernel.org/git/e1442a04-7c68-0a7a-6e95-304854ad...
https://man7.org/linux/man-pages/man7/fanotify.7.html
In the original fanotify API,
only a limited set of events was supported. In particular, there
was no support for create, delete, and move events. The support
for those events was added in Linux 5.1. (See inotify(7) for
details of an API that did notify those events pre Linux 5.1.)
https://www.phoronix.com/scan.php?page=news_item&px=Linux-5....And https://lore.kernel.org/git/87czs1d6uy.fsf@evledraar.gmail.c... to link to fanotify discussion on the git mailing list (as well as some flaming about the feature not being supported on linux).
I have tried Watchman, but setting it up is a pain. There are so many ways to use it. I also welcome running less Facebook code on my systems.
> It is currently available on macOS and Windows.
After all these years of Windows-only or MacOS-only software, you guys deserve this.
My 2c is that one of the unambiguously positive externalities of the tech mega-corp trend is all the great OSS we get as a by-product of their operations.
I mean, I don’t exactly love how iPhones get made, but I’m pretty stoked that clang kicks ass now.
Are there any recommendations or standardized tools for structuring monorepos for companies that don't have a dedicated dev tools team? Last I checked, lerna seemed to be the most common tool to support JS monorepos - is that still true? Is there a better tool for a primarily Typescript codebase (primarily React on the front end, Node on the backend, but also native mobile apps)?
The nice thing with this type of separation for us is being able to target CI/CD scripts to specific apps. Previously we were using targeted dev script logic to initiate the different app builds which just wasn't maintainable. This new approach this time around made for Electron deployments to be super simple, consistent, and repeatable.
All this was done by two team members on dev side.
Also incremental build support in Typescript itself has seen a lot of improvements in recent versions. It is useful to check if your monorepo can benefit from Typescript incremental builds.
[1]: https://support.microsoft.com/en-us/office/save-disk-space-w...
Unfortunately that approach was put in maintenance mode since it didn't seem like it would be supportable on macOS.
It supports neat stuff like partial clone which seems like a pretty big deal.
Git partial-clone looks almost perfect, except it only downloads and displays files explicitly added to the git sparse-checkout list. I want some "magic" vfs shenanigans that lets me view and browse the full repo exactly as if the full repo where checked out, but when I open a directory or file the contents are downloaded on-demand.
[0]: https://github.com/git/git/tree/master/contrib/scalar
[1]: https://github.com/microsoft/git/blob/vfs-2.37.0/Documentati...
[1]: https://docs.microsoft.com/en-us/windows/win32/projfs/projec...
[2]: https://docs.microsoft.com/en-us/windows/win32/cfapi/build-a...
the buffer projectile-files-errors says "warning: Empty last update token."
Maybe Perforce. Or didn't MS have their own in-house SCM as well?