Git commit 注释格式

Git 本身并没有硬性限制注释的格式,不过,对于多人参与的项目来说, 好的注释风格更加有利于团队合作。 即使是自己用,也应当坚持实用好的注释风格, 一来是对自己的工作历史负责,二来得以养成好的注释习惯。 虽然这里标题说的是 Git,其他源代码控制系统也可以参考的。

可以先看看一些著名开源项目源代码管理系统当中的提交注释, 其中也有用 SVN 和 Bazaar 的, Apahe 的源码看不到 logview,可能是使用了 CVS 文件格式的原因:

结合其他参考文章,我总结 Git 的 推荐 注释风格如下:

  1. 第一行为对改动的简要总结,建议长度不超过 50,用语采用命令式而非过去式。

    Vim 很贴心,在默认配置下,注释的第一行文字颜色是黄色, 超过 50 列之后就变成白色了。

  2. 第一行结尾不要英文的句号 . ,中文的就也不要 吧。

    为啥?我给 rst2wp 提交的时候,对方也提出了这个要求 [1] [2] , 后来查了查,大概原因是,第一行被认为是一个“标题”,也会作为邮件标题, 而标题是不需要标点的。 上面那些开源项目也都遵守了这一规则。 不过也有 例外的

  3. 第二行为空行。

    如果配置了自动发送邮件,那么第一行就用来做邮件标题, 第三行开始的内容是邮件正文, 第二行是分隔线,用于区分两者。

  4. 第三行开始,是对改动的详细介绍,可以是多行内容,建议每行长度不超过 72。

    可以包括原因、做法、效果等很多内容,一切你认为与当前改动相关的。 为何是 72 长度呢?因为 git log 输出的时候能显示得比较好看, 前面 4 个空格作为缩进,后面留 4 个空格机动(英文按单词排版)。 Vim 的 gq 命令排版很方便。

    一些项目还对这个部分的内容有特殊要求,比如加一些特定标签什么的。

  5. 建议全部英文,首字母大写。如果一定要用中文,请尽量使用 UTF-8 编码。

  6. 大项目中,可以用 module/submodule: 前缀作为第一行的开头, 前缀首字母不必大写。

    前缀的冒号后面跟一个空格比较好看。 为了控制字符串长度,子模块名称可适当缩写,但应保持统一。

我以前喜欢在注释第一行加上 New: Add: Fix: 这样的前缀, 看来也是没有必要了。

Tips: 提交之前,用 git diff --check 可以检查有无空白字符错误, 比如行尾留有空白什么的。

BTW,在使用 Git 或者其他 SCM 时,还应当避免下面这些做法:

  • 把 SCM 当做备份工具。

    SCM 是项目/代码管理工具,备份功能只是“福利”。 随意将未完成测试或临时的工作结果进行提交, 不仅破坏日志的“纯洁性”,还不利于日后的浏览、整理、汇总等工作。 在开源项目中这么做的话,没人会接受这种提交。 如果确实需要备份当前工作异地继续的话,可以采用这样的折衷方法:

    $ git commit                # 在本地进行提交
    $ git format-patch -n1      # 导出 Patch
                                # 这个 Patch 就是你的备份
    $ git am Path_To_Patch_File # 如果换了工作地点,导入 Patch
    $ git reset --mixed [hash]  # 撤销提交,保留更改,继续工作
  • 一个改动不一次提交完成。

    “提交”的概念是具有独立的功能、修正等作用。 小可以小到只修改一行,大可以到改动很多文件, 但划分的标准不变,一个提交就是解决一个问题的。

    对格式的修正,不应该和其他功能修补一起提交, 这种情况应该考虑使用 git add --editgit add -p 也可以用用,更复杂和强大一些。

  • 注释不清晰。

    比如只有“修正 BUG”、“改错”、“升级”等,没有其他内容,等于没说。

参考

用 rst2wp 来写 WordPress

很久没有写 Blog 了,没想到一下子拉了这么长时间。 想想最初停止的原因,是因为在看到 reStructuredText 之后, 觉得用来写文章、文档或者 Blog 非常好,就想学着用用。 谁知 rst 太复杂了,光 说明文档 就那么长, 也没有完整的中文版,就想来翻译一下,翻译的结果还是用 rst 来写。 结果卡死在这里了,后来忙了就没有再继续了, Blog 也就没有再更新,翻译也没有进行完。

