pre-commit hooks are fundamentally broken
pre-commit hooks are fundamentally broken Let's start a new Rust project. $ $ $ $ Initialized empty Git repository in /home/jyn/src/third-website/best-fizzbuzz-ever/.git/ $ $ [main (root-commit) 661dc28] fizzbuzz 1 file changed, 4 insertions(+) create mode 100644 main.rs Neat. Now let's say I add this to some list of fizzbuzz projects in different languages. Maybe .... this one . They tell me I need to have "proper formatting" and "use consistent style". How rude. Maybe I can write a pre-commit hook that checks that for me? $ $ $ $ $ Diff in /home/jyn/src/third-website/best-fizzbuzz-ever/src/main.rs:1: -fn main() { for i in 0.. { - println ("fizzbuzz"); -}} +fn main() { + for i in 0.. { + println("fizzbuzz"); + } +} Neat! Let's commit that change. $ $ [main 3be7b87] add pre-commit hook 1 file changed, 4 insertions(+) create mode 100755 pre-commit $ On branch main Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: main.rs Oh ... We fixed the formatting, but we didn't actually stage the changes. The pre-commit hook runs on the working tree , not on the index , so it didn't catch the issue. We can see that the version tracked by git still has the wrong formatting: $ fn main() { for i in 0.. { println ("fizzbuzz"); }} Maybe we can make the script smarter? Let's checkout all the files in the index into a temporary directory and run our pre-commit hook there. 1 $ $ $ Diff in /tmp/best-fizzbuzz-ever-pre-commit.ZNyw/main.rs:1: -fn main() { for i in 0.. { - println ("fizzbuzz"); -}} +fn main() { + for i in 0.. { + println("fizzbuzz"); + } +} Yay! That caught the issue. Now let's add our rust program to that collection of fizzbuzz programs. $ $ [main 3cb40f6] make pre-commit hook smarter 2 files changed, 11 insertions(+), 4 deletions(-) $ $ remote: Enumerating objects: 222, done. remote: Total 222 (delta 0), reused 0 (delta 0), pack-reused 222 (from 1) Receiving objects: 100% (222/222), 29.08 KiB | 29.08 MiB/s, done. Resolving deltas: 100% (117/117), done. From https://github.com/joshkunz/fizzbuzz * [new branch] master -> upstream/master $ Successfully rebased and updated refs/heads/main. Maybe we'll make one last tweak... $ $ Diff in /tmp/best-fizzbuzz-ever-pre-commit.n1Pj/fizzbuzz-traits.rs:4: use std::iter; struct FizzBuzz { - from : i32 - , to : i32 + from: i32, + to: i32, } impl FizzBuzz { Uh. Huh. Right. The code that was already here wasn't formatted according to rustfmt. Our script is running on every file in the git repo, so it won't let us commit. Maybe we can change it to only run on modified files? $ $ [main f2925bc] update main.rs; make pre-commit even smarter 2 files changed, 5 insertions(+), 1 deletion(-) Alright. Cool. Let's do one last thing. Let's say we had an existing PR to this repo and we need to rebase it. Maybe it had a merge conflict, or maybe there was a fix on main that...
Preview: ~500 words
Continue reading at Hacker News
Read Full Article