查看未找到的提交的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/*\$ 不匹配,因为在 end-of 之前有一个 CR -线。
提交似乎来自a GitHub PR,并通过“挤压和合并”与提交消息合并,因此通过 GitHub 编辑。查看提交消息与来自git-subtree 的original commit 相比,您会发现原始提交不在该行中包含任何CR 字节。 (我们稍后还会回到它被“压缩和合并”的事实,因为这导致了其他问题!)
看看如何解决这个问题,我发现的最佳方法是下载git-subtree.sh 的副本,然后编辑find_latest_squash 函数以回显预期的提交引用;即,将函数替换为:
echo "960a3d21bab0293630da8919847f87f4af3a3198" "88c5c5b6bb675d0d95ae3ec4db3258768d0c8fc0"
完成此操作后,运行git-subtree 将产生两个提交:一个更新 webidl2.js 的副本(其父提交为 960a3d21bab),但由于之前的 squash,这实际上会导致一个删除所有内容的提交和添加 webidl2.js 的新副本(git-subtree 期望有一个提交图,实际上只是子树,在根,偶尔会有新的提交被挤压;“挤压和合并”导致整个存储库出现在该提交中,子树在其前缀路径中),然后是合并提交,更新存储库中子树的副本。
重要的是,今后不要修改 git-subtree 创建的 squash 提交,因为 git-subtree 对它的任何更改都非常敏感。