迁了一下服务器,顺便弄了一下Git hook,把两个仓库给实现本地修改触发git hook实现服务器自动部署。
什么是git hooks
在git上是这么介绍的:
和其它版本控制系统一样,Git能在特定的重要动作发生时触发自定义脚本。有两组这样的钩子:客户端的和服务器端的。客户端钩子由诸如提交和合并这样的操作所调用,而服务器端钩子作用于诸如接收被推送的提交这样的联网操作。 你可以随心所欲地运用这些钩子。
个人理解的git hook其实就像一个触发器吧,当远程服务器收到本地的命令之后就执行某些操作。
git hooks的种类
git中,有两种类型的钩子:客户端的和服务器端的。
客户端的钩子有:
pre-commit
钩子在键入提交信息前运行。prepare-commit-msg
钩子在启动提交信息编辑器之前,默认信息被创建之后运行。post-commit
钩子在整个提交过程完成后运行。applypatch-msg
你可以用该脚本来确保提交信息符合格式,或直接用脚本修正格式错误。pre-applypatch
在git am
运行期间被调用post-applypatch
运行于提交产生之后,是在git am
运行期间最后被调用的钩子。pre-rebase
钩子运行于变基之前,以非零值退出可以中止变基的过程。post-rewrite
钩子被那些会替换提交记录的命令调用。post-checkout
在git checkout
成功运行后调用。post-merge
在git merge
成功运行后调用。pre-push
在git push
运行期间, 更新了远程引用但尚未传送对象时被调用。pre-auto-gc
会在垃圾回收开始之前被调用,可以用它来提醒你现在要回收垃圾了,或者依情形判断是否要中断回收。
服务器端的钩子有:
pre-receive
处理来自客户端的推送操作时最先被调用。update
它会为每一个准备更新的分支各运行一次。post-receive
在整个过程完结以后运行,可以用来更新其他系统服务或者通知用户。
如何使用git hooks
所有的钩子脚本都存放在 .git/hooks 文件夹中。当使用 git init
初始化一个新版本库时,Git 默认会在这个目录中放置一些示例脚本。这些示例的名字都是以 .sample 结尾,如果你想启用它们,得先移除这个后缀。
简单的自动部署
既然要在服务器上进行操作,肯定得登录服务器了咯。
服务器登录
要实现ssh免密码登录,大家也可以具体参考一下这篇文章
A为本地主机(即用于控制其他主机的机器) ; B为远程主机(即被控制的机器Server), 假如ip为172.24.253.2 ; A和B的系统都是Linux
在A上的命令:
$ ssh-keygen -t rsa (连续三次回车,即在本地生成了公钥和私钥,不设置密码)
$ ssh root@172.24.253.2 “mkdir .ssh;chmod 0700 .ssh” (需要输入密码, 注:必须将.ssh的权限设为700)
$ scp ~/.ssh/id_rsa.pub root@172.24.253.2:.ssh/id_rsa.pub (需要输入密码)
在B上的命令: $ touch /root/.ssh/authorized_keys (如果已经存在这个文件, 跳过这条)
$ chmod 600
/.ssh/authorized_keys (# 注意: 必须将/.ssh/authorized_keys的权限改为600, 该文件用于保存ssh客户端生成的公钥,可以修改服务器的ssh服务端配置文件/etc/ssh/sshd_config来指定其他文件名)$ cat /root/.ssh/id_rsa.pub » /root/.ssh/authorized_keys (将id_rsa.pub的内容追加到 authorized_keys 中, 注意不要用 > ,否则会清空原有的内容,使其他人无法使用原有的密钥登录)
回到A机器:
$ ssh root@172.24.253.2 (不需要密码, 登录成功)
这样就轻松实现了ssh免密登录
初始化
git init 和 git init –bare 的区别
初始化出来的仓库是不一样的,前者初始化的是一个普通的仓库,其中 .git 文件夹是隐藏的,并且能看见该仓库下所有的源码。而后者初始化出来的仓库中的文件,就是 .git 中的文件夹,但不能像前者那样直接浏览或修改仓库中的代码。
使用 git init --bare
初始化一个远程仓库
该仓库是用于项目部署的。在我们本地开发完成后,将项目push至该仓库后,将自动部署网站。
这里就拿nginx来举个例子,按照nginx默认目录来进行操作 建立一个xxx-bare.git(bare repository)和一个xxx(repository)目录,Git远程库的命名一般使用.git和其他目录区分,但并非强制。
$ cd /usr/share/nginx/html
$ git init --bare xxx-bare.git
$ cd /usr/share/nginx/html
$ git clone xxx-bare.git xxx
配置Git Hook
将目录切换至 /usr/share/nginx/html/xxx-bare.git/hooks
,如果目录下没有post-receive
这个文件,可以使用touch post-receive
直接创建,当仓库收到push请求后,就会自动执行该钩子中的脚本。根据自身需求编辑脚本内容:
#!/bin/sh
unset GIT_DIR
cd /var/www/html/project
git pull origin master
编辑完成后,给该脚本添加可执行权限
$ chmod +x post-receive
测试及使用
为开发的本地仓库添加remote源
这个客户端本地仓库,即开发的机子的本地仓库,添加remote源,以后往这个remote push代码时,就会自动触发上面的脚本。
$ git remote add deploy user@ip:/gitrepo_dir
$ git push deploy master
gitrepo_dir
就是服务器上的xxx-bare.git的文件夹位置
以后就可以通过git push deploy master
来自动更新服务器上的代码咯。
最后再写一个typecho的小坑
博客上传图片失败的问题,要把typecho里的usr文件权限修改为777,就可以了。
$ sudo chmod -R 777 usr
然后可以上传本地图片了。