解决 git 上游变基"hard case"



如果每个分支都带有对其初始基提交(例如branch@{base})的引用,git 上游变基"硬情况"问题不会得到解决吗?

这个初始基本提交(例如,存储在配置文件中的branch.<name>.base下)将首先是分支最初创建时指向的提交。

然后,任何git rebase new_base_commit branch实际上都可以在将branch@{base}更新为new_base_commit之前执行git rebase --onto new_base_commit branch@{base} branch

它只会自动执行文档的"困难案例"解决方案。

我想,如果这样一个简单的解决方案还没有实施,应该有充分的理由不这样做。既然我看不到任何东西,那一定意味着我误解了什么。

那么如果有,这些原因是什么?

>EDIT:阅读 bk2204 的答案让我意识到这种行为对于跟踪分支的特殊用例才有用且预期(我应该更早意识到,因为它是关于上游变基的),所以初始基础应该只记录用于跟踪分支,并且仅用于使用隐式@{upstream}的命令, 就像没有争论的git rebase一样。 >EDIT:我刚刚发现,实际上,git pull --rebasegit rebase已经使用git merge-base --fork-point算法做了类似的事情,但后者使用可以垃圾收集的 reflog 来计算分叉点。

所以我仍然想知道:为什么不简单地将其存放在branch.<name>.remote旁边并branch.<name>.merge呢?

例如,当用户开始跟踪另一个分支*时,可以使用git merge-base --fork-point upstream local计算分叉点并存储在git config branch.local.forkPoint(或任何其他名称)下,以及git config branch.local.remotegit config branch.local.merge.
然后,当用户执行git pull --rebasegit rebase时,它可以执行**:

git rebase --onto local@{upstream} `git config branch.local.forkPoint` local

如果用户尝试执行git pullgit merge,它可以首先检查local@{upstream}是否未变基,如下所示:

git merge-base --is-ancestor `git config branch.local.forkPoint` local@{upstream}

如果它被重定基址,它可能会中止,并建议改为变基或编写完整的合并命令来强制它(例如)。


EDIT:我认为,为了能够正确处理文档此页面中"变基的危险"中描述的情况,当通过合并而不是变基将分支"同步"到其上游时,应该检查最后一个"同步点"以验证上游从那时起也没有变基。

因此,每个git pullgit merge也应该在应用合并后将上游分支中的合并父提交存储在某个地方(例如branch.local.lastSyncPoint可能)。 在应用合并之前,还应检查:

git merge-base --is-ancestor `git config branch.local.lastSyncPoint` local@{upstream}

实际上,它可能会使对分叉点的检查毫无用处。

>EDIT:此外,我认为变基应该丢弃从最后一个"同步点"访问的所有提交,这些提交不包括在(变基)上游(local@{upstream}..`git config branch.local.lastSyncPoint`)中。在丢弃提交的情况下,它将使其根据预期工作。 <小时 />

*,带git switch --create local --track upstreamgit checkout -b local upstreamgit branch --track local upstreamgit branch --set-upstream-to upstream local

** 而不是即时:

git rebase --onto local@{upstream} `git merge-base --fork-point local@{upstream} local` local

首先:branch
不会有一个单一的branch@base:"基础"不会相同,例如对于git rebase mastergit rebase develop

第二:你仍然需要分析提交列表:
假设另一个开发人员(我们叫他戴夫)致力于分支develop?如果戴夫在他的一次提交中修复了与您相同的错误怎么办?他挑选了你的一个提交?

git专注于存储内容。当发生"合并"或"变基"等操作时,它会应用"通常有效"(并且运行良好)的规则,但验证内容是否正确始终留给用户。

首先,Git 不会以你想到的方式跟踪分支"开始"的位置。 分支只是指向提交的指针,每个提交都包含指向一个或多个先前提交的指针。 因此,如果我做类似git checkout -b topic-branch的事情,Git 不会记录从中创建此分支的提交,并且该提交在任何方面都不是特殊的。

其次,Git 不会优先考虑任何一个分支而不是另一个分支。 从现有分支创建新分支并不意味着原始分支与我刚刚创建的分支特殊或不同,Git 也不假设我将新分支合并到旧分支中。 例如,我可能没有一个主分支,而是以版本命名的分支:v1v2v3等。 因此,从v3创建v4与从主分支创建topic-branch没有任何不同。 跟踪v4的基础是没有意义的,因为它永远不会合并到v3中。

第三,Git 明确不将分支作为一个概念来跟踪。 有意使提交不包含分支名称或分支点。 分支旨在成为对现有提交的轻量级引用。 旨在两个分支可以指向同一个提交,这对于打包效率很重要。 如果我想创建一个分支major-feature,其中包含和扩展topic-branch而又基于main,我要么必须在我的提交中公开我把一个小主题变成主要功能的历史记录,要么我必须在major-feature重写所有提交。

因此,虽然跟踪这些信息将有助于某些用例,但它会为许多其他用例添加一堆无趣的元数据,并且会增加一堆复杂性。

相关内容

  • 没有找到相关文章

最新更新