【问题标题】:How to pull a series of commits from another repository in git?如何从 git 中的另一个存储库中提取一系列提交?
【发布时间】:2014-04-09 21:06:31
【问题描述】:

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

你看,A 有 28,000 次提交。除了最近的30个左右,我不在乎。为简化讨论,假设我对提交 #1 到 #27,970 不感兴趣,但我想保留提交 #27,971 到 #28,000 的历史记录。

我尝试了两种不同的方法。

  • A(使用git rebase -i)中的#1 到#27,970 提交压缩为一个提交,然后将git pull A 压缩为B。我在这里遇到的麻烦是在A 的 rebase 期间,有很多关于 git 无法应用某些提交的错误。我对A 中的这些提交一无所知,所以我无法修复它们。 (另外,执行 rebase 需要 很长 时间 - 好几个小时,我还没有完成。)
  • 在提交 #27,970 处下载A 的快照(即无历史记录)并将其放入B,然后对新文件执行git addgit commit。然后从A(使用git format-patch)为提交#27,971 到#28,000 创建一个补丁,并将该补丁(使用git apply)应用到B。这一切似乎都很好,除了它没有维护给定文件的提交历史。也就是说,在应用补丁后,所有 30 次提交的所有更改似乎都同时发生了:历史没有被保留。

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

【问题讨论】:

  • 我可以想出许多不同的方法来做你想做的事,但我只会用我脑海中浮现的第一个最简单的方法来回答。另外,你基本上只是想创建一个新的 repo B,它是 A 的克隆,但只是它最近的 30 次提交?
  • @Cupcake 我编辑了我的问题:B 有自己的文件;它不是一个新的回购。
  • B 包含哪些文件,它们与A 中的文件有什么关系?如果它们是相同的文件但共享不同的历史记录(例如您在变基后会得到什么),那么当您将文件从 A 合并到 B 时,我不会对您最终遇到冲突感到惊讶。在解决这些冲突时要非常小心。

标签: git version-control git-pull


【解决方案1】:

因此,我研究了两种可能的选择来满足您的需求。其中之一是浅克隆 repo A,但根据the documentation

浅层存储库有许多限制(您不能克隆或从中获取,也不能从中推送或进入),但如果您只对历史悠久的大型项目的近期历史感兴趣,并且会希望将修复作为补丁发送。

无法执行基本的网络选项,例如从浅层 repo 推送和获取,这听起来像是一个很大的限制,所以我认为下一个选项可能更适合你。您可以尝试从提交master~29 开始创建一个孤儿分支,而不是创建一个浅层回购,然后在其之上重新提交master~28..master

git checkout --orphan root master~29
git add .
git commit -m "Add your message here"

这将启动你的孤立分支,新的根提交包含你在提交master~29 处的历史状态。接下来,您需要将后代提交重新设置为基础(这将保留历史记录,但提交日期除外,因为重新设置必须更新):

git rebase --preserve-merges --onto root master~29 master
# or `-p` for short
git rebase -p --onto root master~29 master

这将在您的新根目录之上重建 master 的其余部分,同时保留所有合并提交。如果你想确认master这个新版本和旧版本一样,只是历史更短,那么在rebase之后立即做一个diff:

git diff master@{1} master

我强烈建议您先测试另一个克隆

Documentation for orphan branches.

【讨论】:

  • 谢谢!你的孤儿分支策略对我有用。请注意,我对存储库A 执行了所有上述命令,然后我将git pull 编辑为AB。出于某种原因,有一些合并冲突需要处理,但没有什么是我无法处理的。
猜你喜欢
  • 2015-09-14
  • 1970-01-01
  • 2016-09-25
  • 1970-01-01
  • 1970-01-01
  • 2019-04-15
  • 2011-06-05
  • 2011-07-04
  • 1970-01-01
相关资源
最近更新 更多