Go的gofmt和diff/VCS问题?

huangapple go评论89阅读模式
英文:

Go's gofmt and diff/VCS issues?

问题

我对Go的gofmt工具有一个问题,它根据官方Go规范自动格式化程序的输出(例如,在Go中,你不能争论括号应该放在哪里,因为规范已经固定了)。

在以下页面上:

http://golang.org/doc/effective_go.html

在“格式化”段落中,写道:

> 例如,没有必要花时间对齐结构体字段的注释。Gofmt会为您完成这项工作。给定声明

type T struct {
    name string // name of the object
    value int // its value
}

> gofmt会对齐列:

type T struct {
    name    string // name of the object
    value   int    // its value
}

然而,我不明白这如何与diff和版本控制系统(VCSes)协同工作。

例如,如果我有一个新行:

confuzzabler int // doo doo be doo

并运行diff,我应该得到这个结果:

2d1
<     confuzzabler int // doo doo be doo
7d5
< 

生活将会很美好:diff显示了唯一发生变化的行。

然而,如果我重新运行gofmt,我得到这个结果:

type T struct {
    confuzzabler int    // doo doo be doo
    name         string // name of the object
    value        int    // its value
}

现在我重新运行diff,我得到这个结果:

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
< 

这是一个非常令人困惑和误导的diff输出,因为只有一行发生了变化。

作为Go开发者,你如何处理这个问题?

英文:

I've got a question about Go's gofmt tool, which formats automatically the output of programs according to the official Go specs (for example 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?

答案1

得分: 6

-b --ignore-space-change 忽略空格数量的变化。
-w --ignore-all-space 忽略所有空格。

关于版本控制系统的问题,如果您按照某个已建立的约定(假设这个约定是gofmt遵循的)自己格式化代码,您将手动重新格式化代码块中的空格,就像gofmt所做的那样,这个更改将被任何版本控制系统视为更改。所以在这种情况下,我真的看不出有什么语义问题。如果您关心版本控制系统提供的差异工具,您可能应该查看它们是否支持忽略空格更改,就像上面提到的GNU diff一样。顺便说一句,git diff也支持使用相同的-b命令行选项。

英文:
$ 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.

答案2

得分: 5

你的基于Go的项目标准应该规定如下:

> 在将任何Go代码提交到版本控制系统之前,应使用gofmt进行格式化。这是唯一可接受的格式。

然后就没有争议了;如果代码通过gofmt时没有改变,那就一切正常。如果通过gofmt时发生了变化,那么使用gofmt的输出。在编辑时你可以自行决定如何操作(遵守其他编码标准),但这是将代码提交到你的版本控制系统的要求。

英文:

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.

答案3

得分: 1

如果这真的困扰你,那么进行两次提交。

第一次提交添加了confuzzabler。一个合理的注释是“向T添加新变量”。
你的差异将仅限于你实际更改的代码。

然后,执行gofmt。

第二次提交只是格式更改,一个合理的提交消息可以是“gofmt”。这里的差异将仅限于gofmt更改的代码。

英文:

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.

答案4

得分: 0

比较差异输出,很明显发生了什么。既不令人困惑也不具有误导性。

英文:

Comparing the diff output, it's obvious what happened. It's neither confusing nor misleading.

huangapple
  • 本文由 发表于 2011年9月8日 21:08:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/7348548.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定