有没有一种方法可以在GIT中锁定一个分支?

59

我有一个锁定Git仓库的想法,可以在GIT更新钩子中使用锁定脚本来阻止用户将文件推入其中,因为推送只能识别userid作为参数而不是分支。因此,我可以锁定整个仓库,也就是锁定一个目录。

是否有一种方法可以锁定Git中的特定分支?

或者,是否有一种方法可以让更新钩子识别用户正在从哪个分支推送代码以及向哪个分支推送代码?


1
你想永久锁定分支名称(使用标签),还是只是防止其他人向其推送? - hasen
请参见https://dev59.com/gG435IYBdhLWcg3w-1Z_#5097437。 - VonC
把代码放在单独的仓库里,然后拉取到主仓库有什么问题吗?这是更标准的工作流程。 - Asclepius
4个回答

52

被推送的分支是update hook的第一个参数。如果你想锁定名为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

2
我在 GitHub 上的远程仓库中没有看到 .git 目录,只有在本地克隆的仓库中才有。但是我不认为将此代码放入本地仓库中的 .git/hooks/update 中会锁定其他人从其本地仓库推送到该远程分支的效果。我是否漏掉了什么? - Ajoy Bhatia
1
@AjoyBhatia 必须有一个 .git 目录。如果它是一个裸仓库,那么主目录已经是 .git 目录了。(如果你有像 HEAD、branches、hooks、config 等文件/文件夹,则它是一个裸仓库。)将你的 hook 放入 hook/ 目录中。 - 0xpentix

10
更新钩子(update hook),来自文档:

该钩子对于每个要更新的引用执行一次,需要三个参数:

  • 正在更新的引用名称,
  • 存储在引用中的旧对象名称,
  • 将存储在引用中的新对象名称。

所以……确实,它知道正在推送哪个分支,并且可以简单地检查该参数并在不想将分支推送到时失败退出。

如果您想要在用户上传对象之前(聪明地)执行此操作,则可以使用pre-receive钩子:

该钩子对于每个接收操作执行一次。 它不需要参数,但对于要更新的每个引用,它会在标准输入上接收格式为以下一行的行:

<old-value> SP <new-value> SP <ref-name> LF

其中<old-value>是存储在引用中的旧对象名称,<new-value>是要存储在引用中的新对象名称,而<ref-name>则是引用的完整名称。

(这些是空格和换行符)


这份信息确实对我有所帮助,但是更新钩子只知道正在推送的分支(源分支),有没有一种方法可以从更新钩子中捕获代码将要推送到哪个分支(目标分支)? - Senthil A Kumar

7

3
你可以使用 pre-commit 来实现此功能。它内置了 no-commit-to-branch 钩子,可用于防止将提交推送到一个或多个分支。
设置步骤如下:
  • 使用 pip 或 brew 进行安装(安装说明请访问 https://pre-commit.com/#install
  • 在项目根目录下创建一个 .pre-commit-config.yaml 文件(如下所示)
  • 运行命令 pre-commit install 将钩子安装到你的 git 配置中。
以下是保护分支的基本配置:
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项目中引人注目且简单易用的补充。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接