zlacker

Hk, a new Git hook manager

submitted by DrBenC+(OP) on 2025-02-17 16:23:30 | 96 points 82 comments
[view article] [source] [go to bottom]

NOTE: showing posts with links only show all posts
◧◩◪
5. whilen+C8[view] [source] [discussion] 2025-02-17 17:08:29
>>regula+06
While I understand your valid criticism with the overhead of using an interpreted language here, I must point out that using multiple versions in the same repository is quite an antipattern that comes with various complications. Maybe you should consider switching to a version manager of[0] your[1] choice[2].

[0]: https://github.com/jdx/mise

[1]: https://github.com/asdf-vm/asdf

[2]: https://github.com/version-fox/vfox

10. autarc+mf[view] [source] 2025-02-17 17:47:19
>>DrBenC+(OP)
I wrote a tool in this space as well, precious (https://github.com/houseabsolute/precious). It's odd to me that these tools are often talked about with such a focus on Git hooks. Yes, that is definitely one use case, but I also want to run this sort of thing in CI to check PRs, and I _also_ want to run it locally to apply _pretty-printing_ to new code, rather than just having it check the code that I wrote.

I think hk does do all those things, but it's a bit obscured by the focus on Git hooks in the docs. But the docs are also still in a super early state, so maybe that will be fleshed out more in the future.

◧◩◪
18. goku12+ni[view] [source] [discussion] 2025-02-17 18:05:26
>>cowsan+Fd
Committing git hooks to the repo is possible. These are the 2 ways in which they're commonly handled:

1. Link the scripts from the worktree to the .git/hooks directory - perhaps using a bootstrap script.

Ref: https://codeinthehole.com/tips/tips-for-using-a-git-pre-comm...

2. Declare the directory in the worktree to be the local git hooks directory.

Ref: https://knpw.rs/blog/direnv-git-hooks

◧◩
25. goku12+sl[view] [source] [discussion] 2025-02-17 18:28:27
>>pimlot+T7
While your concern is valid, I recommend learning about git hooks from their canonical source rather than from the documentation of any hook manager. Hooks are features of Git itself. Hook managers are an after-thought. Meanwhile, this tool and its docs also appear to be works in progress. I use pre-commit (a python program, not the hook itself) as a hook manager. But nothing beats the git book and docs. Here are some links:

1. https://git-scm.com/docs/githooks

2. https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks

Here is another site dedicated to git-hooks. You'll find some good examples and resources there:

https://githooks.com/

◧◩◪◨
30. judofy+uo[view] [source] [discussion] 2025-02-17 18:48:34
>>jayd16+3m
> Could the Go solution add parallelism, sure. Did they? Not yet.

They did: Lefthook lets you define a "group" where you can specify that every command should be done in parallel: https://lefthook.dev/configuration/group.html. In addition, it's possible to configure the whole hook to run in parallel through another property: https://lefthook.dev/configuration/parallel.html.

I'm assuming that Hk's innovation here is that it's a bit smarter with what it runs in parallel. Maybe it uses the globs to automatically run commands in parallel which targets different files?

> "Rust is faster" as an off the cuff comment that should have been left out seeing it has triggered some folks to hyper focus on that point.

It's not a a hyper focus: This was the first reason (out of only three) that Hk itself presented as a reason to use it over Lefthook. So yes, I agree: It should have been left out if the intention wasn't for people to focus on it. Put it somewhere in a footnote if it's not so relevant.

35. azeira+7u[view] [source] 2025-02-17 19:22:30
>>DrBenC+(OP)
I don't know if this is well-known or not, but nix flakes are _amazing_ for managing and configuring cross-platform hooks.

In less than 40 lines of nix, most of which is boilerplate, you have fully cross-platform automatically installed and declaratively managed hooks, as part of your repo.

Need to run it in CI too? Well, no problem! Nix runs equally well in CI as it does locally.

Check this flake for example:

https://github.com/Azeirah/remarks/blob/main/flake.nix

See line 62 in the shell script.

This flake:

1. Manages ALL my dev env dependencies. Including even the specific version of bash that the script is running on, also the specific python dependencies down to the bit.

2. It's (posix-compliant) cross-platform, so it runs on MacOS, WSL, Linux, NixOS, ARM, x86 etc. Also docker.

3. It uses no specialized tools other than Nix, which is now a 20 year old Linux project which is quickly gaining even more traction. Nix is a programming language for reproducible, reliable and declarative dependency management (think docker but with a pure and functional programming language, rather than a recipe with installation instructions)

4. It also creates binaries as well as docker images from the binary. The docker image is like 2 lines of extra code.

Highly highly recommended. It's a bit difficult to wrap your head around initially, but holy damn if all dependency management problems don't just magically disappear forever once you learn Nix.

And I mean ALL of them. Whether it's Linux packages, docker containers, development environments, CI, virtual machines, containers, compilers, C headers from a 1970 Bell Labs project. No matter the architecture or OS (except Windows! :D).

Oh, did I mention it has a lockfile? So you can rollback or upgrade piecewise? Whenever you want?

It's like a programmable version of the superset of npm, cargo, pip, apt, brew, composer, gem, make, cmake, docker, git, Jenkins and even Linux itself (if you dare go the way of NixOS)

◧◩
43. hv42+wB[view] [source] [discussion] 2025-02-17 20:10:07
>>timhh+tm
You will be able to use mise to set up any tools required for the linters. See https://mise.jdx.dev/dev-tools/
◧◩
46. Arcuru+aD[view] [source] [discussion] 2025-02-17 20:22:22
>>azeira+7u
And since this thread is talking about git hooks, there's also this project for managing git hooks inside Nix https://github.com/cachix/git-hooks.nix
◧◩
47. srid+DD[view] [source] [discussion] 2025-02-17 20:25:55
>>autarc+mf
I use https://github.com/cachix/git-hooks.nix which provides all of it:

- Pre-commit hook setup

- Run locally anytime (`pre-commit run -a`)

- Check in CI (as Nix flake check)

Example repo: https://github.com/srid/haskell-template

The pre-commit configuration: https://github.com/srid/haskell-template/blob/master/nix/mod...

◧◩
54. jdxcod+QI[view] [source] [discussion] 2025-02-17 21:10:20
>>judofy+2b
This project is brand new. I've only spent 3 days on it and this doc I half finished today. That said, I just did some benchmarks and it certainly is much faster than its peers. 4.6x faster than lefthook and 6.1x faster than pre-commit (in the best case).

I'll put these benchmarks on that page in different scenarios.

Update: https://github.com/jdx/hk/blob/main/docs/public/benchmark.pn...

As I said in the doc I think real-world performance in a large codebase will show that hk is even faster still—though that will depend on the project in question. It's really just a matter of providing the right levers in the right places and having good defaults.

Despite what everyone here says: yeah, just doing CLIs in Rust will be faster than Go and for CLIs like this milliseconds matter.

◧◩◪
64. judofy+QV[view] [source] [discussion] 2025-02-17 23:06:23
>>jdxcod+QI
I'm sorry, but it's very hard to take this project seriously: You originally claimed that it was 1.5x faster than Lefthook, but then you removed the parallel support from the Lefthook (https://github.com/jdx/hk/commit/ad473331db2866f6574555ac4b0...) and changed your claim to "4.6x faster". These numbers are also just for some a specific workload (Prettier, ActionLint, pkl eval, ripgrep, cargo fmt) on this specific repo. For now the "4.6x number" is heavily based on the fact you have five jobs and Hk runs commands in parallel by default while you let Lefthook run them sequentially. I bet you can turn that number into 10x if you just add a few more jobs!

> Despite what everyone here says: yeah, just doing CLIs in Rust will be faster than Go and for CLIs like this milliseconds matter.

You've shown nothing to suggest that this is true. On my computer "lefthook --help" is exactly as fast as "hk --help". There's also many other differences between these tools. YAML vs Pkl is one difference. Another one is that Lefthook shells out to "git" to determine the list of staged files, while Hk uses libgit2. Which of these are faster? I'm not sure! It might even depend on repository size and/or other details. And as we all agree: In practice the parallelism strategy will matter the most.

> As I said in the doc I think real-world performance in a large codebase will show that hk is even faster still

I'm absolutely sure that you will be able to tweak hk to become the "fastest" pre-commit runner in your designated category. I'm also pretty sure that similar optimizations will apply quite easily to Lefthook. They're after all doing pretty much the same thing.

◧◩◪◨
65. jdxcod+SW[view] [source] [discussion] 2025-02-17 23:16:35
>>judofy+QV
of course I selected the best benchmark. Once I ran a benchmark that had higher numbers I edited my response—I was up front about that. So far 0 benchmarks show that lefthook is faster and I doubt there could be one knowing how both of them work. I'm not just creating scenarios where I know hk will outperform but I'll certainly highlight the best one.

> then you removed the parallel support

that was not intentional. I fixed that, but it didn't change the results that much:

https://github.com/jdx/hk/commit/dfe1fc1724b8f6c43b184dc98ac...

In any case, I don't know why anyone would take such a new project "seriously". I certainly don't.

◧◩◪
79. hv42+TW2[view] [source] [discussion] 2025-02-18 16:45:24
>>DrBenC+il2
One of the goal of hk is to be used with mise (https://mise.jdx.dev/dev-tools/)

mise supports an experimental bootstrapping feature: it can download itself and install the tools required for the project.

See https://mise.jdx.dev/cli/generate/bootstrap.html and https://mise.jdx.dev/continuous-integration.html#bootstrappi...

[go to top]