Git子树:移动子树到一个不同的目录并且拉它

quhf5bfb  于 2023-03-06  发布在  Git
关注(0)|答案(2)|浏览(157)

假设我创建了一个如下的子树:

git subtree --add --prefix=subdir <path_to_remote> <remote_branch> --squash

然后我想移动/重命名subdir,所以我这样做:git mv subdir dir2/subdir
现在,当我尝试将该子树拉到一个新前缀时:

git subtree --pull --prefix=dir2/subdir <path_to_remote> <remote_branch> --squash

git说:

Can't squash-merge: 'dir2/subdir' was never added.

我怎样才能做好呢?

siv3szwd

siv3szwd1#

git subtree命令知道你的子树,因为当你add一个子树时,它在第一次提交时存储了名字:

Add 'subdir/' from commit 'c7fbc973614eced220dcef1663d43dad90676e00'

git-subtree-dir: subdir
git-subtree-mainline: c166dc69165f6678d3c409df344c4ed9577a2e11
git-subtree-split: c7fbc973614eced220dcef1663d43dad90676e00

--squash选项的git subtree pull查找包含git-subtree-dir的提交,以从远程存储库中找到最近的提交,从而找到应用和压缩所有提交的点。
在许多情况下,git subtree split --rejoin操作将成功:

$ git subtree split --rejoin --prefix=dir2/subdir HEAD
Merge made by the 'ours' strategy.
25070c483647f8136655d0e0c6c3d62f469177aa

结果提交如下所示:

Split 'dir2/subdir/' into commit '25070c483647f8136655d0e0c6c3d62f469177aa'

git-subtree-dir: dir2/subdir
git-subtree-mainline: 59cc3c770e78dbc30bdfe36a6b4e14ce83b38f6c
git-subtree-split: 25070c483647f8136655d0e0c6c3d62f469177aa

在大多数情况下,此提交将被找到,并且下一个git subtree pull --squash将成功。请注意,有时子树操作会失败,并在存储库的工作副本中留下子树的分支。请确保删除所有剩余的临时分支,以从头开始。
有时候上面的操作不成功,但是我从来没有找到原因。在这种情况下,你可以重定基到添加子树的提交,并通过修改提交消息来手动更改目录名。但是,这个操作会破坏你的整个历史记录。

qaxu7uf2

qaxu7uf22#

正如另一个答案所指出的,这里的问题是git-subtree将文件夹名嵌入到提交中,并且拒绝承认你已经重命名了它。这个答案建议你做一个分裂/重新加入,我认为这最终会使你的提交历史变得有点臃肿和复杂。
一个更简单的方法是通过一个简单的commit命令git-subtree做正确的事情。
1.找到git-subtree做过压缩合并的最后一个提交,我不认为git-subtree提供了一个本地工具来完成这个操作,但有一种方法是手动搜索(假设你的文件夹名为“basedir”):

git log -1 --grep "git-subtree-dir: basedir"

在提交的末尾,它可能看起来像这样:

git-subtree-dir: basedir
git-subtree-split: 607efa887537d5544b3a99e2a0a2dd64abcc72ee

你需要注意提交消息中git-subtree-split:的值,假设它是607efa887537d5544b3a99e2a0a2dd64abcc72ee
1.重命名文件夹,就像你正在做的:git mv basedir basedir2 && git commit
1.现在,通过执行以下操作来创建一个空提交(假设您想将其重命名为“basedir”):

git commit --allow-empty

使用下面的提交消息(当然,你可以自定义它):

Reassign subtree dir from basedir to basedir2

git-subtree-dir: basedir2
git-subtree-split: 607efa887537d5544b3a99e2a0a2dd64abcc72ee

注意,哈希值607efa887537d5544b3a99e2a0a2dd64abcc72ee与前面的哈希值完全相同。
你现在可以开始了!你基本上什么都没做,只是做了一个空的提交消息,并手动将git-subtree-dir从“basedir”重命名为“basedir 2”。Git-subtree在某种程度上是一个简单的工具,可以简单地使用它来记住subdir是什么。我觉得它应该真正将它作为工具的一部分,而不是用户需要手动构建这样的提交。但无论如何它都能工作(至少在我测试它的时候它能工作)。

相关问题