背景描述
在刚开始用Git的时候,每次都是将本地将代码push到远程仓库,然后再ssh到服务器上git pull,甚是麻烦。后来在项目开发中使用git的时候,发现push之后,编译系统竟然会有自动部署等功能。顿时觉得这等神器,必须学习一下,所以就请教了吴旭东老师。下面就是我通过Git Hook神器将自己的项目自动化部署到服务器的过程。
自动部署理论
首先要明确现在代码的分布情况,开发者电脑上的本地仓库,git服务器上的远端仓库,web服务器上的另一个本地仓库,我们浏览器访问的就是这里的代码。其实自动部署就是要当从开发者本地仓库提交代码到远端仓库的时候,自动把代码部署到web服务器的本地仓库,实现开发者本地仓库和web服务器的本地仓库的同步。(即通过GitHook中的post-receive脚本文件)
安装过程
- 在服务器上创建一个裸仓库(git服务器上的远端仓库)首先要在服务器上建立一个裸仓库,我存放裸仓库的文件夹是/home/workspace/gitbook,进入到该文件夹,然后使用git init –bare springSummary.git创建裸仓库。
在服务器上创建一个普通Git仓库 - 在服务器上建立一个普通Git仓库用于存放网站的源代码。(web服务器上的另一个本地仓库)
mkdir /var/www/workspace cd /var/www/workspace git clone /home/workspace/gitbook/springSummary.git
- 配置Git Hook进入到/home/workspace/gitbook/springSummary.git/hooks文件夹,使用vi post-receive创建一个脚本,当你在本地仓库执行git push后就会触发post-receive。
post-receive的内容如下:#!/bin/sh #判断是不是远端仓库 IS_BARE=(git rev-parse --is-bare-repository) if [ -z "IS_BARE" ]; then echo >&2 "fatal: post-receive: IS_NOT_BARE" exit 1 fi unset GIT_DIR DeployPath="/var/www/workspace/springSummary" echo "===============================================" cd DeployPath echo "deploying the test web" #git stash #git pull origin master git fetch --all git reset --hard origin/master gitbook build sleep 15 time=`date` echo "web server pull at webserver at time:time." echo "================================================"
保存后赋予可执行权限:
chmod +x /var/www/workspace/springSummary/hooks/post-receive
这样在开发者提交代码的时候,就会自动部署。
在这里需要解释两个问题:
- 在这里第一个问题,因为我部署的是一个gitbook项目,所以需要额外在脚本中添加一行指令gitbook build,但是仅添加这一行的话会导致最后这个脚步执行失败,因为build需要大约8秒时间。所以我的解决方案是在脚本中添加sleep 15,这样可以等待build执行结束并把结果返回到显示的终端。(如果只是需要自动更新项目,请把这两行指令删去)
- 在这里我使用的是git fetch,为什么没有用git pull实现。区别在于:
- git fetch:相当于是从远程获取最新版本到本地,不会自动merge。
- git pull:相当于是从远程获取最新版本并merge到本地。
- pull实现相当于fetch后再用merge,来合并本地和远端的代码。
这里就有个问题,如果开发者在提交过程出现失误,使用git reset复位后,现在远端的代码版本低于web端的代码版本,再使用pull的时候就不能实现和开发者本地的代码的同步。所以这里使用fetch后,在强制使用reset实现web端的代码版本指针和git服务端的一致。(如果在本机可以使用stash,然后pull,然后drop刚才stash的内容)