这是一篇歪门邪道文章,不按常理走,不喜尽管喷。 这是一篇歪门邪道文章,不按常理走,不喜尽管喷。

一般来说将本地的代码推送到服务器的方式,都是在服务器的仓库用git init --bare初始化一个裸仓库,里面只有一些索引和版本信息,有关裸仓库的介绍请自行查找。我基本都是一个人用git,比如这个博客是基于hugo的,我想每次在本地用git push之后,服务器上能直接生效,相当于把仓库完全同步了。但是git initgit init --bare都不能直接这么做。

咋办呢?搜呗。在网上找到了关于git钩子的相关内容,大概就是在你git操作之后会执行你自己写的钩子,那就用这个了。

首先在服务器新建个仓库,而且要专门配置一下receive.denyCurrentBranch=ignore,不然你在本地push的时候会报remote: error: refusing to update checked out branch: refs/heads/master的错误,因为git push只允许推送到裸仓库,具体可以参考这个stackoverflow的回答

然后我们来写钩子脚本,有一些没卵用的例子在.git/hooks文件夹下,我们写的脚本也需要放在这里,因为我需要在服务器端写hook,所以对应的应该是写post-receive,这样就会在服务器接手之后执行该脚本

#!/bin/sh
GIT_WORK_TREE=$PWD git reset --hard
echo "ok"

然后执行chmod +x .git/hooks/post-receive 给它执行权限

最后一句ok没什么用,你写的操作会在客户端推送的时候执行并能看到结果,以remote开头就像这样

对象计数中: 3, 完成.
写入对象中: 100% (3/3), 225 bytes | 0 bytes/s, 完成.
Total 3 (delta 0), reused 0 (delta 0)
remote: HEAD 现在位于 4d0425f d
remote: ok
To 45.32.43.30:/home/www/a
   b861b71..4d0425f  master -> master

这样就搞定了,梳理一下流程:

服务器init空仓库 > 本地clone空仓库 > 本地添加修改仓库内容 > 本地add commit push > 服务器receive > 服务器看看有没有hook脚本 > 服务器执行post-receive脚本

整个下来之后,本地就和服务器有一模一样的仓库了,在某些场景下非常好用,比如微信开发时需要在本地写代码,但测试时必须要在配置的服务器上调试和测试,此时用这种方法只需要正常使用git控制版本,写完直接push就能看到代码修改后的效果了

最后贴个alias,这样每次在服务器新建个文件夹(仓库)直接执行ginit就搞定上述所有过程了

alias ginit='git init \
&& git config receive.denyCurrentBranch ignore \
&& echo -e "#!/bin/sh\nGIT_WORK_TREE=$PWD git reset --hard\n echo \"ok\"" > $PWD/.git/hooks/post-receive \
&& chmod +x $PWD/.git/hooks/post-receive'