我一直在使用git-subtree扩展(https://github.com/apenwarr/git-subtree)来管理我们主项目中的子项目。它做的很好,除了当我尝试从我们的主项目中分离出对子项目所做的更改时失败。
例如,之前我已经完成了以下工作:
git subtree add -P Some/Sub/Dir --squash git@gitserver:lib.git master
将库代码引入到我们主项目的Some/Sub/Dir中。一切都进行得很顺利,然后我将更改推送到我们中央主项目裸git存储库。然后我决定对我在Some/Sub/Dir中本地版本的库进行更改,提交它,然后将其分离以将其推回lib.git存储库。
git subtree split -P Some/Sub/Dir -b some_branch
一切都按预期工作。不再需要本地副本,我将其删除。
从中央仓库克隆一个新的副本后,我对Some/Sub/Dir中的lib进行了一些更改,并决定将这些更改拆分出来并推回lib.git存储库。我尝试使用与以前相同的子树拆分命令,但是这次我得到以下输出:
1/ 3 (0)
2/ 3 (1)
3/ 3 (1)
fatal: bad object d76a03f0ec7e20724bcfa253e6a03683211a7bb1
d76a03f0ec7e20724bcfa253e6a03683211a7bb1来自我添加子树时的操作:
commit 43b3eb7d69d5eb64241eddb12e5bd74fd0215083
Author: Ian Bond <ibond@onezero.com>
Date: Fri Apr 22 15:06:50 2011 -0400
Squashed 'Subtree/librepoLib/' content from commit d76a03f
git-subtree-dir: Subtree/librepoLib
git-subtree-split: d76a03f0ec7e20724bcfa253e6a03683211a7bb1
这实际上是指lib.git仓库中的一个提交。
我所了解的是(我是一个git新手,所以可能会有错误、忽略某些东西或者使用不正确的术语),'git subtree add --squash'命令将远程lib.git repo的整个历史记录引入到当前repo中,将其压缩成一个单独的提交(commit),然后将该提交添加到工作分支中。虽然lib.git提交历史记录保留在当前repo中,但它们是悬挂提交,因为除了通过压缩提交的文本之外,它们实际上没有被引用。只要这些悬挂提交存在,git-subtree就可以使用它们来执行拆分操作,但是由于push或pull不包含悬挂对象(或者如果我运行gc并完全修剪悬挂对象),这些悬挂提交就会丢失,git-subtree将不再具备执行拆分所需的必要信息。
我已经添加了一个脚本,可以完全重现我遇到的问题。
我的问题是:
1) 我现在有一些子树,想将它们合并到它们原始的仓库中,但是它们之间没有任何历史联系。我现在的想法是执行以下操作:
git subtree split -P Some/Sub/Dir 43b3eb7^.. --ignore-joins -b splitBranch
我希望将自“git subtree add”以来的所有历史记录拆分出来,并合并回原始仓库(幸运的是,自添加以来未进行任何更改)。这是最好的方法吗?您对如何执行合并有何建议?
2) 有没有办法让git-subtree按预期工作?我相信如果我在“git subtree add”上省略--squash参数,那么一切都会正常工作,但这会导致我的仓库注入大量不相关的历史记录。有没有某种方法可以保留所需的提交记录(最好不保留整个库的历史记录)?