我已经浅层克隆了一个深度为1的repo,并创建了一个用于开发的本地dev分支。在提出PR后,我收到了合并冲突,所以我拉了最新的master,并试图将其与dev分支合并。
方法1:
- 当我试图拉动分支时,它显示
fatal: refusing to merge unrelated histories
- 因此,我删除了本地master,并使用switch创建了一个新的分支
git switch -c master origin/master
- 现在,当我尝试将主分支合并到本地以解决合并冲突时,我得到了错误
fatal: refusing to merge unrelated histories
方法2:
- 方法1中的步骤2之前相同
- 我已经尝试过挑选导致合并冲突的提交。由于repo是浅层克隆的,因此它没有提交历史记录并抛出错误
bad object
我尝试过–allow-unrelated-histories
,有太多的合并冲突需要手动修复。
如何解决这个问题并将master合并到我的dev分支?
Never1使用--allow-unrelated-histories
。相反,加深(或"不允许"(你的克隆。编辑:根据注释,您还需要将克隆转换为完整克隆(它目前是一个单分支克隆,我应该预料到这一点,因为在克隆过程中使用--depth
默认也会创建一个单支路克隆(。
Git中的合并依赖于三个提交,而不是两个:
- 有您的当前提交(又名
HEAD
(,它将代表从某个共同起点开始所做的工作 - 有一些其他提交,这将代表在其他分支中完成的工作,因为是相同的共同起点和
- 还有第三个提交,合并基础,这是常见的起点
当您运行git merge
时,您提供的参数(通常是像feature
或master
这样的分支名称(位于这三个参数的中间:;其他";或CCD_ 12提交。当前或--ours
提交是由您签出的内容暗示的。第三次提交是Git自己找到的共同起点。但是Git需要历史来找到这个提交。
在Git存储库中,历史无非是存储库中的提交。一个正常的非浅层克隆具有所有提交,2,因此它具有所有历史。浅克隆的目的是以权宜之计的名义故意省略一些历史。出于某些目的,这是可以的(因此实际上是权宜之计(。对于合并,不是;不要这么做。
如果您有一个现有的浅层克隆,例如,因为您的CI系统创建了一个,请考虑运行:
git remote set-branches origin "*"
git fetch --unshallow
第一个命令将克隆转换为标准的完整克隆(撤消单个分支(。请注意,您可以在没有引号的情况下键入*
,但使用这样的引号应该始终有效。
第二个命令重定向通常的git fetch
操作,使其删除浅度。如果这会占用太多的系统资源,那么您也可以使用git fetch --depth
或git fetch --deepen
向浅存储库中增量添加更多提交,直到您有足够的历史记录(足够的提交(供git merge
定位公共起点。这种方法的问题是,无法保证深度有多深,这意味着没有正确的方法来选择正确的深度。这反过来意味着一个循环,在这个循环中,你反复加深深度,直到它";足够";,,每次都会使用越来越多的系统资源,这可能是您最初试图通过浅层克隆来避免的。
大多数制作浅层克隆的CI系统首先为您提供了一种强制执行完整克隆的方法(总体而言,这比制作浅层然后取消浅层克隆更有效(。因此,如果浅层克隆是问题所在,就像在这种情况下一样,一开始就不要这么做。
1高级Git用户规则:除非你已经证明--allow-unrelated-histories
是可以的,否则永远不要使用它。
2记住,git clone
操作的核心是复制所有提交,但不复制任何分支名称。Git不需要分支名称来运行,但它确实需要提交。我们——人类——不喜欢使用没有分支名称的Git,所以我们总是让Git创建一些分支,尽管CI系统有时不会打扰它们;我们使用分支名称和/或远程跟踪名称(记住其他存储库的分支名称(来查找感兴趣的提交。Git也可以使用这些,但可以直接使用原始哈希ID,这就是这些CI系统的工作方式。