git-子树未找到最新的壁球

git-subtree not finding latest squash

对于 this repository, git subtree merge --squash --prefix=resources/webidl2 8a7ff70664 where that commit comes from this repository,合并冲突失败。

添加-d启用调试输出,我们发现:

Squash found: 5353ef707674e9d894f207581d7dffab2609b832 bd216bcd5596d60734450adc938155deab1e1a80

但是,这不是最新的 squash,运行 log call manually and changing the --grep option it becomes apparent that --grep="^git-subtree-dir: resources/webidl2/*$" isn't matching 960a3d21bab0293630da8919847f87f4af3a3198 没有明显的原因(它确实匹配 --grep="^git-subtree-dir: resources/webidl2/*",但包含 git-subtree-dir 的行在两个匹配的提交中,每个字节都是相同的,因此为什么一个与前一个 --grep 选项匹配而另一个不匹配是没有意义的。

鉴于 git-subtree 无法找到之前的 squash,我如何做一个新的 squash 而不认为其中的所有内容都是本地更改并因此导致冲突?

正在查看未找到的提交的 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$ 操作匹配行尾,正如您在非 Windows 系统上所期望的那样是 LF,因此 ^git-subtree-dir: resources/webidl2/*$ 不会匹配,因为在行尾之前有一个 CR。

提交似乎来自 a GitHub PR and merged through "squash and merge" with the commit message therefore edited through GitHub. Looking at the commit message compared with the original commit 来自 git-subtree,您会发现原始提交 在该行中包含任何 CR 字节. (我们也会在稍后 "squash and merged" 回过头来,因为这导致了其他问题!)

看看如何解决这个问题,我发现最好的方法是下载 git-subtree.sh 的副本,然后编辑 find_latest_squash 函数以仅回显预期的提交引用;即,将函数替换为:

echo "960a3d21bab0293630da8919847f87f4af3a3198" "88c5c5b6bb675d0d95ae3ec4db3258768d0c8fc0"

完成后,运行 git-subtree 将产生两个提交:一个更新 webidl2.js 的副本(其父提交是 960a3d21bab),但由于之前的挤压这个实际上会导致提交删除所有内容并添加 webidl2.js 的新副本(git-subtree 期望有一个提交图,它实际上只是子树,在根部,偶尔有新的提交which squash; "squash and merge" 导致整个存储库出现在该提交中,子树在其前缀路径中),然后是合并提交,它更新了存储库中子树的副本。

重要的是,今后不要修改 git-subtree 创建的压缩提交,因为 git-subtree 对它的任何更改都非常敏感。