现在,随着一切在发展,似乎 WordPress 有些没落了, 原来的 rst 支持插件居然也几乎没有了。 大家都热衷于使用 Jekyll, Octopress, Pelican 类似的软件来生成静态 Blog, 摈弃了以前 PHP+Mysql 的动态网站方式, github 还提供配套的 托管服务 。 我不喜欢全静态化的实现方式,网站大了以后更新效率肯定会降低, 好在这些生成工具大多都支持 MarkdownreStructuredText , 继续使用 rst 来写 Blog 也不会太影响将来可能的迁移。

继续 Blog 吧,懒人又开始面临一个不是问题的问题:网络不好,连接速度慢, 直接登录 WordPress 后台写简直太痛苦了。 所以有一段时间我都是在本地编辑,然后粘贴到后台看效果。 这种方式在 rst 在线预览工具 的帮助下还算凑合 (原来有个 rst2a 也挺好用,但已经挂了很久了)。 看过一些 Blog 客户端软件,感觉大多仍然不理想,功能不足, WordPress 推荐工具 多半也不好用, 很多都很长时间没更新了。 于是,继续搜索,找到了现在用的 rst2wp

rst2wp 的工作方式是在本地用任何你喜欢的编辑器写 rst 文档, rst2wp 帮你转换成 html、预览或者上传到 WordPress 中。 rst 文件中可以指定 Category 和 Tag, 上传时会自动记录 Post Id 用于以后的编辑。 我 Fork 之后还增加了记录 date 和 slug 的功能。 一个比较完整的 rst 文档示例如下:

..  -*- mode: rst -*-
..  -*- coding: utf-8 -*-
 
:id: 6
:title: 用 rst2wp 来写 WordPress
:slug: 201211-test-rst2wp
:date: 2012-11-27 00:19:37
:publish: yes
:categories:
    - Blog
    - Tools
:tags:
    - blog
    - git
    - github
    - WordPress
    - RestructuredText
 
 
blah 测试 中文。
 
+---+---+---+
| a | b | c |
+===+===+===+
| 1 | 2 | 3 |
+---+---+---+

先用着吧,顺便熟悉 reStructuredText 的语法。

Ubuntu 升级到 10.04 lucid

本来能够直接从 9.04 升级上来的,但由于我启用了 sshfs,而 mount 在网络启动之前执行,所以系统升级完启动后就挂在 mount sshfs 那里不动了,一开始不知道,以为不行了,就直接重新安装了 10.04,也好,4、5年了,该重装一会了。

启用 Ctrl+Alt+Backspace 快捷键重启 X

System->Preferences->Keyboard->Layouts->Options,打开 Key sequence to kill the X server 并选中 Control+Alt+Backspace,立即生效,或者执行命令:

$ setxkbmap -option terminate:ctrl_alt_bksp

这个是每次启动 X 之后执行才生效。

设置系统默认输入法

System->Administration->Language Support 中,Install/Remove Languages 中装上中文语言支持,安装 fcitx,然后在 Keyboard input method system 里选上 fcitx,重启 X。

Mysql 服务启动的问题

