zlacker

[return to "Hk, a new Git hook manager"]
1. judofy+2b[view] [source] 2025-02-17 17:20:48
>>DrBenC+(OP)
> lefthook is written in go, hk is written in rust. This will make hk faster but the advanced parallelism logic in hk should make hk much faster. Because git hook managers are often limited not by their own logic but the speed of the commands they run, this should make hk significantly faster in real-world usage.

What a strange sentence. First Hk will be faster than Lefthook because it will be written in Rust[1], but then later on it says that it doesn't actually matter? But either way it will be faster because it has "advanced parallelism"?

Looking at the comparison to Lefthook it's not clear to me why this isn't a PR to Lefthook. It's already a well-established solution which is present in many package managers. Surely the distinction between "checks" and "fixes" would be possible to introduce there as well?

Do we yet another tool instead of working together on improving the existing ones?

[1]: Which also is not a given. Programs which allocate a lot can be faster in Go since the garbage collector only works on the live set of objects whereas Rust have to explicitly deallocate all memory. CLI tooling is actually kinda a sweet-spot of GCs: You don't want to spend time reclaiming memory until you reach a certain threshold of used memory. In scenarios where you use less than the threshold you end up spending zero cycles on deallocation. (And completely leaking all memory is bound to cause problem on bigger commands or smaller machines.)

◧◩
2. searea+mb[view] [source] 2025-02-17 17:22:06
>>judofy+2b
It makes sense. If you have 4 hooks, and you run them serially, it will be slower than if you ran them in parallel.
◧◩◪
3. rounce+fh[view] [source] 2025-02-17 17:58:37
>>searea+mb
That assumes the hooks themselves can be run in parallel. Without a way to describe dependencies between them there's big scope for race conditions.
◧◩◪◨
4. thayne+xH[view] [source] 2025-02-17 20:57:56
>>rounce+fh
Which is why it is best if you plan for parallelism from the beginning, so that your configuration has a straightforward way to indicate dependencies and making sure certain hooks aren't run in parallel with conflicting hooks
◧◩◪◨⬒
5. rounce+VS[view] [source] 2025-02-17 22:33:59
>>thayne+xH
The subject program doesn't seem to provide a way in which to specify the dependencies between hooks, hence they will just race each other assuming they are all fired off in parallel.
◧◩◪◨⬒⬓
6. jdxcod+r42[view] [source] 2025-02-18 11:50:45
>>rounce+VS
in fact I do believe I have a solution to this problem. I should have this fully implemented soon but right now it is not.

First, I intend to be able to define simple "dependencies", but IMO that's not the interesting part.

I am going to use rw mutexes on every file with staged changes. If 2 steps are running against disjoint files there is no problem. If 2 steps are running against "check" (not "fix" which edit files by convention), they can also run at the same time. The only scenario where blocking is necessary is when you have 2 "fix" or 1 "check" and 1 "fix" on an intersection of their files.

For that scenario there is going to be a setting that you can enable to run a steps "check" command first (only if this scenario is about to happen, if no files will be in contention it will simply run "fix"), and if "check" fails, then it will switch to "fix".

This is my current idea and in my head I think it would work. There are caveats, notably running "check" and then "fix" might be slower than just waiting and running "fix" once which is why it needs to be optional behavior. You also may not care about things stomping on each other (maybe the linters themselves have their own locking logic).

[go to top]