我想在我的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
答案 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)