diff options
Diffstat (limited to 'public/git-go-pre-commit.html')
-rw-r--r-- | public/git-go-pre-commit.html | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/public/git-go-pre-commit.html b/public/git-go-pre-commit.html new file mode 100644 index 0000000..8b81f61 --- /dev/null +++ b/public/git-go-pre-commit.html @@ -0,0 +1,69 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title>A git pre-commit hook for automatically formatting Go code — Luke T. Shumaker</title> + <link rel="stylesheet" href="assets/style.css"> + <link rel="alternate" type="application/atom+xml" href="./index.atom" name="web log entries"/> +</head> +<body> +<header><a href="/">Luke T. Shumaker</a> » <a href=/blog>blog</a> » git-go-pre-commit</header> +<article> +<h1 id="a-git-pre-commit-hook-for-automatically-formatting-go-code">A +git pre-commit hook for automatically formatting Go code</h1> +<p>One of the (many) wonderful things about the Go programming language +is the <code>gofmt</code> tool, which formats your source in a canonical +way. I thought it would be nice to integrate this in my <code>git</code> +workflow by adding it in a pre-commit hook to automatically format my +source code when I committed it.</p> +<p>The Go distribution contains a git pre-commit hook that checks +whether the source code is formatted, and aborts the commit if it isn’t. +I don’t remember if I was aware of this at the time (or if it even +existed at the time, or if it is new), but I wanted it to go ahead and +format the code for me.</p> +<p>I found a few solutions online, but they were all missing +something—support for partial commits. I frequently use +<code>git add -p</code>/<code>git gui</code> to commit a subset of the +changes I’ve made to a file, the existing solutions would end up adding +the entire set of changes to my commit.</p> +<p>I ended up writing a solution that only formats the version of the +that is staged for commit; here’s my +<code>.git/hooks/pre-commit</code>:</p> +<pre><code>#!/bin/bash + +# This would only loop over files that are already staged for commit. +# git diff --cached --numstat | +# while read add del file; do +# … +# done + +shopt -s globstar +for file in **/*.go; do + tmp="$(mktemp "$file.bak.XXXXXXXXXX")" + mv "$file" "$tmp" + git checkout "$file" + gofmt -w "$file" + git add "$file" + mv "$tmp" "$file" +done</code></pre> +<p>It’s still not perfect. It will try to operate on every +<code>*.go</code> file—which might do weird things if you have a file +that hasn’t been checked in at all. This also has the effect of +formatting files that were checked in without being formatted, but +weren’t modified in this commit.</p> +<p>I don’t remember why I did that—as you can see from the comment, I +knew how to only select files that were staged for commit. I haven’t +worked on any projects in Go in a while—if I return to one of them, and +remember why I did that, I will update this page.</p> + +</article> +<footer> + <aside class="sponsor"><p>I'd love it if you <a class="em" + href="/sponsor/">sponsored me</a>. It will allow me to continue + my work on the GNU/Linux ecosystem. Thanks!</p></aside> + +<p>The content of this page is Copyright © 2013 <a href="mailto:lukeshu@lukeshu.com">Luke T. Shumaker</a>.</p> +<p>This page is licensed under the <a href="http://www.wtfpl.net/txt/copying/">WTFPL-2</a> license.</p> +</footer> +</body> +</html> |