git-subtree没有找到最新的壁球

时间:2017-11-03 18:44:26

标签: git git-subtree

使用this repositorygit 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未能找到这个以前的壁球,我怎么能做一个新的壁球而不认为那是一个局部的变化,从而最终导致冲突?

1 个答案:

答案 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对它的任何更改都非常敏感。