使用this repository,git subtree merge --squash --prefix=resources/webidl2 8a7ff70664
提交来自this repository,它会因合并冲突而失败。
添加-d
以启用调试输出,我们发现:
Squash found: 5353ef707674e9d894f207581d7dffab2609b832 bd216bcd5596d60734450adc938155deab1e1a80
但是,这不是最新的压缩,并且手动运行log call并更改--grep
选项,很明显--grep="^git-subtree-dir: resources/webidl2/*\$"
与960a3d21bab0293630da8919847f87f4af3a3198不匹配没有明显的原因(它匹配--grep="^git-subtree-dir: resources/webidl2/*"
,但两个提交中包含git-subtree-dir
的行是逐字节相同的,因此没有理由为什么一个匹配前一个--grep
选项但不是其他选项。
鉴于git-subtree
未能找到这个以前的壁球,我怎么能做一个新的壁球而不认为那是一个局部的变化,从而最终导致冲突?
答案 0 :(得分:1)
查看未找到的提交的object:
$ git cat-file -p 960a3d21bab0293630da8919847f87f4af3a3198 | hexdump -C
[…]
00000cc0 6c 6c 6f 77 20 60 2d 60 0d 0a 0d 0a 67 69 74 2d |llow `-`....git-|
00000cd0 73 75 62 74 72 65 65 2d 64 69 72 3a 20 72 65 73 |subtree-dir: res|
00000ce0 6f 75 72 63 65 73 2f 77 65 62 69 64 6c 32 0d 0a |ources/webidl2..|
00000cf0 67 69 74 2d 73 75 62 74 72 65 65 2d 73 70 6c 69 |git-subtree-spli|
00000d00 74 3a 20 38 38 63 35 63 35 62 36 62 62 36 37 35 |t: 88c5c5b6bb675|
00000d10 64 30 64 39 35 61 65 33 65 63 34 64 62 33 32 35 |d0d95ae3ec4db325|
00000d20 38 37 36 38 64 30 63 38 66 63 30 |8768d0c8fc0|
00000d2b
这里的关键点是git-subtree-dir
行以0d 0a
结尾(CR LF)。 git log --grep
的{{1}}操作与行尾相匹配,正如您在非Windows系统上所期望的那样,它是LF,因此$
不匹配,因为有一个CR在行尾之前。
提交似乎来自a GitHub PR,并通过“压缩和合并”与提交消息合并,因此通过GitHub进行编辑。查看提交消息与^git-subtree-dir: resources/webidl2/*\$
中的original commit进行比较,您会发现原始提交不包含该行中的任何CR字节。 (我们还会回到以后的事实,那就是“挤压并合并”,因为这会导致其他问题!)
看看如何解决这个问题,我发现的最佳方法是下载git-subtree.sh
的副本,然后编辑git-subtree
函数以回显出预期的提交引用;即,将功能替换为:
find_latest_squash
完成此操作后,运行echo "960a3d21bab0293630da8919847f87f4af3a3198" "88c5c5b6bb675d0d95ae3ec4db3258768d0c8fc0"
将产生两个提交:一个更新webidl2.js(其父提交为960a3d21bab)的副本,但由于之前的压缩,这实际上会导致删除提交所有内容并添加了一个webidl2.js的新副本(git-subtree希望有一个提交图表,它实际上只是子树,在根,偶尔会有新的提交压缩;“壁球和合并”导致整个存储库出现在该提交中,子树在其前缀路径中),然后是合并提交,它更新存储库中子树的副本。
重要的是,继续,不要修改git-subtree创建的squash提交,因为git-subtree对它的任何更改都非常敏感。