Go's gofmt and diff/VCS issues?
I've got a question about Go's gofmt tool, which formats automatically the output of programs according to the official Go specs (for ex开发者_如何学运维ample you cannot argue about where brackets should go in Go, because that's apparently fixed by the specs).
On the following page:
http://golang.org/doc/effective_go.html
under the "Formatting" paragraph, it is written that:
As an example, there's no need to spend time lining up the comments on the fields of a structure. Gofmt will do that for you. Given the declaration
type T struct {
name string // name of the object
value int // its value
}
gofmt will line up the columns:
type T struct {
name string // name of the object
value int // its value
}
However I don't understand how this could possibly play nice with diff and VCSes.
For example, if I had a new line:
confuzzabler int // doo doo be doo
and run a diff, I should get this:
2d1
< confuzzabler int // doo doo be doo
7d5
<
And life would be all good: the diff shows the only line that got changed.
However if I re-run the gofmt I got this:
type T struct {
confuzzabler int // doo doo be doo
name string // name of the object
value int // its value
}
And now I re-run diff and I get this:
2,4c2,3
< confuzzabler int // doo doo be doo
< name string // name of the object
< value int // its value
---
> name string // name of the object
> value int // its value
7d5
<
Which is a highly confusing and misleading diff output because only one line changed.
How do you deal with this as a Go developer?
$ diff --help|grep -i white
-b --ignore-space-change Ignore changes in the amount of white space.
-w --ignore-all-space Ignore all white space.
As to issues with VCS, if you were formatting the code yourself following some established convention (let's assume here this convention is what gofmt
follows) you'd have manually reformatted the whitespace in that code block exactly the way gofmt
did, and this change would have been counted by any VCS as a change. So I don't see any problem with semantics in this case, really. If you instead care about diffing tools provided by VCSes you should probably look whether they do support ignoring whitespace changes as the GNU diff mentioned above does. FWIW git diff
does support this with the same -b
command line option.
Your Go-based project standards should dictate something like:
Before any Go code is committed to the VCS, it is formatted with
gofmt
. This is the only acceptable format.
Then there is no argument; if the code passes through gofmt
unchanged, all is well. If it changes when passed through gofmt
, then use the output from gofmt
. What you do while editing is up to you (subject to the other coding standards), but this is a requirement for any code checked into your VCS.
If this really bothers you, do two checkins.
The first check in adds confuzzabler
. A reasonable comment is "Adding new variable to T".
Your diff will be isolated to the code you have actually changed.
Then, perform gofmt.
The second commit is just formatting changes and a reasonable commit msg would be "gofmt". The diff here will be only code that gofmt has changed.
Comparing the diff output, it's obvious what happened. It's neither confusing nor misleading.
精彩评论