无法启动或者重启,修改 /etc/init/mysqld.conf,在 start on (net-device-up 后面添加内容如下:

start on (net-device-up IFACE=eth0

如果提示 Can't create test file 类似的信息导致无法启用,是由于用户变更了 datadir,而系统没有赋予 mysql 读写那个目录的权限所致。修改 /etc/apparmor.d/usr.sbin.mysqld 添加下面的内容:

/your new datadir/ r,
/your new datadir/** rwk,

/etc/init.d/apparmor restart 后 mysql 就能启动了。注意上面的 datadir 如果是 ln 指向,需要填写真实路径。

mysql 还有个烦人的问题,就是 bind-address 默认只是本机,如果想改成 ip 或者 0.0.0.0 代表所有地址,还不能着急,先 bind 127.0.0.1 启动一会,然后停止服务修改 bind-address,不然 sudo service mysql 脚本又会出现问题。

好像 mysql 的自动启动取消了?在 /etc/rc.local 中加一句 service mysql start

启动时检查完磁盘就没有反应的问题

多半是由于 fstab 中有挂载 cifs/smbfs/sshfs 的行为,其实这个时候磁盘还没有检查完,而且永远也检查不完,因为网络还没有启用,那些需要网络挂载驱动器的行为就陷入了永远的等待状态,昏死的设定。

显卡驱动安装参考

Openoffice.org 字体列表中不显示中文字体名称

只显示为英文,这个需要修改 /etc/environment

LANG="en_US.UTF-8"
LANGUAGE="en_US:en_GB:en"
LC_CTYPE="zh_CN.UTF-8"

如果输入法又变成 ibus,sudo im-switch -s fcitx 后重启 X 即可。openoffice 是根据当前环境来决定是显示字体的中文名称还是英文名称的。

Samba 共享中的 symbolic link 无法被访问

需要在 /etc/samba/smb.conf 中添加下面几句内容:

[global]
    follow symlinks = yes
    wide links = yes
    unix extensions = no

一点使用感觉

  • 很多操作都是在窗口模式下实现,反而用 cli 不知该怎么作了。
  • 易用性倒是好多了,却同时搞得一些复杂操作麻烦或者出问题了,比如 mysql 服务启动的问题,比如 fatab 里面加上个 sshfs 就无法启动的问题等等。

参考

WordPress 烦人的 revision 和 auto-draft

revision 是早就有了,auto-draft 是最近才发现的,个人非常不喜欢这2个功能,偏偏 WordPress 还没有在后台中增加显式的关闭功能,所以更显得烦人。

revision 是你每保存一次 post 的时候,都把修改前的内容存成一个 revision,这样你就不用担心以前的版本找不到了。问题是,写 blog 又不是写代码,用得着这把牛刀么?就是写代码,也有不想保存的版本,基本上扔到 scm 里面就不会再看了呀。

禁用 revision 的方法,对目前的 WordPress 3.0 有效,在 wp-config.php 中添加:

define('WP_POST_REVISIONS', false);
define('AUTOSAVE_INTERVAL', 60000);

同时也禁止了自动保存,多手工保存吧,或者本地写好了再 post 。

auto-draft 是这样出现的,当你 new 一个 post 的时候,以前是第一次保存的时候生成 id,现在则是打开 new 页面的时候就生成了,体现在数据库中 wp_posts.post_statusauto-draft。这种没有内容先保存的方法一般是用来避免多人同时保存时的写入数据冲突,可一般的 blog 会频繁产生这种情况么?更糟糕的是,auto-draft 类型的post 无法在 Posts 管理中进行编辑,也就是说如果你打开了 new post 页面,输入了一些内容,然后没有保存或者发布就离开了这个页面,那么数据库中就多了一条 auto-draft “僵尸记录”,你再也找不到它了。

auto-draft 目前好像没有方法关闭,但可以从数据库中把他们更改为 draft,以后当草稿修改成新文章就是了:

mysql> SELECT DISTINCT post_status, COUNT(1) FROM wp_posts GROUP BY post_status;
mysql> UPDATE wp_posts SET post_status='draft' WHERE post_status='auto-draft';

最后,贡献一个 php 脚本,自动把 revision 和 auto-draft 都修改成草稿 draft,并且找出数据库中不连续的 post id,把他们也都存成草稿,这样可以保持 url 中 id 的连续性,似乎更加美观和整洁。未经严格测试,请参考使用:

Apple Mail 邮件太多不下载问题的解决

Apple Mail version3.6(936)

原先拿到这个 mac 本本的时候,由于家中网速比较慢,收发邮件比较折磨人,而我又属于对邮件依赖较重的,所以专门申请了个新的 gmail 帐号,专门用在这个机器上,把邮件下载到本地便于处理(平时个人邮件都是自己发给自己的 N 个邮箱共享),顺便体验下 Apple Mail 软件。

Apple Mail 倒算是中规中矩,按下不表,中间有一段时间没怎么用这台 mac,而这个专用 gmail 帐号里面堆积的邮件应该也不少了,简单估计有几百封吧。终于,等到我想用的那一天,突然发现它不下载新邮件了。

逐项检查,系统和软件工作正常,网络正常,gmail 登录进去肯定是有新邮件,而且 pop 设置正常。所有的东西都没有动过,并且原先刚设置好这个帐号的时候,邮件下载都是正常的。Command+0 打开 Activity 窗口监视──连接、登录、查找新邮件、退出,貌似正常,但完全无视我邮箱中赫然在目的新邮件哪。

纯属无意中翻看 gmail 的在线帮助,其实对这类帮助并不报太大希望的,因为一般上面只有一些常规问题的答案,我的问题比较蹊跷,八成没有。帮助里面专门有针对 Apple Mail 3.0 Troubleshooting,列了几个问题,对照我的情况,逐个回答如下:

  • Have you recently used Gmail’s POP service with this client and address?
  • --> Yes, this address just worked recently
  • When are you encountering problems?
  • --> Downloading
  • Does your client display an error?
  • --> No, my mail client does not show an error
  • Downloading issues
  • --> Some or all messages don’t download

然后帮助给了4个解决方法,其中第2条是亮点:

Try enabling recent mode in your POP client by replacing 'username@gmail.com'
in the Username field of your POP client settings with 'recent:username@gmail.com',
and uncheck the box next to Remove copy from server after retrieving a message
in your Advanced POP client settings. Recent mode fetches the last 30 days of mail,
regardless of any other factors. If you don't Leave messages on server your 
messages will be moved to Trash after download.

看仔细了,在邮件帐户前面加上 recent:,只下载最近30天的邮件,这个以前没听说过,从之,我的邮件又愉快的下载了。至于30天以前的邮件如何下载,我是不需要了。至于为什么会这样,还真不明白是 gmail 这里有限制,还是 Apple Mail 无法读取30天以前邮件的邮件头导致无法下载,希望有明白人指点一二。

附 gmail 帮助截图为据:

Gmail帮助中关于Apple Mail的Troubleshooting

可恶,被 PHP-Mcrypt 的官方 Example 误导了

在看 php 的 mcrypt 加密,想使用对称算法,解决小块内容(比如 url、post)网上传输的安全性。即加密、解密用同一个密码。官方文档有个非常完整的演示功能的例子,大概顺序是:

  • 打开 module
  • 生成 IV
  • 得到 key/密钥/密码
  • 初始化(引擎?)
  • 进行加密操作
  • 关闭(引擎?)
  • 重新初始化(引擎?)
  • 进行解密操作
  • 关闭(引擎?)
  • 关闭 module

加密、解密放在了一个代码片段中,大概是想说,加、解密就那一句代码不同而已。

按照这个理解,为了使用方便,我把加、解密分解成了2个函数,内容都和例子差不多,不会有错。但一运行,不管用哪种加密算法,都会出现奇怪的解密后与原文不一致的错误。还不是完全不一致,后面大半段内容都是正确的,比如原文是包含 a-z 26个字母的字符串,运行结果如下:

$ ./mcrypt.php 
Encrypt:
M~<5¶¤Jw^TÝ×. ÃV¯
Decrypt:
Âò¹ÁIijklmnopqrstuvwxyz

好一通找原因,最后在支持算法列表页面中找到这么一句:The IV must be unique and must be the same when decrypting/encrypting.加、解密时所使用的 IV 必须相同。

昏,例子代码中 IV 是使用随机数生成的,分成2个函数之后,加、解密操作生成的 IV 肯定不一样,这就是解密失败的原因。mcrypt_create_iv() 函数文档页面的 user notes 中有位 Chris 还对 IV 纠正了一些错误观点。

综上,正确解密需要将 IV 与密文一同存储、传递。而我的需求比较简单,就没有必要这么作,反正 IV 也不需要保密,所以直接用 key 的 sha1 值的片断,比如前8位(与 git 版本号简写类似)作为 IV,对安全性影响不大,应该是可以接受的。

问题解决,收工,有和我一样吃过亏的同学么?