git: copy (cherry-pick) history of one repository into a directory of another
我有两次休息。第一次回购(我们称之为A)是不久前开始的;第二次回购(B)是最近开始的。现在我们认为我们宁愿把B作为A的一个子目录,所以我想这样做,但要保留B的提交历史。
- 我想要完整的提交历史。也就是说,我不想仅仅把B的历史压缩成一个补丁,然后将其作为新的提交放到A中。
- 我不想保留b的精确sha1(我知道这可能是不可能的)。
- 我不在乎保留B的承诺的时间戳(尽管这样做很好)。
- 我不想保留作者身份。
- 我只想保留B提交的每个提交的差异/补丁。
- 我不想保留任何关于两个独立存储库的概念。事实上,我只想有一个前进的方向。
- 我不需要b是a的git子模块,它有自己的.gitdir或类似的东西。
在任何操作结束时,我希望满足三个标准:
在b的HEAD中看到的文件和目录位于a的子目录中,即/path/to/repoB/somefile.js位于/path/to/repoA/B/somefile.js中。
B的所有提交消息都按时间顺序出现在A的提交结束时。
每个提交的差异都是可用的(可由git log等查看)。
一些例子可以阐明我的意图:
在回购B中,承诺1是增加file.txt。
commit 2是编辑file.txt。
因此,在回购协议A中,我需要两个新的承诺:
回购A承诺98:增加B/file.txt。
repo a commit 99:编辑B/file.txt。
编辑:
子目录中的合并Git存储库已被提议为我问题的副本。我承认这与我的要求非常接近,并且有几个很好的答案。我在那里试过了subtree的答案,还有rebase --onto的答案。两者都非常接近,但都不令人满意:subtree不允许git log不提及path/to/file/without/repo-subdir(我将b移入repo-subdir)而通过存储库历史查看历史;rebase --onto不允许b的历史从a的HEAD中可见。
- 子目录中可能存在合并Git存储库的副本
- stackoverflow.com/…
- 特别是,请参见git subtree对博士建议副本的回答。
这就是我最后做的。多亏了来自自由节点(IRC)的#git的atrus引导我朝正确的方向前进。
在回购B中,建立一个新的分支机构:git checkout -b indir。
在repo b中,mkdir b-subdir,其中b-subdir是dir,我希望b以a的dir树结束。
在repo b中,git mv [...] b-subdir将所有东西(.git/和b-subdir/本身除外)移入b-subdir。
向回购B承诺这一行动。
推到原点(push -u origin HEAD)。
回购A:git remote add repo-b ssh://......../repo-b.git。
江户十一〔11〕。
埃多克斯1〔12〕
这允许我查看来自repo b的任意文件的完整历史记录(使用git log的--follow开关),而不需要从文件路径中去掉b-subdir/前缀。使用git subtree,如果去掉它,您只会在b中看到文件的历史(如果不去掉,您会在a中看到历史)。