<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ken Powers</title>
    <description>The latest articles on DEV Community by Ken Powers (@knpwrs).</description>
    <link>https://dev.to/knpwrs</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F514920%2F41d3cae9-a931-44aa-83c2-c4c9ce62a916.jpeg</url>
      <title>DEV Community: Ken Powers</title>
      <link>https://dev.to/knpwrs</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/knpwrs"/>
    <language>en</language>
    <item>
      <title>Using Direnv to Automatically Manage Git Hooks</title>
      <dc:creator>Ken Powers</dc:creator>
      <pubDate>Sun, 15 Nov 2020 18:51:16 +0000</pubDate>
      <link>https://dev.to/knpwrs/using-direnv-to-automatically-manage-git-hooks-3mb8</link>
      <guid>https://dev.to/knpwrs/using-direnv-to-automatically-manage-git-hooks-3mb8</guid>
      <description>&lt;p&gt;The recent release of &lt;a href="https://github.com/typicode/husky/issues/776"&gt;npm@7 broke husky&lt;/a&gt;, my git hook management tool of choice. When I was looking into why my git hooks had stopped working I came across &lt;a href="https://archive.is/y1uCz"&gt;the docs for the next version of husky&lt;/a&gt; and saw that git hooks will now be stored in a committed directory rather than inside &lt;code&gt;package.json&lt;/code&gt;.  This got me thinking; do I really need husky? Surely there must be a simple method to manage a directory of git hooks inside your repository. I want something that's (mostly) automatic, safe, easy, and preferably uses tooling I'm already familiar with (installing a global dependency just to manage git hooks on a per-project basis is somewhat less than ideal).&lt;/p&gt;

&lt;h1&gt;
  
  
  TL;DR
&lt;/h1&gt;

&lt;p&gt;As the title suggests, I am now using &lt;a href="https://direnv.net/"&gt;&lt;code&gt;direnv&lt;/code&gt;&lt;/a&gt; to manage my git hooks. What I landed on was adding the following line to a &lt;code&gt;.envrc&lt;/code&gt; file in the root of my repositories:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--local&lt;/span&gt; core.hooksPath &lt;span class="nv"&gt;$PWD&lt;/span&gt;/.githooks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I just run &lt;code&gt;direnv allow&lt;/code&gt; and place whatever hooks I want in the &lt;code&gt;.githooks&lt;/code&gt; directory at the root of my project, e.g., an executable file at &lt;code&gt;.githooks/commit-msg&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Check out &lt;a href="https://github.com/knpwrs/instant.bible"&gt;knpwrs/instant.bible&lt;/a&gt; or &lt;a href="https://github.com/knpwrs/listenator"&gt;knpwrs/listenator&lt;/a&gt; on Github to see this setup in action.&lt;/p&gt;

&lt;h1&gt;
  
  
  How does this work?
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://dev.to/blog/multiple-git-users"&gt;I already use &lt;code&gt;direnv&lt;/code&gt; for other things.&lt;/a&gt; It's a really handy tool for managing environment variables in a way that isn't tied to any specific framework or implementation, and additionally makes environment modifications available to all of your tooling. The trick is that &lt;code&gt;.envrc&lt;/code&gt; is more than just a file which specifies variables for &lt;a href="https://direnv.net/"&gt;&lt;code&gt;direnv&lt;/code&gt;&lt;/a&gt; to export -- it's a shell script which &lt;a href="https://direnv.net/"&gt;&lt;code&gt;direnv&lt;/code&gt;&lt;/a&gt; executes inside of &lt;code&gt;bash&lt;/code&gt; (even if you use another shell such as &lt;code&gt;zsh&lt;/code&gt;). Our &lt;code&gt;git config&lt;/code&gt; call configures the current git repository to look for hooks inside the &lt;code&gt;.githooks&lt;/code&gt; directory inside our repository. Whereas most solutions involve symlinking or copying files into &lt;code&gt;.git/hooks&lt;/code&gt;, we just reconfigure each individual git repository to tell it where to look for hooks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://direnv.net/"&gt;&lt;code&gt;direnv&lt;/code&gt;&lt;/a&gt; works automatically, so that makes this setup easy to use. It also won't execute any &lt;code&gt;.envrc&lt;/code&gt; files without explicit permission, so it's safe.  Since &lt;a href="https://direnv.net/"&gt;&lt;code&gt;direnv&lt;/code&gt;&lt;/a&gt; isn't tied to any specific framework or implementation, this setup for git hooks works great for polyglot monorepos (e.g., several microservices in a single git repository or multiple app implementations in a single repository).&lt;/p&gt;

&lt;p&gt;What I really would have liked is some sort of environment variable to configure where &lt;code&gt;git&lt;/code&gt; should look for hooks. This works just as well, though.&lt;/p&gt;

&lt;p&gt;Note that passing &lt;code&gt;--local&lt;/code&gt; isn't actually necessary, as &lt;code&gt;git config&lt;/code&gt; is &lt;code&gt;--local&lt;/code&gt; by default, and &lt;code&gt;--global&lt;/code&gt; only if specified. That said, for this purpose I do like passing &lt;code&gt;--local&lt;/code&gt; so our intentions are explicitly clear to anyone reading our code.&lt;/p&gt;

&lt;h1&gt;
  
  
  I want it to be less automated!
&lt;/h1&gt;

&lt;p&gt;I hear you. Running non-exports in your &lt;code&gt;.envrc&lt;/code&gt; isn't for everyone. If you would prefer manual hook initialization for your project, or if you would just like hooks to be opt-in, you can place the &lt;code&gt;git config&lt;/code&gt; call above into a shell script or even a &lt;code&gt;Makefile&lt;/code&gt; like such:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.PHONY: hooks

hooks:
    git config --local core.hooksPath $(shell pwd)/.githooks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now just have people run &lt;code&gt;make hooks&lt;/code&gt; and you're good to go!&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://direnv.net/"&gt;&lt;code&gt;direnv&lt;/code&gt;&lt;/a&gt; just may now be my favorite way to manage git hooks now! It's simple, safe, framework-agnostic, and automatic. I haven't seen the &lt;code&gt;git config&lt;/code&gt; approach discussed much elsewhere, so even if you prefer something more manual, hopefully this article was still helpful to you.&lt;/p&gt;

&lt;p&gt;This post originally appeared at &lt;a href="https://knpw.rs/blog/direnv-git-hooks"&gt;https://knpw.rs/blog/direnv-git-hooks&lt;/a&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>direnv</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
