如何防止特定分支在git中合并?

时间:2018-10-24 11:45:09

标签: git githooks

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

随着时间的流逝,dev分支与master有所不同。另外,那里还有一些不正确的合并,使部分代码混乱。我们已经多次尝试将dev重置(强制推动)为与master相同。可以这么说,要重新开始。

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

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

3 个答案:

答案 0 :(得分:4)

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

当您尝试通过强制推动来重置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

答案 1 :(得分:0)

GitHub具有一项称为“受保护的分支”的功能,该功能使存储库管理员可以禁用强制推送到特定分支的功能。

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

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

答案 2 :(得分:0)

  

迟早有人将旧开发人员合并到新开发人员中,   支持一切。

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

git config pull.rebase interactive

git-config手册页中:

  

pull.rebase

     

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

     

preserve时,还将--preserve-merges传递给git rebase,因此   本地提交的合并提交不会通过运行而变平   git pull。

     

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

     

注意:这可能是危险的操作;除非您不使用它   了解其含义(有关详细信息,请参见git-rebase(1))。

这样,无论何时重写远程分支(使用push -f), 谁拉谁负责识别和删除“旧” 在重新设置期间提交。这样可以清除历史记录(即:否 在每个分支上合并“旧”版本。