0

如果每个分支都引用了它的初始基本提交(比如) ,那么git 上游 rebase “硬案例”问题是否会得到解决branch@{base}

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

然后,任何git rebase new_base_commit branch人实际上都可以git rebase --onto new_base_commit branch@{base} branch在更新branch@{base}new_base_commit.

它只会自动化文档的“硬案例”解决方案。

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

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


编辑:阅读bk2204 的回答让我意识到这种行为只会对跟踪分支的特殊用例有用和预期(我应该早点意识到,因为它是关于上游变基的),所以应该记录初始基数只用于跟踪分支,仅用于使用隐式的命令@{upstream},例如git rebase不带参数的命令。


编辑:我刚刚发现实际上,git pull --rebase并且git rebase已经使用 的算法做了类似的事情git merge-base --fork-point,但后者使用可以被垃圾收集的 reflog 来动态计算分叉点。

所以我仍然想知道:为什么不简单地将它存储在旁边branch.<name>.remotebranch.<name>.merge

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

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

如果用户尝试执行 agit pull或 a git merge,它可以首先检查local@{upstream}没有重新设置基础,使用:

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

如果它被 rebase,它可能会中止,并建议改为执行 rebase 或编写完整的合并命令来强制它(例如)。


编辑:我认为,为了能够正确处理文档此页面中“变基的危险”中描述的情况,当使用合并而不是变基将分支“同步”到其上游时,最后一次“同步”点”应该被检查以验证上游也没有从那时起重新定位。

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

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

实际上,它可以使对分叉点的检查无用。


编辑:此外,我认为变基应该丢弃从最后一个“同步点”可到达的所有提交,这些提交未包含在(变基)上游(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
4

2 回答 2

0

首先,Git 不会按照您的想法跟踪分支“开始”的位置。一个分支仅仅是一个提交的指针,每个提交都包含一个指向一个或多个先前提交的指针。因此,如果我执行类似的操作git checkout -b topic-branch,Git 不会记录创建此分支的提交,并且该提交在任何方面都不是特别的。

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

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

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

于 2020-06-12T21:09:53.177 回答
0

首先: a 不会有branch@base一个branch
“基础”不会相同,例如git rebase masterand git rebase develop

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

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

于 2020-06-12T11:58:31.263 回答