54

我有一个想法,通过在 GIT 更新挂钩中设置一个锁定脚本来锁定用户将文件推送到其中的存储库,因为推送只能将用户 ID 识别为参数而不是分支。所以我可以锁定整个 repo,它只是锁定一个目录。

有没有办法锁定 GIT 中的特定分支?

或者有没有一种方法可以让更新挂钩识别用户从哪个分支推送以及代码被推送到哪个分支?

4

4 回答 4

50

被推送到的分支是更新钩子的第一个参数。如果您想锁定分支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
于 2011-07-26T08:06:49.947 回答
10

来自文档的更新挂钩:

钩子对每个要更新的 ref 执行一次,并接受三个参数:

  • 正在更新的 ref 的名称,
  • 存储在 ref 中的旧对象名称,
  • 以及要存储在 ref 中的新对象名。

所以......是的,它确切地知道正在推送哪个分支,并且如果它不希望将分支推送到,则可以简单地检查该参数并退出失败。

如果您想(智能地)在用户上传对象之前执行此操作,您可以使用 pre-receive 挂钩:

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

<old-value>SP <new-value>SP<ref-name>低频

其中<old-value>是存储在 ref 中的旧对象名称,<new-value>是要存储在 ref 中的新对象名称,是 ref<ref-name>的全名。

(这些是空格和换行符)

于 2010-03-18T16:07:52.813 回答
7

我相信像 gitolite 这样的工具具有这种功能:http: //github.com/sitaramc/gitolite

于 2010-03-18T16:24:34.603 回答
3

您可以使用预提交来执行此操作。它有一个内置的no-commit-to-branch钩子,可用于防止提交到一个或多个分支。

设置

基本的设置过程是:

  • 使用 pip 或 brew 安装(https://pre-commit.com/#install上的说明)
  • 在项目的根目录中创建一个.pre-commit-config.yaml文件(初稿见下文)
  • 通过运行将钩子安装到您的 git 配置中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 项目的引人注目且简单的补充。

于 2020-03-19T17:12:18.187 回答