git无法合并不相关的历史浅克隆



我已经浅层克隆了一个深度为1的repo,并创建了一个用于开发的本地dev分支。在提出PR后,我收到了合并冲突,所以我拉了最新的master,并试图将其与dev分支合并。

方法1:

  1. 当我试图拉动分支时,它显示fatal: refusing to merge unrelated histories
  2. 因此,我删除了本地master,并使用switch创建了一个新的分支git switch -c master origin/master
  3. 现在,当我尝试将主分支合并到本地以解决合并冲突时,我得到了错误fatal: refusing to merge unrelated histories

方法2:

  1. 方法1中的步骤2之前相同
  2. 我已经尝试过挑选导致合并冲突的提交。由于repo是浅层克隆的,因此它没有提交历史记录并抛出错误bad object

我尝试过–allow-unrelated-histories,有太多的合并冲突需要手动修复。

如何解决这个问题并将master合并到我的dev分支?

Never1使用--allow-unrelated-histories。相反,加深(或"不允许"(你的克隆。编辑:根据注释,您还需要将克隆转换为完整克隆(它目前是一个单分支克隆,我应该预料到这一点,因为在克隆过程中使用--depth默认也会创建一个单支路克隆(。

Git中的合并依赖于三个提交,而不是两个:

  • 有您的当前提交(又名HEAD(,它将代表从某个共同起点开始所做的工作
  • 有一些其他提交,这将代表在其他分支中完成的工作,因为是相同的共同起点
  • 还有第三个提交,合并基础,这是常见的起点

当您运行git merge时,您提供的参数(通常是像featuremaster这样的分支名称(位于这三个参数的中间:;其他";或CCD_ 12提交。当前或--ours提交是由您签出的内容暗示的。第三次提交是Git自己找到的共同起点。但是Git需要历史来找到这个提交。

在Git存储库中,历史无非是存储库中的提交。一个正常的非浅层克隆具有所有提交2,因此它具有所有历史。克隆的目的是以权宜之计的名义故意省略一些历史。出于某些目的,这是可以的(因此实际上是权宜之计(。对于合并不是;不要这么做。

如果您有一个现有的浅层克隆,例如,因为您的CI系统创建了一个,请考虑运行:

git remote set-branches origin "*"
git fetch --unshallow

第一个命令将克隆转换为标准的完整克隆(撤消单个分支(。请注意,您可以在没有引号的情况下键入*,但使用这样的引号应该始终有效。

第二个命令重定向通常的git fetch操作,使其删除浅度。如果这会占用太多的系统资源,那么您也可以使用git fetch --depthgit fetch --deepen向浅存储库中增量添加更多提交,直到您有足够的历史记录(足够的提交(供git merge定位公共起点。这种方法的问题是,无法保证深度有多深,这意味着没有正确的方法来选择正确的深度。这反过来意味着一个循环,在这个循环中,你反复加深深度,直到它";足够";,每次都会使用越来越多的系统资源,这可能是您最初试图通过浅层克隆来避免的。

大多数制作浅层克隆的CI系统首先为您提供了一种强制执行完整克隆的方法(总体而言,这比制作浅层然后取消浅层克隆更有效(。因此,如果浅层克隆是问题所在,就像在这种情况下一样,一开始就不要这么做。


1高级Git用户规则:除非你已经证明--allow-unrelated-histories是可以的,否则永远不要使用它。

2记住,git clone操作的核心是复制所有提交,但不复制任何分支名称。Git不需要分支名称来运行,但它确实需要提交。我们——人类——不喜欢使用没有分支名称的Git,所以我们总是让Git创建一些分支,尽管CI系统有时不会打扰它们;我们使用分支名称和/或远程跟踪名称(记住其他存储库的分支名称(来查找感兴趣的提交。Git也可以使用这些,但可以直接使用原始哈希ID,这就是这些CI系统的工作方式。

相关内容

  • 没有找到相关文章

最新更新