搜索

首页  >  问答  >  正文

git - 为什么要Sign Off?

为什么很多开源项目都要求Sign Off?Git里面已经配置用户名和邮箱了,再次署名的意义是什么?

另外,怎么进行Sign Off操作?是在提交描述最后加一行就行,还是在Pull Request的时候,还是需要用什么其他方法?

某草草某草草2781 天前1652

全部回复(2)我来回复

  • 大家讲道理

    大家讲道理2017-05-02 09:27:58

    首先,区分 sign-off 和签名。 @nightfire 已经解释了签名。我来解释(翻译)一下 sign-off 的意义。

    我并没有看到「很多开源项目都要求」sign-off。最著名的是 linux 内核。它的文档里是这么说的:

    11) Sign your work

    To improve tracking of who did what, especially with patches that can
    percolate to their final resting place in the kernel through several
    layers of maintainers, we've introduced a "sign-off" procedure on
    patches that are being emailed around.

    因为在 Linux 的开发过程中,他们并不使用 GitHub 创造的「pull request」,而是通过(分布式的)电子邮件寄送补丁(所以 git 对邮件有着相当好的支持)。补丁寄来寄去的,就需要跟踪了,不然像 BSD 经历过的那样扯起皮来影响开发就不好了。「Signed-off-by」实际上是一个声明,你保证寄送的补丁符合「Developer's Certificate of Origin 1.1」里边那几点。

    StackOverflow 上有人说了,这只是少数几个项目的要求,大部分项目并不使用 sign-off。

    PS: 你如果看内核提交的话,有时能看到一个 commit 有一长列 sign-off 的。这种情况下仅仅一个 committer 和一个 author 怎么够呢?

    回复
    0
  • PHPz

    PHPz2017-05-02 09:27:58

    简单的答案是为了让你证明你就是你!

    一般提交的时候会有 author 和 committer 两个信息,通常都是一个人(私有项目,共用 central repo)。

    在没有 Github 的年代(比如说 Git 最早是用于 Linux Core 的协作开发),现在大家都习以为常的 pull request 并不是这么简单就能搞定的。那时候会常常使用 patch 的方式分布式开发,比如说你把你的提交(此时产生 author 信息)通过邮件附件的方式发给项目管理/维护者,然后他/她再合并到中心库去(这是产生了 committer 信息)……

    然而,不管是 author 还是 committer,本质上它们都无法证明那个“人”就是真实的做了那件事情的人。因为想知道一个开发者的姓名和电子邮件实在太简单不过了,邮件附件发出去的 patch 能证明作者就是你吗?接收到邮件并且去做了合并的人能确保就是 committer 那个人吗?(假设一个项目有多个管理/维护者)

    所以,看重这一点的人会使用 GPG 秘钥来进行安全的签名,也就是你问的 Sign Off ,其实就是一个电子签名啦,很多电子邮件客户端也用这个做数字签名的。

    我尽可能的说的简单明了,但其实这里面的细节多得超乎你的想象,有兴趣的可以看看这篇文章:A Git Horror Story: Repository Integrity With Signed Commits,而这篇文章也还没有讲完与 Sign Off 相关的一切。

    还有一个关注点是这样的,很多项目都会有许可证对吧?但是你在项目内或许会用到第三方代码,很可能这些代码的许可政策和这个项目的许可证是互斥/冲突的。如果是开源项目(如你所问),对这方面事情就更加看重了(你想别人找你打官司吗?)。Git 的 Sign Off 是可以精确到行的,这就是代码真实来源的一个考证(尽管可靠性有待商榷,但总好过没有……)。这方面的东西就不扯了,我也就是略有耳闻罢了。

    想使用签名,最简单需要三步(以 Mac 为准):

    1. 你需要 gunpg 的程序,Mac 可以用 homebrew 安装:

    2. 你需要生成你的 GPG 秘钥,过程省略了,上面那篇文章里有,生成好以后是这样的:

    3. 你需要告诉 Git 你的秘钥 ID 是啥(因为可以同时拥有多个秘钥):

      `git config --global user.signingkey KEY_ID`
      这个 ID 就在第二步列表里可以找到
      

      好了,至此以后 git commit 命令里加上 -S (注意大写),提交的时候就会自动附上你的数字签名了,你就是你,拒绝仿冒!


    根据 @依云 的提示,--sign-off--gpg-sign 是有区别的,这个是有历史原因的,感兴趣的可以看看她答案里的评论。以下引用 Google 搜索的答案:

    -s adds a "signed off by" field to the commit. -S actually GPG signs the commit, which was added in git 1.7.9. Also, this does not sign all commits, but only those which are made by the user directly using the git c command. In a rebase, when new commits are created, this will not sign off on (or PGP sign) the commits, unless you do an interactive rebase and manually commit every change.

    -S 可以两个一起做了,这是前面答案里推荐使用此选项的原因。所以 --sign-off 只是署名,而 --gpg-sign 是使用 GPG 秘钥来署名。


    OK,又错了…… -S 不能两个一起做了,如果既要署名又要签名,就得两个一起用。

    回复
    0
  • 取消回复