2013年3月6日星期三

Git仓库的体积问题

我用git-filter-branch(1)手册中的方法:
git filter-branch --subdirectory-filter foodir -- --all
把Git仓库中的一个目录独立成一个新的Git项目。发现项目的.git目录没变小太多。原项目:
$ du -sk .git
55332 .git
新项目:
$ du -sk .git
49792 .git
新项目其实代码和历史都不多。我做过一次相同的事情,新项目会显著变小。我猜测是不是推到Git服务器上后会自动压缩,去掉历史里面无关的内容。于是我把内容推到GitLab(3.1版,后台是Gitolite管理),再clone下来,果然变小了很多:
$ du -sh .git
268K .git
我到服务器上检查,服务器上的仓库目录也压缩了。
所以git-filter-branch之后不用担心体积大小,放到服务器上会自动压缩的。

2013年3月1日星期五

Gitlab:缺乏工程性的项目

GitLab是一款界面类似GitHub的Git管理软件。虽然很强大,但是在工程性上欠佳。

GitLab的开发很快,也很流行。到官方博客去看,差不多一个月一个小版本,几个月就出一个大版本。3.0还是去年10月发布的,现在master分支已经是针对5.0的了,应该很快就要发布了。这些大版本都有重大的不兼容引入。

4.0前,仓库是在一个名字空间内。4.0开始,仓库是按用户名来区分的,类似GitHub的user/repo的命名方式。这和之前版本的用法是不兼容的。如果用户不想用这种用户名区分的仓库命名方式,想安装去年11月发布的3.1,就不能按照官方给出的文档地址来安装。因为这个是stable分支,现在指向的是4-1-stable,我们需要切换到3.1分支的文档来参考安装。

仅仅3月多月前的稳定版都没有一个正确的安装文档。这个文档里面init script和Nginx配置文件的地址分别是:https://raw.github.com/gitlabhq/gitlab-recipes/master/init.d/gitlab和https://raw.github.com/gitlabhq/gitlab-recipes/master/nginx/gitlab。master分支已经针对5.0了,和3-1-stable不兼容。gitlab-recipes这个项目没有针对3.1的分支。怎么办呢?我只好按照GitLab 3.1的发布日期2012年11月22日,去找到gitlab-recipes最接近那天的版本,下载这个版本的配置文件。

从4.1版本开始,GitLab的作者已经全职开发GitLab。充足的时间让这款软件的演进速度很快,但由于作者更专注于新功能的开发,而忽略了维护工作,导致文档缺乏,没有一个长期支持的稳定版本,缺乏对发行版本生命周期的管理。

GitLab一直依赖他们fork的Gitolite。5.0开始,将不依赖Gitolite,而用他们自己开发的GitLab Shell来管理仓库。有用户提出,之前GitLab宕了Git仓库还能访问(Gitolite是独立的);这样改动后,GitLab如果宕了整个Git仓库就不能访问了。

此外,GitLab安装过程繁琐,容易出错,而目前没有打包好的安装包。我觉得这对推广软件是很重要的,但貌似作者并不重视发行渠道。

根据我安装GitLab的经历,我觉得目前的GitLab还不太适合企业里面全面推广和长期部署。

2013年2月25日星期一

Ruby的psych错误

按照官方文档安装GitLab,执行有些命令时会出现如下警告:
It seems your ruby installation is missing psych (for YAML output).
To eliminate this warning, please install libyaml and reinstall your ruby.
我觉得这只是个警告,就没有处理。而且按照上面的说明,只是用于YAML输出的,应该没有大问题。

后面执行这一步
sudo -u gitlab -H bundle exec rake gitlab:setup RAILS_ENV=production
出了这样的错误。我没有处理,继续按后面的步骤操作。安装完后,GitLab的网页可以打开,但是用LDAP认证登录是出现类似错误:
Could not authorize you from Ldap because "Can't dump anonymous class class".
GitLab诊断文档说这个错误出现是因为没有用Ruby 1.9.3,可我是新装的Ruby 1.9.3啊。在这个issue里面发现我的错误与一开始被我忽略的psych错误可能有关,需要先解决psych的错误。

按照这个方法重新安装Ruby之后还是有错。后来觉得这个答案更适合我的情况,可还是未能解决。折腾了多次后无解,我觉得我的Ruby环境已经被搞乱了,决定按照GitLab的安装文档从头安装一遍Ruby。

最终通过重新安装Ruby解决了上述错误。至于Ruby没有psych的原因,是我犯错误没有执行其中一条安装依赖的命令(我看到公司Wiki上有人贴的过程说没有执行这步也可以,而实际是我看错了,他是执行了这一步的):
sudo apt-get install -y build-essential zlib1g-dev libyaml-dev libssl-dev libgdbm-dev libreadline-dev libncurses5-dev libffi-dev curl git-core openssh-server redis-server postfix checkinstall libxml2-dev libxslt-dev libcurl4-openssl-dev libicu-dev
其中的libyam-dev没有安装,就导致Ruby没有了YAML的输出功能。

