强制分支在合并和推送之前进行重新分配

时间:2017-06-12 13:02:06

标签: git gitlab

我想在我的Gitlab服务器上添加一个钩子,以防止在master之前推送合并的分支,如果它们之前没有重新绑定。

例如: A---B---C---D ← master \ E---F---G ← new-feature

我希望用户在合并/推送之前重新定义他的功能。 A---B---C---D-------------H ← master \ / E'---F'---G'

我不希望这被推 A---B---C---D---H ← master \ / E---F---G

这是一个良好的开端,但我并不认为只是拒绝不清空合并提交: Force Feature Branch to be Rebased Before it is Merged or Pushed

3 个答案:

答案 0 :(得分:2)

绝对可以,但你需要编写一些代码。您还必须确定精确定义“良好”提交图更新的内容。您的示例说明了要求:

o--o--o--*   <-- master

到此:

o--o--o--*---o   <-- master
    \       /
     o--o--o

将被拒绝,而这个:

o--o--o--*---------o   <-- master
          \       /
           o--o--o

将被接受。但是第三种选择呢?

o--o--o--*------o-----o   <-- master
          \    /     /
           o--o--o--o

这增加了两个合并而不仅仅是一个;但没有 new commit的合并具有任何父级,它是master的先前值的祖先。

那么呢?

o--o--o   <-- master

(此处推送已移除以前是master提示的提交。)

如果第二次推送,即添加两次合并,但没有一次返回任何早期提交,则被接受,最后一次推送也不是要被接受,你的任务的一部分很简单:你想要允许最多一次合并,或许将其限制为两个父母中的一个父母中的一个 - 也许这甚至必须是“第一个父母” - 具有先前价值master(标记为*的提交)。你的任务的其余部分可能是允许 no 合并,只要建议的新master不是旧master的祖先(没有提交将是去除)。

如果第二个(双合并)推送 被接受,则编码将更加棘手。请注意,如果它不被接受,有人仍然可以推送这样的合并,他们只需要在多个步骤中进行(每次合并一次)。

答案 1 :(得分:2)

强制重新定位的通常原因是对合并提交的病态仇恨,因为设置策略的人看不到它们的价值。目前尚不清楚为什么你想要克服rebase的缺点(中间提交不会经过测试的几率)但仍然有合并;在我看来,这可能是最不值钱的合并提交。但如果你必须......

你暗示你想接受的合并将是“空的”;这不完全正确。它将更改应用于其第一个父级(但不应用于其第二个父级,因为如果允许的话,它将是快进的)。

我认为你真的说的是,如果可以从第二个父级访问第一个父级(通过父指针),则接受合并。所以你可以得到

的输出
git rev-list --merges $oldrev..$newrev

并将每个生成的提交ID作为 commit-ID 参数提供给

git merge-base --is-ancestor commit-ID^ commit-ID^2

如果merge-base命令返回非零值,则拒绝。

(从技术上讲,我猜你可能也想确保提交没有3个或更多的父母。)

仍然允许这样的事情

     (origin/master)
            |
x -- x -- x -------------------- M <--(master)
           \                    /
            x -- x -------x -- x
                  \      /
                   x -- x

如果避免这是一个规则,那就更难了;你基本上希望通过头部提交的第一个父指针可以访问每个合并。 (但你不能只是说合并应该从头部提交的第一个父级可以到达,因为那样你仍然允许

     (origin/master)
            |
x -- x -- x -------------------- M -- x<--(master)
           \                    /
            x -- x -------x -- x
                  \      /
                   x -- x

这是同样的事情。)所以你可以在开始寻找合并之前作为“第一步”,做一个

git rev-list --first-parent $oldrev..$newrev

并挂起返回的所有提交ID值的列表,以便在您找到每个合并时确认它在该列表中。

如果这一切听起来都没有乐趣,我完全同意;这就是为什么我不会尝试从这个建议中组装一个工作脚本的麻烦,为什么我建议你允许合并,或者不要试图采取这样一个不同寻常的中间地带。

答案 2 :(得分:0)

如果您仍在寻找。 gitlab是唯一实现此功能的git服务器。他们称其为半线性历史。 看第二个选项 gitlab configuration

这将在合并请求中毫不费力地强制执行这种历史记录(右图): enter image description here