Archive for the ‘git’ tag
惨痛教训一则
这几天都在装机器,开发机、测试机、测试服务器,费了不少时间。
代码原来就是在测试机上的,所以先git clone到开发机上来,然后把测试机重新格掉了,然后再clone回去。
然后发现我新写的代码都不见了,这才想起来那些代码都只是git stash掉,没有真正commit,所以clone的时候是没有备份的。
老老实实重新写了,又费了一个半小时。
吃一堑长一智。以后一定注意。
使用Git发送patch
以前我一直很土地手写patch邮件,今天Ian Campbell教了新招数,先记下来。Git的send-email可能要单独安装(我的Debian就是)。
首先要安装好MTA,我现在用的是exim,看自己喜好了。然后Git的配置文件要写好。
[user]
name = OOXX
email = XXOO
[sendemail]
smtpserver = SMTPSERVER
chainreplyto = false
signedoffcc = true
Patch要排版怎么办?没关系,用git format-patch。然后使用git send-email就OK了。
% git send-email $(git format-patch HEAD^..) --to XIAOMING --cc XIAOHONG --bcc XIAOFANG
注意由于前面signedoffcc设置的缘故,邮件会自动抄送patch里面所有sign off了的人。
慢着,写个Linux内核补丁,不知道该往哪发,怎么办?内核hacker们早就帮我们想好了。
% cd LINUX_KERNEL_DIR % ./scirpt/get_maintainer.pl PATH_TO_YOUR_PATCH
运行之后会出来一些地址,有list和maintainer,尽管发就好了。
Git让我不爽的一个地方
这一篇是凑数的,纯属吐槽。
我在看某个项目的代码,想了解一下这个项目是怎么一步一步发展起来的,所以希望从最高的一个commit开始看起,一直看到最新的commit。
可是Git不能很随意在历史里面切换,很怨念啊。Git一旦checkout一个commit之后,它的HEAD就指向这个commit,然后后面的log都没有了。想了再checkout下一个commit,还必须先checkout到master,然后再checkout想要的commit,太繁琐。现在想起SVN的好了。
UPDATE:
其实只要知道SHA值就可以直接checkout了,不一定需要切换到master的。我前面那样写是因为我不知道后面commit的SHA是什么。
可以用git log master查看master的log,这样就没必要再切来切去了。
谢谢iveney同学的帮助。
Git Supervisual Cheatsheet
http://panela.blog-city.com/git_supervisual_cheatsheet.htm
http://panela.blog-city.com/update_of_git_supervisual_cheatsheet.htm
Git忽略已跟踪文件的改动
我的Emacs配置文件已经放到github上面了,一方面记录更改,一方面也可以到处都可以下载来用。
目前我常用的机器上,都有一份dotemacs的clone。那么问题来了,假如对其中一个文件做了只适合本地的修改,那么commit就会把这些修改一起记录下来,然后push到github上面时,就会在各个系统之间的混乱。
因此我专门做了一个文件放在init-files里面,命名为99local-conf.el,最后才加载之。我想达到的效果是,在仓库里面做一个空文件来占位,但是每次提交时却不提交这个文件的修改。
gitignore只能忽略那些原来没有被track的文件,所以修改.gitignore是无效的。
正确的做法是在每个clone下来的仓库中手动设置不要检查特定文件的更改情况。
% git update-index --assume-unchanged /path/to/file
缺点就是每个新的仓库都必须手动设置一次。幸运的是,这样的设置每个仓库只要进行一次就够了。
Git实践小记
从我使用Git与@liuhui998翻译Git Community Book的实践来看,Git是一个非常强大的工具。但是光有好工具是不够的,必须有好的工作流才可以保证协作的顺畅。
事出有因。我从liuhui998的仓库fork出来一份,然后开始翻译。刚刚开始在翻译的时候,我使用了一个分支liuw,然后在翻译完成之后,把liuw合并到master中去,然后push到github,再由liuhui998来pull。
liuhui998 pull了之后,也push到了他的github仓库。但是后来他觉得这样的分支结构有点乱,所以做了一个rebase操作。这下出问题了,rebase操作令得同样的commit有了不同的SHA1 ID,我在从他那里pull的时候,发现不能再进行fast-forward合并了。Progit中提到,“永远不要衍合那些已经推送到公共仓库的更新”,而liuhui998恰恰做的就是这样一件事。
在rebase之后,同样的commit内容有了不同的ID,所以在我pull回来的仓库中会出现两次,浪费空间。然后整个工作树也被搞得很难看。
当然,这也有我的一份责任,我在push之前,应该先把分支清理一下,自己先rebase好。
问题搞明白了就好办了,现在liuhui998的版本是最干净的,所以我直接采用他的版本就OK了。下面的upstream是liuhui998的github仓库,origin/master就是我的github仓库。
$ git reset --hard 5b9d65 # 回退到没有出问题的commit $ git pull upstream master ... 可以直接fast-forward ... $ git push --force # 改写origin/master,因为远程仓库原来被我搞乱了
很多东西,真是“纸上得来终觉浅,绝知此事要躬行”,看书都看到了,就是没有实际去做,也没有这个意识。
以后要养成好习惯,一是在发布自己的commit之前先进行清理,二是不要轻易rebase已经发布的commit。
http://www.kernel.org/pub/software/scm/git/docs/git-rebase.html 有提到 RECOVERING FROM UPSTREAM REBASE。
Git and Mercurial
I use Git and Mercurial. Take a note on some of my configurations.
Git is configured via git(1) command. Configurations eventually go into .gitconfig, which can be edited by hand.
# note "--global" means per user # system wide setting is set with "--system" # if cd into project dir and without "--global", settings will be in project scope $ git config --global user.name 'Wei Liu' $ git config --global user.email liuw@liuw.name # if use windows, better set $ git config --global core.autocrlf true $ git config --global core.safecrlf true
Mercurial is configured via ~/.hgrc or project specified .hgrc.
[ui] username = Wei Liu <liuw@liuw.name>
As far as I can see, Git is more powerful while Mercurial is easier to use. There’s still more to learn about DVCS. Some interesting stuffs:
http://www.python.org/dev/peps/pep-0374/
This article provides several usage scenarios on several VCS, quite useful to green hand like me.
http://code.google.com/p/support/wiki/DVCSAnalysis
Google’s analysis of Git and Mercurial. But I got the sense that the reviewer’s biased towards Mercurial. Anyway, Google is a Python company.