如何从git中的另一个存储库中提取一系列提交?

如何从git中的另一个存储库中提取一系列提交?,git,version-control,git-pull,Git,Version Control,Git Pull,我有两个存储库,A和B。我想将A中的所有文件及其历史记录的子集复制到B中B有自己的历史文件,我也想保存这些文件;它不是一个全新的存储库 你看,A有28000次提交。除了最近的30多个,我不在乎。为了便于讨论,假设我对提交(1至27970)不感兴趣,但我希望保留提交(27971至28000)的历史记录 我试过两种不同的方法 将A(使用git-rebase-i)中的提交1到27970压缩为单个提交,然后git将A压缩为B。我在这里遇到的麻烦是,在A的重新基址期间,有很多关于git无法应用某些提交的

我有两个存储库,
A
B
。我想将
A
中的所有文件及其历史记录的子集复制到
B
B
有自己的历史文件,我也想保存这些文件;它不是一个全新的存储库

你看,
A
有28000次提交。除了最近的30多个,我不在乎。为了便于讨论,假设我对提交(1至27970)不感兴趣,但我希望保留提交(27971至28000)的历史记录

我试过两种不同的方法

  • A
    (使用
    git-rebase-i
    )中的提交1到27970压缩为单个提交,然后
    git将
    A
    压缩为
    B
    。我在这里遇到的麻烦是,在
    A
    的重新基址期间,有很多关于git无法应用某些提交的错误。我不了解
    A
    中的这些提交,因此无法修复它们。(另外,执行重定基准需要很长时间——很多小时,我还没有完成。)
  • 在commit#27970下载
    a
    的快照(即无历史记录),并将其放入
    B
    ,然后对新文件执行a
    git add
    git commit
    。然后从
    a
    (使用
    git格式补丁
    )为提交#27971到#28000创建一个补丁,并将该补丁(使用
    git apply
    )应用到
    B
    。这一切似乎都很好,只是它没有维护给定文件的提交历史。也就是说,应用补丁后,所有30次提交中的所有更改似乎都同时发生:历史记录没有保留

必须有一个简单的方法来做到这一点

所以我研究了两种可能的方法来实现您的目标。其中之一是对回购
a
进行浅克隆,但根据:

浅层存储库有许多限制(您不能克隆或从中获取,也不能从中推送或插入),但如果您只对具有长期历史的大型项目的最近历史感兴趣,并且希望以补丁的形式发送修复,则浅层存储库就足够了

不能做一些基本的网络选项,比如从浅层回购中推送和取回,这听起来是一个很大的限制,所以我认为下一个选项可能更适合你。您可以尝试从提交
master~29
开始创建一个孤立分支,而不是进行浅层回购,然后在提交
master~28..master
的基础上重新设置提交的基础:

git签出--孤立根主目录~29
git添加。
git commit-m“在此处添加消息”
这将启动您的孤立分支,使用一个新的根提交,其中包含您在提交
master~29
时的历史状态。接下来,您将希望重新设置子体提交的基础(这将保留历史记录,但提交日期除外,因为重新设置基础,提交日期将必须更新):

git-rebase——保留合并——到根主机~29主机上
#或者简称为`-p`
git-rebase-p——在根master~29 master上
这将在新根目录上重建
master
的其余部分,同时保留任何合并提交。如果您想确认新版本的
master
与旧版本相同,只是历史记录较短,那么只需在重新基础后立即进行差异:

git diff master@{1} master
我强烈建议您先测试另一个克隆


.

我可以想出许多不同的方法来做你想做的事,但我会用我脑海中第一个最简单的方法来回答。另外,你基本上只是想做一个新的回购
B
,它是
a
的克隆,但只是最近30次提交的副本吗?@Cupcake我编辑了我的问题:
B
有自己的文件;这不是新的回购协议。
B
包含什么类型的文件,以及它们与
a
中的文件有何关系?如果它们是相同的文件,但共享不同的历史记录(如重新基线后得到的历史记录),那么当您将
a
中的文件合并到
B
中时,您最终会遇到冲突,我并不感到惊讶。在解决这些冲突时要非常小心。谢谢!你的孤儿分支策略对我有用。注意,我对存储库
A
执行了上述所有命令,然后我
git将
-ed
A
拉入
B
。出于某种原因,有一些合并冲突需要处理,但没有什么我不能处理的。