【问题标题】:How to prevent a specific branch from being merged in git?如何防止特定分支被合并到 git 中?
【发布时间】:2019-03-28 19:41:40
【问题描述】:

我们有一个 master 分支,用于发布的生产代码,一个 dev 分支,用于测试服务器的代码,以及每个开发人员认为合适的各种功能分支(从 master 分支)。

随着时间的推移,dev 分支与master 有所不同。此外,还有一些不正确的合并会弄乱部分代码。我们已经多次尝试重置(强制推送)devmaster 相同。可以这么说,重新开始。

不幸的是,这不会持续很长时间。迟早会有人将旧的dev 合并到新的dev 中,将所有的混乱都带回来。我怀疑这甚至可能自动发生,天真的 git pull 默默地合并新旧分支头。

是否可以通过服务器端提交挂钩来防止这种情况?如果合并了错误的提交,会拒绝接受 git push 的东西吗?

【问题讨论】:

  • “迟早会有人合并旧的开发......我怀疑这甚至可能会自动发生”。它本身不是 git,有人在做。如果您使用的是 github 或 gitlab,您可以保护您的分支 dev 直接推送,仅通过 Pull/Merge 请求合并分支。
  • 在 pre-receive 中搜索入站,如果看到任何不喜欢的内容,请拒绝推送。
  • 其实...我刚刚想出了一个更简单的想法——创建一个dev2 分支并将其用于测试服务器。这样,任何人都不会意外合并任何内容。

标签: git githooks


【解决方案1】:

Git Hooks 可以。将以下 POC 脚本放入您的远程(服务器端)存储库上的 .git/hooks/pre-receive 并授予其执行权限。

配置你要保护的分支,例如master

$ git config hooks.protected-branch.refs master

文件:.git/hooks/pre-receive

#!/bin/sh

read old_value new_value ref_name

refs=$(git config hooks.protected-branch.refs)

for ref in $refs; do
    if [ "$ref_name" == "refs/heads/$ref" ]; then
        if [ "$old_value" == "0000000000000000000000000000000000000000" ]; then
            continue
        fi

        if ! git merge-base --is-ancestor "$ref_name" "$new_value"; then
            echo "$ref_name is protected branch"
            exit 1
        fi
    fi
done

当你尝试通过 force-push 重置 master 时,你会得到类似这样的输出:

Counting objects: 12, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (12/12), 920 bytes | 153.00 KiB/s, done.
Total 12 (delta 4), reused 0 (delta 0)
remote: refs/heads/master is protected branch
To ../demo
 ! [remote rejected]   master -> master (pre-receive hook declined)
error: failed to push some refs to '../demo

【讨论】:

    【解决方案2】:

    GitHub 有一个称为受保护分支的功能,它使存储库管理员能够禁用强制推送到特定分支。

    除了阻止强制推送之外,受保护的分支还可以进行必要的状态检查。

    更多信息... 请查看https://blog.github.com/2015-09-03-protected-branches-and-required-status-checks/

    【讨论】:

      【解决方案3】:

      迟早会有人将旧开发者合并到新开发者中,从而带来 把它弄得一团糟。

      这是使用默认git pull 行为时的常见问题。到 避免它,可以将git pull 配置为使用rebase 通过 默认而不是merge。也就是说,将当前分支重新定位到 远程分支而不是合并它:

      git config pull.rebase interactive

      来自git-config 手册页:

      pull.rebase

      true 时,将分支重新设置在获取的分支之上,而不是 当“git pull”是时从默认远程合并默认分支 跑步。请参阅“branch..rebase”以在每个分支上进行设置 基础。

      preserve 时,也将 --preserve-merges 传递给 git rebase 所以 本地提交的合并提交不会通过运行而变平 git 拉。

      当值为interactive时,rebase以交互方式运行 模式。

      注意:这是一个可能很危险的操作;不要使用它,除非你 理解其中的含义(详见 git-rebase(1))。

      这样,无论何时重写远程分支(使用push -f), 谁拉谁负责识别和丢弃“旧” 在变基期间提交。这会产生一个干净的历史记录(即:没有 在每个分支上合并“旧”版本)。

      【讨论】:

        猜你喜欢
        • 2016-07-26
        • 1970-01-01
        • 2014-10-28
        • 2011-12-30
        • 1970-01-01
        • 1970-01-01
        • 2011-11-20
        • 2016-01-12
        • 2010-10-20
        相关资源
        最近更新 更多