我一直在使用git-subtree扩展(https://github.com/apenwarr/git-subtree)来管理我们主项目中的子项目.当我尝试从主项目中拆分对子项目所做的更改时,它正在完成我想要的事情.
比如早些时候我做过
git subtree add -P Some/Sub/Dir --squash git@gitserver:lib.git master
Run Code Online (Sandbox Code Playgroud)
将库代码引入我们主项目中的Some/Sub/Dir.这里的一切都很棒,所以我把我的更改推到了我们的中央主要项目裸git repo.然后我决定在Some/Sub/Dir中更改我的本地版本的lib,提交它,然后将其拆分以将其推回到lib.git repo
git subtree split -P Some/Sub/Dir -b some_branch
Run Code Online (Sandbox Code Playgroud)
一切都按预期工作.不再需要repo的本地副本我删除了它.
从我们的中央仓库克隆了一个新的repo副本后,我对Some/Sub/Dir中的lib进行了一些更改,并决定将这些更改拆分出来并将它们推回到lib.git存储库.我尝试使用与以前相同的子树分割命令,但这次我最终得到以下输出:
1/ 3 (0)
2/ 3 (1)
3/ 3 (1)
fatal: bad object d76a03f0ec7e20724bcfa253e6a03683211a7bb1
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
实际上是指lib.git repo中的提交.
我能够拼凑起来(我是一个git noob所以我可能错了,忽略了一些东西,或者在这里使用了不正确的术语),'git subtree add --squash'将带来整个历史远程lib.git repo进入当前仓库,将其压缩到单独的提交中,然后将该提交添加到工作分支中.lib.git提交历史记录保留在当前的repo中,但是它们是悬空提交,因为除了通过压缩提交的文本之外它们实际上没有被引用.只要那些悬空提交仍然存在,git-subtree就可以使用它们来执行拆分,但是由于推或拉不包含悬空对象(或者如果我运行gc并完全修剪悬空对象),那些悬空提交将丢失并且git-subtree不再具有执行拆分所需的信息.
我添加了一个脚本,可以完全重现我一直存在的问题.
我的问题是:
1)我可以做些什么来处理我现在有子树的现有情况,我想要合并回原始仓库,但不再有任何将它们链接在一起的历史记录.我目前的想法是做一些像:
git subtree split -P Some/Sub/Dir …Run Code Online (Sandbox Code Playgroud) 我尝试将目录及其所有历史记录从存储库移动到另一个存储库。
提取目录的完整历史记录很容易git subtree split。
这会创建一个新分支,可以轻松地将其提取到其他存储库。
现在我曾经git subtree add将目录粘贴回第二个存储库。
如果我看gitk或git log --decorate --graph一切看起来都很好。所有提交都按预期存在。此外,所有文件都按预期存在。
但是,当我尝试使用的是看一个移植文件的历史记录git log -- transplanted_dir/somefile,我只看到了一个“合并”承诺,从产生的git subtree add。
为什么我在上面的 gitk 中看到提交,但在单个文件的日志中没有?
如果我做一个简单的git merge,我可以看到每个文件的历史记录,但是这些文件当然不会存在于子文件夹中。
将移动的提交集成到另一个存储库中的正确方法是什么?
重现情况的详细示例命令:
#create two repositories:
git init a
git init b
# create directory dir with some history
cd a
mkdir dir
echo 1 > dir/file
git add .
git commit -am 1
echo 2 > dir/file
git commit -am 2
echo 3 …Run Code Online (Sandbox Code Playgroud)