我需要一种方法来防止将远程主分支合并到 gitlab 中的本地主分支中。当我说“主”分支时,它可以是任何分支,这只是一个示例,只要远程和本地分支具有相同的名称即可。
这很容易发生:
远程主分支领先于某人的本地分支。这个人做了一个本地更改,提交它,然后尝试推动,但他当然不能,因为 他的副本不是最新的,然后他只是拉取,这会创建一个合并从远程主分支到他的本地分支,然后他推送他的本地主分支。
远程主分支:
A-->B-->C-->D
本地总店:
A-->B
致力于本地主要:
A-->B-->E
拉(获取+合并):
A-->B-->E------>F
\ /
->C-->D-
当你查看 git log 时,看起来现在这个本地主分支是树的主干,而之前的远程主分支变成了看起来像功能分支的东西。
这次推送实际上并没有改写历史,但是改写了历史的拓扑。
这种情况有名称吗?
我想禁止这种情况,只允许另一个方向的合并,即本地分支合并到远程分支。这会保持原来的主干不变(远程拓扑不会改变),新的提交看起来像一个功能分支,它就是原来的样子:
A-->B-->C-->D-->F
\ /
-->E-----
我仍然希望允许与具有其他名称的分支合并,例如您可以从 main 合并到 dev 或从 dev 合并到 main 并推送它。我只是想禁止推送具有“相同名称”的分支,这将更改远程分支的拓扑。 为什么?保留原始拓扑很重要,因为它表明上例中的 C 和 D 已推送(即发布)到主分支中。这意味着 QA 团队可能对它们进行了测试,并且这些更改可能已发送给我们的客户。它还表明 E 永远不会发生这种情况(只有 F 可以测试并发送给客户端)。如果我们允许重写拓扑(将 E 放在主线中),所有信息都会丢失。
我们正在使用 Gitlab,我知道您可以通过禁止所有推送并使用合并请求来防止这种情况。但我希望允许每个人都从命令行工作并推送到任何分支,只要他们不重写历史或其拓扑即可。
我该如何配置?
fetch + merge 创建了一个“更新合并”,使历史变得混乱。
鼓励 fetch + rebase:
git pull --rebase
pull.rebase true
。在合并请求中使用带有 glab
命令行工具
。但除非您有非常具体的原因想要在命令行上执行所有操作,否则我建议放弃此要求。合并请求太有用了,它们是一种标准的、有记录的、功能丰富的安全贡献方式。您可以
,但是您的贡献者必须知道如何撤消他们的合并。相对简单,rebase 他们的分支,但是很多人不知道。他们要么会为此打扰你,要么放弃而不做出贡献。
# pushing was disallowed leaving us in this state after git pull merged
A - B - E - U [main]
\ /
C - D [origin/main]
$ git rebase origin/main
A - B - C - D [origin/main]
\
E1 [main]
$ git push
A - B - C - D - E1 [origin/main][main]
这说明了另一个问题:如果本地分支只有一次提交,您将无法获得所需的功能气泡。但是,如果您使用合并请求,您可以强制合并提交
git pull
执行 fetch + rebase 来简化此过程。
git pull --rebase
或设置 git config pull.rebase true
。因为这可能会重写历史,所以应该使用 git push --force-with-lease
来完成推送。你不能强迫人们这样做,但你可以鼓励它。
我想禁止这样做,只允许在另一个方向上合并,本地分支合并到origin远程跟踪分支。
您无法合并到远程跟踪分支。它们的目的是跟踪存储库的状态。如果您合并到远程跟踪分支,它将不再跟踪远程。 Git 甚至不允许你切换到远程分支。
> git switch origin/master
fatal: a branch is expected, got remote branch 'origin/master'
我知道您可以通过禁止所有推送并使用合并请求来防止这种情况。出于多种原因你应该这样做,至少对于主分支来说,
!让 git log
按照您的意愿出现是其中最不重要的。
。这将阻止合并,除非分支可以快进,这很好,因为这意味着您在合并请求中测试的代码就是您将合并的代码。它提供了一个简单的变基按钮,供您的贡献者通过变基更新他们的分支。