有个需求是git 代码服务器不对开发人员开放ssh 登录管理权限,并且master 分支只能接受fast forward 提交(只能向前提),不能强制覆盖master 分支,以防意外删除或者破坏master 分支的代码。
如果只是这个需求,在git 服务器上做如下配置即可:
git config --system receive.denyNonFastForwards true
但是这个配置也会影响到各个开发者自己的开发分支,也无法强制覆盖,导致有时和master 同步的时候很不方便;查了一下资料,需要用git hook脚本来解决:
参考资料:
https://git-scm.com/book/zh/v2/%E8%87%AA%E5%AE%9A%E4%B9%89-Git-Git-%E9%92%A9%E5%AD%90
另外查了资料,找了一个参考代码:
做了一下修改,修改如下,经验证可以正常使用满足上面需求,贴出来,供需要的人员参考:
#!/bin/sh
#
# A hook script to block non-fast-forward updates for branches that haven't
# been explicitly configured to allow it. Based on update.sample.
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
#
# --- Command line
refname="$1"
oldrev="$2"
newrev="$3"
# --- Safety check
if [ -z "$GIT_DIR" ]; then
echo "Don't run this script from the command line." >&2
echo " (if you want, you could supply GIT_DIR then run" >&2
echo " $0 <ref> <oldrev> <newrev>)" >&2
exit 1
fi
if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
echo "Usage: $0 <ref> <oldrev> <newrev>" >&2
exit 1
fi
# --- Check types
# if $newrev is 0000...0000, it's a commit to delete a ref.
zero="0000000000000000000000000000000000000000"
if [ "$newrev" = "$zero" ]; then
newrev_type=delete
else
newrev_type=$(git cat-file -t $newrev)
fi
# branch
branch=${refname##refs/heads/}
case "$refname","$newrev_type" in
refs/tags/*,commit)
# un-annotated tag
;;
refs/tags/*,delete)
# delete tag
;;
refs/tags/*,tag)
# annotated tag
;;
refs/heads/*,commit)
# git rev-list doesn't print anything on fast-forward updates
if test $(git rev-list "$newrev".."$oldrev"); then
echo $branch, $newrev, $oldrev
if [ "$branch" == "master" ]; then
echo "hooks/update: Non-fast-forward updates are not allowed for branch $branch"
exit 1
fi
fi
;;
refs/heads/*,delete)
# delete branch
if [ "$branch" == "master" ]; then
echo "can't delete branch: $branch"
exit 1
fi
;;
refs/remotes/*,commit)
# tracking branch
;;
refs/remotes/*,delete)
# delete branch
if [ "$branch" == "master" ]; then
echo "can't delete branch: $branch"
exit 1
fi
;;
*)
# Anything else (is there anything else?)
echo "hooks/update: Unknown type of update to ref $refname of type $newrev_type" >&2
exit 1
;;
esac
# --- Finished
exit 0
以上文件放到 git server的代码 proj.git/hooks/ 的update 文件里面,并且chmod +x update 使其可执行
另外如果需要对多个branch做non-fast-forward限制,可以用参照
对该git库做局部server 的branch配置,具体如下
A. 在server 上cd your-prj.git
B. 对需要限制的branch进行配置:
git config --bool hooks.branch.Your-Branch.denyNonFastForwards true
C. 在 $branch" == "master" 地方修改为如下
deny=$(git config --bool hooks.branch."$branch".denyNonFastForwards)
if ["$deny" == "true"]; then
....
以上,供需要的朋友参考。
2019.8.8