6 ms·
Hk, a new Git hook manager
- righthand 2y agoGit hooks are like make files for me. Copy/paste that `git staged files` command and then add your linter commands (in .githooks/pre-commit file). Add `set -e`. Set package manager post-install hook to config git to the `.githooks` dir. Sadly I think git hook managers remove the simplicity of the whole design. Understandably since no one reads manuals anymore and projects don’t mind tacking on yet another module/plugin, however easy.
- deleted 2y ago[deleted]
- regularfry 2y agoI can get behind a hook manager that's a single binary. Where I have an issue is with (for instance) python hook managers where you now need to have python interpreter management that's aware of both the python app you're working on, and the tooling which might have a non-intersecting version requirement.
- whilenot-dev 2y agoWhile 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 https://github.com/jdx/mise [1]: https://github.com/asdf-vm/asdf https://github.com/asdf-vm/asdf [2]: https://github.com/version-fox/vfox https://github.com/version-fox/vfox
- regularfry 2y agoYou have misunderstood my criticism. I don't care in the slightest about the interpreter overhead. I care that I am forced into needing multiple versions in the same repository by having one version required by (for instance) a hook manager, and a different version required by the project itself. I am already using a version manager; it doesn't solve that problem.
- cowsandmilk 2y agoThe big difference with Makefiles is that git hooks can’t be committed to the repo. Hook managers allow hooks to be shared and updated across a team.
- goku12 2y agoCommitting 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-commit-hook/ 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 https://knpw.rs/blog/direnv-git-hooks
- globnomulous 2y agoSo do dev-environment start-up scripts, which in my experience are always simpler, clearer, and more maintainable than these managers. Just put your hook logic in a script and copy it to the git hooks folder on startup as necessary -- and then, voila, you've avoided the nonsense of some well-intentioned package whose author thinks Rust in git hooks is a selling point rather than a head scratcher.
- what 2y agoHooks shouldn’t be shared and updated across a team. Don’t force your workflow on others. Which is exactly why you can’t or shouldn’t commit them.
- goku12 2y agoWhat is the technical justification behind such as statement? Sharing hooks across the team doesn't equate to forcing a workflow on them. Each developer must manually activate the hooks in some manner in all the cases I've seen. Otherwise, they work as usual without the hooks and without interfering in the workflow in any manner. As a corollary, the hook conditions are enforced in the CI (since it can't be enforced in the developer's system). Git hooks are instead offered as a convenience function to help the developers catch mistakes early and often, before it hits the CI.
- warp 2y ago100%, I was using husky because we were using it at work. But it turns out for my use-case all I needed was this in my package.json: "scripts": { "postinstall": "git config --local core.hooksPath etc/hooks" },
- rav 2y agoOoh, core.hooksPath is quite nifty. I usually use something like ln -sf ../../scripts/git-pre-commit-hook .git/hooks/pre-commit which simply adds a pre-commit symlink to a script in the repo's scripts/ dir. But hooksPath seems better.
- Klonoar 2y agoSometimes I wonder if the death of blogging - which in turn killed a lot of showing people how to use a tool where they’d otherwise skip the manual - means we entered a world where people jump immediately to building a tool for an otherwise simple concept.
- Chilinot 2y agoI like Rust as much as the next guy, but statements like this makes me roll my eyes: > hk is written in rust, pre-commit is written in python. hk will be much faster. I have no idea how fast hk or pre-commit is, i have never used them. What matters to speed is the algorithms used and their complexities. If you implement a shitty algorithm with exponential complexity in Rust it's going to be slower than a linear complexity algorithm in python.
- deleted 2y ago[deleted]
- jitl 2y agoThis isn't true when it comes to CLI tools, where fixed costs and warm-up time can easily dominate over algorithmic complexity, especially comparing a scripting language to an ahead-of-time language. Without careful construction, a tool written in python with whatever O(log(n)) time complexity may still be booting up by the time a Rust tool finishes the job in O(n^2) time: frequently n is actually pretty small outside whole-repo builds, and the cost of interpreter is high especially with accompanying tooling -- python3 itself will run `print("hello")` on my machine in 40ms, but when wrapped in pyenv (which I think is typical?) it takes 400ms. The same goes for node/npx and ruby/bundle. Compare to an ahead-of-time compiled binary from go, which can boot and print hello in 3ms on my machine -- it has between 10x to 100x the wallclock budget the python program just spends booting up.
- trallnag 2y agoThese days I'd say tools pipx (and now also uv) are far more common than pyenv for tool management
- pimlottc 2y agoI appreciate the comparison to the leading existing tools, but it also assume a familiarity with them. This doc could also use a basic introduction for people who are new to this area and don't already use a hook manager. Examples of hooks, what the benefit is, etc.
- goku12 2y agoWhile 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 https://git-scm.com/docs/githooks 2. https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks 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/ https://githooks.com/
- judofyr 2y ago> 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.)
- searealist 2y agoIt makes sense. If you have 4 hooks, and you run them serially, it will be slower than if you ran them in parallel.
- vlovich123 2y agoI say this as a huge fan of Rust, Rust adds almost nothing to this kind of parallelism.
- searealist 2y agoIt doesn't claim that. It claims: 1) Rust is fast, so that helps some. 2) They run hooks in parallel, and that helps a lot.
- autarch 2y agoI wrote a tool in this space as well, precious (https://github.com/houseabsolute/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.
- srid 2y agoI use https://github.com/cachix/git-hooks.nix 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 https://github.com/srid/haskell-template The pre-commit configuration: https://github.com/srid/haskell-template/blob/master/nix/modules/flake/pre-commit.nix https://github.com/srid/haskell-template/blob/master/nix/mod...
- joachimma 2y agoFor me the issue to be solved is how to easily get the team to run the tool. Some focus should be on integrating build tools. When I or a team member do gradle build, npm build or cargo build or similar on a fresh checkout the tool should ask to be installed.
- autarch 2y agoThat is what mise from the same author is for. It lets you define per-project sets of tools with specific versions (including languages). I find it quite useful and I'm planning to get my team at work to adopt it once I get some round tuits.
- DrBenCarson 2y agoI would use a wrapper sh script that checks for the tool and prompts an install, basically how Java projects include maven or gradle into a repo
- hv42 2y agoOne of the goal of hk is to be used with mise (https://mise.jdx.dev/dev-tools/ 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 https://mise.jdx.dev/cli/generate/bootstrap.html and https://mise.jdx.dev/continuous-integration.html#bootstrapping https://mise.jdx.dev/continuous-integration.html#bootstrappi...
- timhh 2y agoInteresting. I've been working on a pre-commit replacement too, written in Rust but using WASI for all plugins (no exceptions!). I haven't got very far but I think this will have huge advantages over pre-commit, mostly in reliability. Me and my colleagues have had numerous issues setting up pre-commit because it inherits Python's atrocious infrastructure. I'm curious how this is going to deal with actually running plugins? Will it take the same approach as pre-commit and add dedicated not-very-good support for a load of different languages?
- Spivak 2y agoNot gonna say Python isn't a mess but I'm surprised a self-contained application is so bad. All the pieces are there to have it work— give it its own venv, use wrappers or the shebang so transparently uses it, and plug-ins get installed into that venv. All should be happy.
- trallnag 2y agoIs it that difficult to use `pipx install` or `uv tool install`?
- hv42 2y agoYou will be able to use mise to set up any tools required for the linters. See https://mise.jdx.dev/dev-tools/ https://mise.jdx.dev/dev-tools/
- jdxcode 2y ago
- azeirah 2y agoI 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 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)
- guipsp 2y agoNix is slow enough that having it in your pre-commit gets annoying
- azeirah 2y agoHaven't run into that yet, but can imagine that it gets worse if your devenv is large. I'm sure it's something that can be engineered away and optimized in the Nix core though. Because yeah it isn't a hyperspecialized tool for specifically git hooks alone written in Rust. No. It's not a saw nor a hammer. It's an entire workshop. Flakes are less of a workshop, but more like a bus with tools or a heavy-duty toolbox.
- Saphyel 2y agoMy git pre-commits are usually calling other executables or other tools, so I'm not quite sure how much it matters how fast is the git pre-commit tool. Can we have a benchmark of a normal use case of how much time are we saving with this new tool? or is this "Yet Another Rust Rewrite" (YARR)?
- thayne 2y agoBeing written in rust instead of python or go probably doesn't matter that much. But being able to run multiple tasks in parallel, which hk claims to do, could make a big difference.
- thayne 2y agoThe most compelling thing about this for me is that it uses pkl instead of yaml or json.
- jdxcode 2y agopkl is so good I don't think I need plugins for hk
- khimaros 2y agothis is written by the author of mise
- rswail 2y agoMy question is how do I get this stuff into the repo itself so that it is replicated on a clone/fetch/pull? I don't want to have to have 3rd party tools (including things like PRs/issue management) that don't record their info in the repo itself. Should be possible with the content addressable store underneath and new blob types? Or will that break too much of the existing git?
- turboponyy 2y agonix develop
- rswail 2y agoSorry how is this relevant to wanting to have issues and commit hooks as part of a repo that is cloneable and shareable in the same way as the existing commit->treeish->blob and refs?
- deleted 2y ago[deleted]