我有一个想法,通过在 GIT 更新挂钩中设置一个锁定脚本来锁定用户将文件推送到其中的存储库,因为推送只能将用户 ID 识别为参数而不是分支。所以我可以锁定整个 repo,它只是锁定一个目录。
有没有办法锁定 GIT 中的特定分支?
或者有没有一种方法可以让更新挂钩识别用户从哪个分支推送以及代码被推送到哪个分支?
我有一个想法,通过在 GIT 更新挂钩中设置一个锁定脚本来锁定用户将文件推送到其中的存储库,因为推送只能将用户 ID 识别为参数而不是分支。所以我可以锁定整个 repo,它只是锁定一个目录。
有没有办法锁定 GIT 中的特定分支?
或者有没有一种方法可以让更新挂钩识别用户从哪个分支推送以及代码被推送到哪个分支?
被推送到的分支是更新钩子的第一个参数。如果您想锁定分支myfeature
以进行推送,此代码(放置在 中hooks/update
)将执行此操作:
#!/bin/sh
# lock the myfeature branch for pushing
refname="$1"
if [[ $refname == "refs/heads/myfeature" ]]
then
echo "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
echo "You cannot push to myfeature! It's locked"
echo "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
exit 1
fi
exit 0
来自文档的更新挂钩:
钩子对每个要更新的 ref 执行一次,并接受三个参数:
- 正在更新的 ref 的名称,
- 存储在 ref 中的旧对象名称,
- 以及要存储在 ref 中的新对象名。
所以......是的,它确切地知道正在推送哪个分支,并且如果它不希望将分支推送到,则可以简单地检查该参数并退出失败。
如果您想(智能地)在用户上传对象之前执行此操作,您可以使用 pre-receive 挂钩:
该钩子为接收操作执行一次。它不接受任何参数,但对于每个要更新的 ref,它会在标准输入上接收以下格式的一行:
<old-value>
SP<new-value>
SP<ref-name>
低频其中
<old-value>
是存储在 ref 中的旧对象名称,<new-value>
是要存储在 ref 中的新对象名称,是 ref<ref-name>
的全名。
(这些是空格和换行符)
我相信像 gitolite 这样的工具具有这种功能:http: //github.com/sitaramc/gitolite
您可以使用预提交来执行此操作。它有一个内置的no-commit-to-branch
钩子,可用于防止提交到一个或多个分支。
基本的设置过程是:
.pre-commit-config.yaml
文件(初稿见下文)pre-commit install
。这是一个仅包含no-commit-to-branch
钩子的基本配置:
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.2.5
hooks:
- id: no-commit-to-branch
args: ['--branch', 'master']
如果要保护多个分支,可以使用--branch
在参数列表中包含多个参数:
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.2.5
hooks:
- id: no-commit-to-branch
args: ['--branch', 'master', '--branch', 'staging']
Pre-commit 有许多其他内置钩子,以及大量社区构建的钩子,它们将改变您清理和验证提交的方式。我提到这一点的原因是,虽然这个工具对于防止提交到受保护的分支可能有点过头了,但它还有许多其他特性,使其成为任何 git 项目的引人注目且简单的补充。