Go 的 gofmt 和 diff/VCS 问题?

发布于 12-03 11:08 字数 1433 浏览 2 评论 0原文

我有一个关于 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 和 VCS 配合得很好。

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

厌倦2024-12-10 11:08:54
$ 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.

至于 VCS 的问题,如果您按照某种既定约定自行格式化代码(我们假设此约定是 gofmt 遵循的约定),那么您必须按照以下方式手动重新格式化该代码块中的空白gofmt 做到了,任何 VCS 都会将这一更改视为更改。所以在这种情况下我确实没有看到任何语义问题。如果您关心 VCS 提供的 diff 工具,您可能应该看看它们是否支持忽略空格更改,就像上面提到的 GNU diff 那样。 FWIW 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.

荆棘i2024-12-10 11:08:54

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

在将任何 Go 代码提交到 VCS 之前,都会使用 gofmt 对其进行格式化。这是唯一可接受的格式。

那么就没有争论了;如果代码通过 gofmt 时没有发生变化,则一切正常。如果它在通过 gofmt 时发生变化,则使用 gofmt 的输出。编辑时做什么取决于您(遵守其他编码标准),但这是签入 VCS 的任何代码的要求。

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.

你怎么敢2024-12-10 11:08:54

如果这确实让您感到困扰,请进行两次签到。

第一次签入会添加confuzzabler。一个合理的评论是“向 T 添加新变量”。
您的差异将与您实际更改的代码隔离。

然后,执行 gofmt。

第二次提交只是格式化更改,合理的提交消息是“gofmt”。这里的 diff 仅是 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文