emacs使用magit提交到gerrit

从好几年前我就开始一直使用git了,大部分的提交是在命令行下,反
正emacs的shell功能很好用,也从来没有想过安装插件什么的。

我也在用gerrit管理项目,大部分的时候,项目的.git/config的文件
里面都有这样的一段:

      [remote "origin"]
	url = xxxxx
	fetch = +refs/heads/*:refs/remotes/origin/*
	puttykeyfile = 
	push = HEAD:refs/for/master
       

关键是那个push, 可以让我在命令行下直接git push就push到了
refs/for/master分支上了,方便很多。

突然想在emacs中使用下版本管理,我可从来没用过呢。于是查看了下,
magit评价不错,就直接安装配置了下,具体可从https://github.com/magit/magit
看如何安装使用。

但安装完之后发现push的时候默认push的分支是
master:refs/heads/master,没发现特别的需要设置的地方(可能是我没仔
细看),如果不能push到refs/for/master的话,对我而言几乎毫无用途啊。
于是就直接修改下源代码了:

       magit.el | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/magit.el b/magit.el
index ae51473..89a6ad1 100644
--- a/magit.el
+++ b/magit.el
@@ -5422,9 +5422,11 @@ even if `magit-set-upstream-on-push's value is `refuse'."
                                         (eq magit-set-upstream-on-push 'askifnotset)))
                                (yes-or-no-p "Set upstream while pushing? "))))))
             (apply 'magit-run-git-async "push" "-v" push-remote
-                   (if ref-branch
-                       (format "%s:%s" branch ref-branch)
-                     branch)
+                   (cond ((magit-get "remote" push-remote "push")
+                          (magit-get "remote" push-remote "push"))
+                         (t (if ref-branch
+                                (format "%s:%s" branch ref-branch)
+                              branch))) 
                    (if set-upstream-on-push
                        (cons "--set-upstream" magit-custom-options)
                      magit-custom-options))
 
       

修改丑陋,能用就行,反正我对lisp基本上不懂。我的修改可从https://github.com/zeze0556/magit检出。

这样依赖,如果在config中配置了push的相关内容(比如文章一开始的
那个配置格式),就会push到指定的分支上,如果没有配置的话,按照默认
的来。

然后到了gerrit的页面一看,乖乖,中文怎么乱码了,看了下模式,是
在git-commit-mode下,然后编码居然是undeced-xxx的,虽然可以通过在
写完日志之后: C-x ret c utf-8-unix Alt-x git-commit-commit来操作,
但明显太烦人了,不过,幸好这个支持hook,于是就在配置中写下下面的
hookl:

      (defun my-git-commit-hook ()
  (auto-fill-mode)
 (flyspell-mode)
  (set-buffer-file-coding-system 'utf-8-unix))
(add-hook 'git-commit-mode-hook 'my-git-commit-hook)
       

这下子就默认以utf-8-unix的编码提交了,乱码什么的通通散去。

PS: 最近在尝试使用emacs的evil插件,现在稍微习惯些了,vim的快速
移动果然不是盖的,不过总在中文输入法什么的和快捷键上卡壳,有些时
候会和emacs的习惯冲突,慢慢锻炼吧。

一懒到底

今天在用rebar编程的时候,觉得每次都要rebar compile实在太烦,觉
得应该懒一些,就弄了一个快捷的方式,用了一下,觉得不错,以后自己
的每个项目里面都应该弄一个类似的配置文件,文件内容很简单:

       #!/bin/bash

alias m='./rebar compile'
alias r='rel/test_proj/bin/test_proj console'
alias e='cat < rel/test_proj/log/sasl-error.log'
alias c='git commit -m'
alias p='git push'
       

使用的时候,只用运行

       . ./env.sh
       

然后就可以通过m来编译,c来提交,r来运行等等等等了。

突然想起emacs的配置也更新了好多,但都没有提交,就顺便提交下吧。
检查一下,添加了很多文件,有些还是按照子模块的方式添加,每次都要
看每个如何编译实在太麻烦,既然今天要懒一次,就决定将这个也优化下,
变成一个可以自动化的内容。

首先是按照makefile的方式,因为反正配置是作为一个项目存放的,而
自己又离不开shell的环境,觉得应该哪个都有,以下是内容:

       EMACS ?= emacs
PWD = $(shell pwd)
PRE ?= $(PWD)
ELFILES = $(shell find . -type f -name \*.el ! -path '*/.*/*' -exec echo $(PWD)/{} \;)
ELCFILES = $(ELFILES:.el=.elc)
LIBS = $(shell find . -type d ! -path '*/.*/*')
.PHONY: all compile clean

all: ready compile

clean:
	find . -name \*.elc -exec rm -rf {} \;

ready:
	@echo "">env.el
	@for i in $(LIBS); do echo "(add-to-list 'load-path \"$(PRE)/$$i\")" >> env.el; done
	@$(EMACS) -Q --batch --no-site-file -f batch-byte-compile env.el

compile: $(ELCFILES)
	rm -rf env.el env.elc
$(ELCFILES): %.elc: %.el
	@$(EMACS) -l env.elc --batch --no-site-file -f batch-byte-compile $< || (echo "error" $<)

       

使用的方式也很简单,检出配置只有,make即可,在windows下使用
windows下的emacs.exe的时候,需要添加下PRE=C:/work/emacs_config的
类似定义,原因在于windows下的emacs.exe不能识别cygwin或者msys的
/cygdrive/c或者/c的路径方式。

事情本来到这里就结束了,结果老婆和我换电脑用下,我是编辑远程文
件,用哪个电脑无所谓的,结果安装了git之后,检出了配置,然后在git
的bash shell中运行make,发现竟然没有make,算了,还是写个shell的版
本好通用些:

       #!/bin/bash
emacs=$EMACS
echo "emacs=$emacs"
if [ -z "$PRE" ]; then
PRE=$PWD
fi
echo $PRE
ELFILES=`find . -type f -name \*.el ! -path '*/.*/*' -exec echo $PWD/{} \;`
LIBS=`find . -type d ! -path '*/.*'`
echo "">env.el
for i in $LIBS; do echo "(add-to-list 'load-path \"$PRE/$i\")" >> env.el; done
$emacs -Q --batch --no-site-file -f batch-byte-compile env.el
for i in $ELFILES
do
    $emacs -l env.elc --batch --no-site-file -f batch-byte-compile $i || (echo "error" $i)
