Git’s Magic Files
39 points by drmorr
39 points by drmorr
Unless I've missed something, I really think the pre-commit (& other hooks) could use an official revamp:
cat them together if they're written in the same language etc.)You cannot check them in
This sounds like a feature. Scripts like these shouldn’t just be ran on your machine by others. It also prioritizes that these scripts are for your local workflow so you can do what you need to do without interrupting others (for instance, maybe you convert spaces to tabs for accessibility on pull, & then reconvert out, but you wouldn’t want that in everyone’s workflow). If you want it in version control make a .githooks directory & add this to your README so users can choose to opt in if they want.
$ git config --local core.hooksPath .githooks
Nothing drives me more mad than tools like Husky or pre-comming adding dependencies & then injecting scripts into my workflow to be executed without consent (often breaking rebase-based workflows)—at least with the little snippet above, you are required to opt in & it has no deps.
Many good points. From my perspective, pre-commit hooks are useful to catch CI errors locally (and combined with worktrees, it would be fine to have them taking a bit of time to execute locally, if they at least finish faster/with less $$ spent on CI, catching the same things - obviously not feasible for every possibly job in CI) and it would be helpful to expose that possibility to all devs.
Maybe the "you need to opt in" as part of a large checklist of getting started is the local optimum 🤷 Maybe "run parts of the CI locally and get a signoff from somewhere to fast-track some CI jobs" could be even more streamlined. If this is handled through git or not, I'm not sure, but the "hooks" concept is well-used so it's a natural starting point for discussions.
I think that pre-commit hooks (if we're singling out that hook for now) requires quite a homogenic development machine in order to be useful for the single developer (fast-failures before pushing) - what if developers are cross-OS & git hooks are written with a single language/OS in mind? And like you say, tools need to be sanitary, self-installing things is a no-go for multiple reasons.
It’s the same argument on why checking in .envrc is counter to the design goal—that is, to have scripts that execute for you & your setup in the way that you want, & to be modified to suit you. Instead this now makes opting for modification or extension impossible since you didn’t let the user be in control of their setup. You can say that you need to execute a certain set up scripts before some staging without mandating how that might be done; please check in & document those scripts. However, there’s a line that’s being crossed with the typical pre-commit-like setup: executing that code on the user’s behalf without them allowing it to be modified (or possibly opted out of).
For instance:
--flag I need to pass in to disable trackingIf you document what you expect to run, I can set up my environment to do what’s needed without having the exact plan laid out for me—& I don’t like being treated like treating contributors or coworkers as not smart enough to set up their own system or read the docs (& it’s okay if they mess it up the first time accidentally!). By checking in those exact scripts, folks can’t make changes since they don’t want push those changes on others & so they will be left with juggling unstaged changes… which inevitably end up getting accidentally added to a commit.
This is how I was able to get .envrc removed from Nixpkgs since folks needed to use it to set their own environment variables as it’s a tool for developers in local environments. Sure enough, while they were arguing against me as “this won’t happen” on the same day that someone sure enough accidentally did.
This is the first time I heard about direnv. Is there any reason to not have both a .env file and a .env.local file in the same directory so the latter overwrites the former?
I understand that, from your perspective, we at work should have an .env.sample commited and .env ignored so every developer creates the .env based on the sample.
.env & .envrc are not the same thing. There have been all sorts of proposed hacks importing/checking other adjacent, but the simpler solution not to be trying to code your way out of a bad premise: if you don’t commit the file, the user can just assemble it what works themselves. You have a template folks should be following like you said, check in an .envrc.{example,sample} instead of having code be executed/not extensible.
I feel like pre-commit hooks are a bit outdated altogether. I'm all for some validation script that can be run locally, but they shouldn't be run as part of git operations. The correct place to ensure that a change follows whatever rules you want (formatting, tests passing, no compiler warnings, whatever) is on the git host. Protect the main branch, have a CI job which checks whatever you want, prevent merge requests from being merged without passing CI.
I think feedback loop is really important for attention, and its better to just instantly be told if the commit message is malformatted or if tests fail. I have have a post commit hook that runs in the background and notifies me if tests fail which is nice, and a pre-commit hook that ensures my commit format is correct.
I think they serve different purposes. That said, if you write your pre-commit and post-commit hooks first, you can probably reuse that logic for your CI.
As I said, I think having good ways to run checks locally is great. I just don't see the reason to make it run as part of git operations.
Being able to check in hooks would be amazing. But could (???) also cause problems if the user doesn't have, e.g., pre-commit installed. But even so, a "hook failed, go install this software" is better than being blissfully unaware that the hooks even exist (until they fail in CI, because hopefully you're running all your hooks in CI, right?)
I think the bigger problem is that git hooks can silently run arbitrary code when you do an innocuous thing like running git pull. Making the user install the hooks themself is at least a little safer.
Agreed. It would depend on the repo being compromised first though, unless we're talking globally configured githooks in the developer's environment. This might be placing the risk in the same category as checked in build scripts or CI workflows, provided those are colocated within the same git repository.
Didn’t realize how many of these “magic files” there actually are. I’ve mostly only used .gitignore, so this was a useful overview for me.