遭遇git send-email和svn patch

Git

Git

长假后的第二天,上头传来了加强代码质量的“旨意”,目标是每一次代码提交都得先给 leader 审核。那么如何落实呢?先导出 patch 文件,然后 email 给责任人,收到对方明确的通过意见后,才能执行 commit。–这种方法似乎很类似 Linux Kernel 的情形,我倒也不反对。

但如此一来,审核环节就成了一个瓶颈,整个的开发行为也就变得串行化。最后方案初步调整为,在 SVN 仓库新开一个分支,专门用于开发人员的提交,开发人员修改后发出 patch 给同事审核,通过后提交到分支。再由 leader 逐个审核分支提交,将认为 OK 的提交合并到主干。这样,主干上始终保持着被认为是合格的代码。

上面的方式到底能带来怎么样的利弊,待试行一段时间再说。以下我只描述在使用 Git 来参与上面的流程时,所遇到的问题,以及如何解决。Git 支持通过补丁文件来进行版本库之间的交互,在《Git 权威指南》一书中,作者是这么描述的(P296):

例如 Git 项目本身的代码提交就主要由贡献者通过邮件传递补丁文件来实现的。

这种使用补丁文件进行提交的方式可以提高项目的参与度。因为任何人都可以参与项目的开发,只要将提交转化为补丁,会发邮件即可。

尽管我认为通过补丁文件加电子邮件的方式已经过时,但不能否认目前为止它还管用。依据书中的讲解,修改 config 配置 sendemail :

[sendemail]
smtpencryption = tls
smtpserver = smtp.gmail.com
smtpuser = xxxxxx@gmail.com
smtpserverport = 587
confirm = always

然后通过 format-patch 很快生成了 patch 文件,接下来就是 send-email,但不幸出现了状况:
Can’t locate Net/SMTP/SSL.pm in @INC (@INC contains: /opt/local/lib/perl5/site_perl/5.12.4/darwin-thread-multi-2level /opt/local/lib/perl5/site_perl/5.12.4 /opt/local/lib/perl5/vendor_perl/5.12.4/darwin-thread-multi-2level /opt/local/lib/perl5/vendor_perl/5.12.4 /opt/local/lib/perl5/5.12.4/darwin-thread-multi-2level /opt/local/lib/perl5/5.12.4 /opt/local/lib/perl5/site_perl /opt/local/lib/perl5/vendor_perl .) at /opt/local/libexec/git-core/git-send-email line 1107.

MacPorts

MacPorts

很明显,它告诉我找不到一个叫做 SSL 的东东,MBP 上安装的是 MacPorts 进行软件管理,于是将焦点首先集中在官方网站上,很幸运找到了一个相似的 Bug Report,尽管该问题单依旧是打开状态,但是其评论当中提供了一个链接可以解决这个问题。

执行下面的命令后,上面的问题消失了。
sudo -H /opt/local/bin/perl -MCPAN -e "CPAN::Shell->force(qw(install Net::SMTP::SSL));"

另外,我注意到下面这个命令可以达到相同的效果,但因为对 Perl 不熟悉,所以不能保证。
sudo -H cpan Net::SMTP::SSL

上面的问题解决了,但是又有了新问题,Git 又开始抱怨了:
Need MIME::Base64 and Authen::SASL todo auth at /opt/local/libexec/git-core/git-send-email line 1154, line 1.

好吧,逢山开路,遇水搭桥,缺什么就装什么:
sudo port install p5-net-smtp_auth

邮件成功发出去了,并且很快收到响应。对方并不认可我的形式,要求提供 patch 文件,以邮件附件而不是邮件正文的形式发送。好吧,这也难不倒我,通过 git diff 可以导出补丁文件,不就是附件吗?离开终端,打开 Mail.app,尽管我讨厌繁琐。

又一次收到响应,对方反馈无法通过 TortoiseSVN 的 Apply patch 功能进行合并,得到的不是合并,而是新建了两个新文件夹,分别命名为 a 和 b。这是怎么一回事情呢?在 Mac OS X 上使用 patch 工具进行实验,成功合并了,说明生成的补丁文件没有问题。

仔细检查 patch 文件,看到其中部分内容如下:
diff –git a/src/com/foo/bar/ps/GalleryActivity.java b/src/com/foo/qcloud/bar/GalleryActivity.java
index 390d413..cd72071 100644
— a/src/com/foo/qcloud/bar/GalleryActivity.java
+++ b/src/com/foo/qcloud/bar/GalleryActivity.java

原来 patch 为了区分不同 revison,git 人为地以 a 和 b 为标记进行区分,通过全文替换,移除 a/ 和 b/,再进行 Apply patch,最后如愿以偿。

7 Comments

superb11月 13th, 2012 at 7:19 上午

you should use code review tools like phabricator.

Chenglong12月 5th, 2012 at 1:23 下午

Git明明可以直接用Gerrit来做审核 干嘛绕圈子

Xu Haojie12月 5th, 2012 at 6:47 下午

因为公司Repository还是SVN

happy4月 13th, 2013 at 8:44 上午

博主你好

有个问题请教你, 我现在想开发一个软件,希望有多个学生参与,但是我不希望学生毕业后,把软件带走,因此希望对学生的访问有所限制。

请问有没有比较好的经验啊?

Xu Haojie4月 13th, 2013 at 11:06 上午

这种需求在企业里也是常见的,常规做法有将软件代码拆分成若干子代码库,软件编译时需要具备所有代码库,但每个人只赋予一个或多个代码库的访问权限,这样可避免一个人能够得到全部代码。编译软件时,必须通过编译服务器执行,这样可以保证每个人能够修改-验证-提交。

happy4月 15th, 2013 at 3:22 下午

首先,谢谢博主的解答

还想问一下,你们在具体管理时,一般使用什么软件,如何设置的? 编译服务器怎么管理呢?
博主能不能写篇博文?

不胜感激

Xu Haojie4月 16th, 2013 at 9:31 上午

Sorry,这个问题我爱莫能助了,公司环境下都是有专门的配置管理员来负责这些事情,我暂时还没有这方面的工作经验。

Leave a comment

Your comment