2013年2月5日星期二

SSH公钥认证的问题

在Gitolite上配置了公钥,对应的私钥放在用户A的.ssh目录下可以认证,而用户B的目录下认证则失败。区别在于用户A的.ssh目录下只有私钥id_rsa,而用户B的目录下除了私钥,还有一个老的公钥id_rsa.pub,这和私钥是不配对的。

经过对比,这俩用户下的私钥是一模一样的,.sshid_rsa的权限也都是正确的。

ssh-v参数,看到这两个用户的公钥认证的输出信息稍微有所不同。用户A的:
debug1: Next authentication method: publickey
debug1: Trying private key: /home/userA/.ssh/id_rsa
debug1: read PEM private key done: type RSA
debug2: we sent a publickey packet, wait for reply
debug1: Authentication succeeded (publickey).
用户B的:
debug1: Next authentication method: publickey
debug1: Offering RSA public key: /home/userB/.ssh/id_rsa
debug2: we sent a publickey packet, wait for reply
debug1: Server accepts key: pkalg ssh-rsa blen 279
debug2: input_userauth_pk_ok: fp ef:a2:55:bc:86:1f:0a:48:e1:45:fc:b5:da:ca:70:e0
debug1: read PEM private key done: type RSA
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password,keyboard-interactive
debug1: Trying private key: /home/userB/.ssh/id_dsa
用户A开始打出的是:Trying private key,而用户B打出的是:Offering RSA public key

最后实在看不出配置哪里有不同,就把用户B下面不相关的公钥id_rsa.pub移出去,然后认证成功了。因为我认为公钥不重要,认证看的是私钥,所以没有管那个无效的公钥。结果罪魁祸首竟然就是这个无关的公钥。

看来OpenSSH如果看到公钥文件名,则从公钥检查起,而这样不配对的私钥就认证失败了。而如果只放私钥,反而会成功。从这个文件里面也能验证这一点。

2013年1月28日星期一

Zip压缩包乱码的处理

别人用Windows发过来的Zip压缩包,用unzip命令解压缩后是乱码的,也是编码问题。用如下命令即可:
unzip -O gbk foo.zip
RAR压缩包乱码处理方式在此

2012年12月6日星期四

终端神秘退出

这几天我的GNOME Terminal有时在敲命令时会退出。今天发现,在输入完命令和空格再按Tab后就会退出。这个问题必须要解决,否则根本无法正常工作。
  • 起初怀疑是GNOME Terminal更新中引入的bug,Google了一下没有相关的结果。
  • 我试验了Teminator和XTerm,也都有同样的问题。
  • 怀疑GNOME的快捷键设置出问题了,把Tab按键映射成了Ctrl-D。但是在Vim或者Gedit里面,Tab是可以正常输入的。
  • 重启了电脑,问题还是有。怀疑是不是本机Readline的设置有问题。登录到服务器上没有这个问题。证明了是本地的问题。
打开.bashrc看,最底下是最近加的一行:
set -e
为什么加这行呢?set -e是让Bash遇到错误(命令返回值非0)就退出,我一般在写Bash脚本的时候在最前面加上这一句。后来我想在.bashrc里面加上,以后的脚本不是都不用加了吗?没有多思考就加上了,结果导致了终端神秘退出的问题。

把这一行注释掉问题就解决了。那为什么按Tab会出错呢?在Bash里面输入:
set -x
输入命令和空格后再按Tab,就会输出Bash补全的很长的输出:
$ a + local compdir=./completions
+ [[ /usr/share/bash-completion/bash_completion == */* ]]
+ compdir=/usr/share/bash-completion/completions

.......
在Bash设置了set -e的情况下,应该是中间有一条命令的返回值非0,所以导致Bash退出了。

由此看来,set -e是根本不能放在.bashrc里面的,否则无法交互使用终端了。需要单独写在脚本里面。另外,set -ex是调试Bash脚本很方便的东西,可经常使用。

2012年12月2日星期日

Android下的自由软件

智能手机和传统的计算机一样,有着各种各样的病毒、流氓软件、窃取用户隐私的软件。也和计算机一样,使用自由/开源软件可以保证这些软件让用户绝对放心。

因为苹果的iOS AppStore的用户许可和GPL的许可不兼容,或者说苹果公司对自由软件很不友好,所以我只对Android下的自由软件感兴趣。

Google Play商店并不提供按照许可来搜索应用,所以我以前搜索的方法比较土,就是搜索github, open source, sourceforge等这样的关键词,来找找自由软件。比较经典的自由软件有ConnectBot,现在越来越多了,比如Firefox, FB Reader。维基百科上有一个页面,列出了Android下的自由软件,还有F-Droid网站AOpenSource网站,上面也都是Android下的自由软件。