done

       

顺便写个clean.sh:

       #!/bin/sh

find . -type f -name \*.elc -exec rm -rf {} \;
       

现在终于对环境的依赖几乎最小了。要获取配置,只需要安装git,然
后检出配置后,在git自带的shell中执行install.sh即可。

需要注意的内容:

1. 上述的编译,即使文件出现错误也会继续后续的编译,不会出现因
为编译错误中断,之所以这样设置是由于一些插件里面有平台的限制或者
判断,脚本只是尽可能的编译每一个脚本。

2. 一般情况下,我喜欢makefile的方式,因为如果文件没有发生更改
的话,makefile是不会再重新编译的,而在shell的方式下,是不理会这些
的。

改那个革

小时候坐火车的时候,从车窗外往外看别的火车,明明是别的火车在走,
总以为自己的再走。当然了,这是最基本的相对运行,但对于当时年龄很
小总是能忆起的一件事情而言,也算上了人生的第N堂物理课了。

从哪个时候起,我就知道了,如果自己原地踏步,别人就会追上你,超
过你,所以要不断的往前走。也同样知道了,如果方向不对,原地踏步在
别人眼里,就是在往前走。

也是从那个时候,在火车上玩,不管你再怎么往回走,都走不到当初出
发的那个站了。

纵观近日热论的中国梦,改革热,老路歪路之争,其核心无非是X党最
伟光正了,因此要准备好高呼好万岁了。

看古装电视剧,尤其是那个长长辫子的,看到天子总是呼万岁,其实,
所有人都知道,万岁是不存在的。”他们知道我们知道的,我们也知道他们
知道的,我们知道他们知道我们知道的,他们也知道我们知道他们知道的
“,但谁都不说,谁都揣着明白装糊涂。

回到改革的话题,当作为火车的政体不改革,一切的改革无非是在火车
仓里的游戏,或许看到有些许的进步,也仅仅相对于火车本身而已,这个
火车说不定只是在慢慢前进,也可能原地不动,也可能在后退,看你如何
选择参照物了。

不过,中国人的优良传统就在这里了,当你说他见识短的时候,他说他
头发长,当你说他长的衰时,他说他腰板好,总之,一切牛头不对马嘴。
当然,还有另外的一项优势,就是看到别家某项好,而自家某项不好又无
法做到的时候,就以国情论,如果自己可以通过不正当手段获取的话,则
以国际同规而论定。

不过,我无论如何也不能如某些人,动不动就13亿人,N千万头颅,全
中国人民,所以,上一段,不妨以我来代替了。

如此一来,人都是自私的,当革别人的命的时候,大呼过瘾,当革自己
的命的时候,高呼救命。

但若非自救,又有何人来救你呢?因此,我又早已对改革失去了信心。
没有了信心,一切便如佛随缘,但实则心不甘,只能抓紧时间努力往外跳,
在这期间,不妨用鸡蛋砸砸墙,说不定以后被我练成了暗器高手呢。

mnesia数据库index的选择

之前刚说了mnesia的一些经验,不想回头就犯错了。这里给自己提醒下。

对于下列的数据结构:

       -record(worker, {id,
                       name,
                       desc,
                       state}).
       

其中,id是唯一的,name可能会重复,但几率较小,state只有4种,
wait/doing/done/error,表示状态。

我在创建的时候,name作为第二个索引,id自然的成了第一索引,一切
都没有问题。最后数据量大约超过了N百万条。

然后,其他的逻辑流程出现了问题,state变为doing状态,没有正确切
换到其他的状态,这样,这个worker就一直处于doing状态,为了重置这些
状态,需要遍历所有的doing状态的worker,并且根据一个过滤列表,检查
后重置为其他的状态,比如done还是wait

我一次检查几百到几万条不等,为了加快速度,就手动的给worker的数
据库再添加一个索引:state,然后悲剧就发生了。

数据库变的非常非常的占用内存,超过几十GB了,虽然我虚拟内存有上
百GB,但也不能这么用啊,关键是,其他的进程对这一数据库的操作就会
变的非常的慢,而且,由于系统内存耗光,整个系统也非常慢。

其实,原因也很简单,问题就在于索引的选择上。对于mnesia而言,为
了加快读取,会对数据库遍历,根据索引生成对应的列表,这样,当每操
作一条数据的时候,就会更新索引,对于上述例子而言,根据state生成的
每个状态的列表元素的个数都是恐怖的,达到了上百万量,这样,当操作
数据的时候,每次都要遍历这些上百万个元素,效率就会非常的低,换言
之,state不适合做索引,而适合做分表

在索引选择上,每个属性对应的数据个数越少,越适合做索引,反之,
适合做分表。