github, ready to go?

假期的时候给一个 golang 开源项目 s 贡献了代码,快两个月了,时间也有点久远了😂 我发现给 golang 项目贡献代码的姿势跟给其他语言贡献代码的姿势不太一样,而我当时只是 hack 了一下,也没记录下来,这不,给自己挖坑了,最近又有一位朋友问我怎么给 github 上的 golang 项目贡献代码,为什么会有这样的问题呢,难道 golang 很特殊?听我一一道来。

问题1:怎么给一个 github 项目贡献代码

docker/compose 为例吧,这个项目的 COMTRIBUTING.md 中描述的指导是非常规范的,客官也不必点击链接跳转了,我总结了一下步骤:

  1. Fork https://github.com/docker/compose
  2. 在你的开发机上 git clone git@github.com:username/compose.git
  3. 配置源仓库地址,在开发过程中与源仓库同步
  4. 提交代码后,在页面上点击 New pull request

关于如何与源仓库同步,可以看 github 的文章:https://help.github.com/articles/syncing-a-fork/

简单总结一下就是:

增加一个源仓库的地址

  • git remote -v
  • git remote add upstream https://github.com/original_owner/original_repository

保持与源仓库同步

  • git fetch upstream
  • git checkout master
  • git merge upstream/master

问题2:golang 有什么特别的

如果按照上面的做法,比如我 fork 了s 这个项目,然后使用 go get:

1
$ go get https://github.com/knarfeh/s

代码就会放在 $GOPATH/src/github.com/knarfeh/s 路径下,然后就修改这份代码吗?不对。问题出在 go 项目的 import path 上,例如:scmd/config.go (commit id:4b6657dfa11462864c527f43a86227def63e03f3)

1
2
3
4
5
6
7
8
9
import (
"encoding/json"
"os"
"path/filepath"

"github.com/mitchellh/go-homedir"
"github.com/zquestz/go-ucl"
"github.com/zquestz/s/providers"
)

这个 import 的路径,指向的是 github.com/zquestz/s/,这就尴尬了,难道把这些指向源仓库的 import 全改了,提 PR 的时候再改回来?也太麻烦了。

问题3:给 github 的 golang 项目贡献代码,正确的姿势是什么

其实很简单,我们可以在源仓库添加我们 fork 的仓库的地址。以 s 为例,具体步骤:

  1. 在 github 上 fork 源仓库
  2. go get https://github.com/zquestz/s
  3. 给源仓库加上 fork 的仓库地址,比如:git remote add fork https://github.com/knarfeh/s
  4. 修改了代码后,git push fork ,然后就可以在 github 上提交 PR 啦

回过来一想,也许这才是 github 的正确使用方式呢,这样的话,也不必用 https://help.github.com/articles/syncing-a-fork/ 这种方式跟源仓库同步了,直接 pull master,然后在 fork 的分支上 rebase 就好了,呵呵呵呵呵🙃

参考资料: