From 75081c63ee8b204a239572a232d50455556882f4 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Mon, 21 Mar 2016 01:55:24 -0400 Subject: Go ahead and add the generated files. So I know about regressions. --- public/git-go-pre-commit.html | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 public/git-go-pre-commit.html (limited to 'public/git-go-pre-commit.html') diff --git a/public/git-go-pre-commit.html b/public/git-go-pre-commit.html new file mode 100644 index 0000000..ba30bdb --- /dev/null +++ b/public/git-go-pre-commit.html @@ -0,0 +1,42 @@ + + + + + A git pre-commit hook for automatically formatting Go code — Luke Shumaker + + + +
Luke Shumaker » blog » git-go-pre-commit
+
+

A git pre-commit hook for automatically formatting Go code

+

One of the (many) wonderful things about the Go programming language is the gofmt tool, which formats your source in a canonical way. I thought it would be nice to integrate this in my git workflow by adding it in a pre-commit hook to automatically format my source code when I committed it.

+

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.

+

I found a few solutions online, but they were all missing something—support for partial commits. I frequently use git add -p/git gui 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.

+

I ended up writing a solution that only formats the version of the that is staged for commit; here's my .git/hooks/pre-commit:

+
#!/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
+

It's still not perfect. It will try to operate on every *.go 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.

+

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.

+ +
+ + + -- cgit v1.2.3