git hook 自动部署

在进行以下操作时 一定要注意文件的权限问题,绝大部分的问题出现是由于文件权限的问题

在服务器端创建git仓库
第一步,安装git:
$ sudo apt-get install git
第二步,创建一个git用户,用来运行git服务:
$ sudo adduser git
第三步,创建证书登录:

收集所有需要登录的用户的公钥,就是他们自己的id_rsa.pub文件,把所有公钥导入到/home/git/.ssh/authorized_keys文件里,一行一个。

第四步,初始化Git仓库:

先选定一个目录作为Git仓库,假定是 /gitroot/52inlove.git, 在 /gitroot 目录下输入命令:

$ sudo git init --bare 52inlove.git

Git就会创建一个裸仓库,裸仓库没有工作区,因为服务器上的Git仓库纯粹是为了共享,所以不让用户直接登录到服务器上去改工作区,并且服务器上的Git仓库通常都以.git结尾。然后,把owner改为git

$ sudo chown -R git:git 52inlove.git
第五步,禁用shell登录:

出于安全考虑,第二步创建的git用户不允许登录shell,这可以通过编辑/etc/passwd文件完成。找到类似下面的一行:

git:x:1001:1001:,,,:/home/git:/bin/bash

改为:

git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell

这样,git用户可以正常通过ssh使用git,但无法登录shell,因为我们为git用户指定的git-shell每次一登录就自动退出。

在服务器初始化一个服务器本地的 Git 仓库

这个仓库就是通过 git init 初始化出来最常见的本地仓库,它的作用是拉去远程仓库(其实就在它旁边)最新的源码到网站的根目录。

git clone /gitroot/52inlove.git #从远程仓库 clone 出源码
为远程仓库(git服务器)设置 Hook
$ cd /gitroot/52inlove.git/hooks
#post-receive 这个文件可能不存在 新建即可
$ vim post-receive 
post-receive内容
#!/bin/sh
echo 'Hook is running'
unset GIT_DIR
NowPath=`pwd`
DeployPath="/webroot/52inlove"
cd $DeployPath
git stash
git fetch --all
git reset --hard origin/master
# git pull origin master 不用这个 应为会自动merge 一旦有冲突就会merge失败
sudo chown -R www-data:www-data /webroot/52inlove
cd $NowPath
echo 'Hook finishes !!! :)'
exit 0
phpstorm push结果如下
➜  52inlove.com git:(master) ✗ git add 'public/index.php'
➜  52inlove.com git:(master) ✗ git commit -m 'commit'
[master 5369f4d] commit
 1 file changed, 1 insertion(+), 1 deletion(-)
➜  52inlove.com git:(master) ✗ git push
Counting objects: 4, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (4/4), 336 bytes | 0 bytes/s, done.
Total 4 (delta 0), reused 0 (delta 0)
remote: Hook is running
remote: No local changes to save
remote: From /gitroot/52inlove
remote:  * branch            master     -> FETCH_HEAD
remote:    b9a1d62..5369f4d  master     -> origin/master
remote: Updating b9a1d62..5369f4d
remote: Fast-forward
remote:  public/index.php | 2 +-
remote:  1 file changed, 1 insertion(+), 1 deletion(-)
remote: Hook finishes !!! :)
To 52inlove.com:/gitroot/52inlove.git
   b9a1d62..5369f4d  master -> master
如果出现以下情况
remote: error: refusing to update checked out branch: refs/heads/master  

remote: error: By default, updating the current branch in a non-bare repository  

remote: error: is denied, because it will make the index and work tree inconsistent  

remote: error: with what you pushed, and will require 'git reset --hard' to match  

remote: error: the work tree to HEAD.  

remote: error:  

remote: error: You can set 'receive.denyCurrentBranch' configuration variable to  

remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into  

remote: error: its current branch; however, this is not recommended unless you  

remote: error: arranged to update its work tree to match what you pushed in some  

remote: error: other way.  

remote: error:  

remote: error: To squelch this message and still keep the default behaviour, set  

remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.  

To git@192.168.1.X:/var/git.server/.../gitroot  

! [remote rejected] master -> master (branch is currently checked out)  

error: failed to push some refs to 'git@192.168.1.X:/var/git.server/.../gitroot' 
解决方法

这是由于git默认拒绝了push操作,需要进行设置,修改.git/config文件后面添加如下代码:

[receive]  
denyCurrentBranch = ignore  
最后
  • 本地的工作环境 git remote 地址为 git@52inlove.com:/gitroot/52inlove.git
  • 将需要操作该仓库的用户的public ssh key 复制到服务器git用户家目录下的.ssh/authorized_keys
git将本地仓库上传到远程仓库
1. git init
2. git add .
3. git commit -am "###"      -------以上3步只是本地提交
4. git remote add origin git@xx.xx.xx.xx:repos/xxx/xxx/xxx.git
5. git push origin 本地分支:远程分支
Permission denied

到以下情况:

error: cannot open .git/FETCH_HEAD: Permission denied 
fatal: Unable to create '/gitroot/www/mood.52inlove/.git/index.lock': Permission denied
error: unable to unlink old 'app/Http/Controllers/Web/IndexController.php' (Permission denied)  

首先考虑权限问题 按以下方法操作试试

//一定要加 -a 不然会离开原有用户组
 usermod -a -G www-data git

//此处不一定要775 根据具体的文件的所需权限来定
 chmod -R 775 mood.52inlove/

git用户加入www-data用户组 (www-data根据具体情况定) 并保证组的权限足够