git hook
一般来说,在服务器部署的时候不建议在网站的根目录建立远程仓库,一是处于安全考虑,二是以下情形:因为当用户A正在服务端master1分支上操作,此时用户2从本地push到master1分支会产生矛盾。解决办法就是使用git init –-bare
方法创建一个裸仓库,然后再使用git hook
将工作目录(working tree
)设置为网站根目录。
git init 和 git init –-bare 的区别
之所以叫裸仓库是因为这个仓库只保存git历史提交的版本信息,而不允许用户在上面进行各种git操作,如果你硬要操作的话,只会得到下面的错误(”This operation must be run in a work tree”);所以该版本库不能称为工作目录(working tree);
首先,我们要通过 git init --bare
初始化一个远程仓库
cd ~
$ mkdir npubbs
$ cd npubbs
$ git init --bare
建立本地仓库
这个仓库就是通过 git init
初始化出来最常见的本地仓库,它的作用是拉去远程仓库(tong一目录)最同新的源码,然后在本地仓库里进行操作,把代码钩到网站根目录)。
$ cd ~
$ mkdir npubbs-local
$ cd npubbs-local
$ git clone ~/npubbs #从远程仓库 clone 出源码
为远程仓库设置 Hook
$ cd ~/npubbs/hooks
$ vim post-receive
修改在 post-receive
里面的执行脚本,设置工作目录(working tree)为网站根目录
git --work-tree=/var/www/npubbs --git-dir=/home/bbsdev/npubbs checkout -f
#/var/www/npubbs为网站根目录
echo "-*- git checkout to /var/www/npubbs -*-"
最后,为post-receive
添加可执行权限
chmod +x post-receive
添加 remote 源
在开发端,为原有 Git 项目里面添加一条新的 remote 源,往这个 remote 源里面 push 代码,就会自动触发git hook
的脚本。
$ git remote add deploy user@server.ip:/home/bbsdev/npubbs
$ git push deploy master
对了,记得初学的时候手残在根目录建了本地仓库,这种情况直接在该目录rm -rf .git
即可。
学习心得
版本控制我在学校管理BBS的时候就已经很熟悉,但是上次思沃大讲堂发现同事们有很多比我更深入的理解,所以分享一下我新学到的东西;
Git 的三种状态
Git 系统上的文件有三种状态已修改(modified)和已暂存(staged)、已提交(committed)。
已修改表示修改了文件,但还没保存到数据库中。
已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。
已提交表示数据已经安全的保存在本地数据库中。
merge和rebase的区别
git merge 会生成一个新得合并节点,保留原始分支情况,而rebase不会
比如:
D---E test
/
A---B---C---F master
使用merge合并, 为分支合并自动识别出最佳的同源合并点:
D--------E
/ \
A---B---C---F----G test, master
而使用rebase则不会保留原始的分支情况,直接线性合并:
A---B---D---E---C'---F' test, master
使用git pull时默认是merge, 加 --rebase参数使其使用rebase方式
git pull --rebase
大家都推荐rebase
,因为线性更直观
新学的指令
git diff # 显示所有未添加至index的变更
git diff --cached # 显示所有已添加index但还未commit的变更
git whatchanged # 显示提交历史对应的文件修改
git show-branch # 图示当前分支历史
git show-branch --all # 图示所有分支历史
git stash list # 查看所有暂存