首页 > 解决方案 > git:将一个存储库的(cherry-pick)历史记录复制到另一个存储库的目录中

问题描述

我有两个回购。第一个回购(我们称它为A)不久前开始;第二个回购(B)是最近开始的。现在我们想我们宁愿让 B 成为 A 的子目录。所以我想这样做,但保留 B 的提交历史。

在完成任何操作后,我希望满足三个标准:

  1. HEAD在B 中看到的文件和目录位于A 的子目录中,即/path/to/repoB/somefile.js/path/to/repoA/B/somefile.js
  2. B 的所有提交消息按顺序显示在 A 提交的时间结束处
  3. 每个提交的差异都是可用的(可通过git log等查看)

一些例子可以澄清我的意图:

  1. 在 repo B 中,commit 1 是添加file.txt
  2. 提交 2 是编辑file.txt
  3. 所以在 repo A 中,我想要两个新的提交:
  4. 回购 A 提交 98:添加B/file.txt
  5. 回购 A 提交 99:编辑B/file.txt

编辑:

已提议合并子目录中的 git 存储库作为我的问题的副本。我承认它与我的要求非常接近,并且有几个很好的答案。我在那里尝试了subtree答案,以及rebase --onto答案。两者都非常接近,但都不令人满意:subtree不允许在不提及(我将 B 移入的位置)git log的情况下查看存储库历史中的历史;并且没有使 B 的历史从 A 中可见。path/to/file/without/repo-subdirrepo-subdirrebase --ontoHEAD

标签: git

解决方案


这就是我最终做的事情。感谢Freenode (IRC) 中的atrusfrom引导我朝着正确的方向前进。#git

  1. 在 repo B中,创建一个新分支:git checkout -b indir
  2. 在 repo B,中,我打算让 B 在 A 的目录树中结束的目录mkdir b-subdir在哪里。b-subdir
  3. 在 repo B 中,将git mv [...] b-subdir所有内容(除了自身)移动到..git/b-subdir/b-subdir
  4. 将这一举动提交给回购 B。
  5. 推到原点 ( push -u origin HEAD)。
  6. 在回购 A 中git remote add repo-b ssh://......../repo-b.git
  7. git fetch repo-b
  8. git merge --allow-unrelated-histories repo-b/indir

这使我可以查看来自 repo B 的任意文件的完整历史记录(使用 的--follow开关git log) ,而无需从文件路径中删除b-subdir/前缀。使用git subtree,如果你去掉它,你只会在 B 中看到文件的历史记录(如果你不这样做,你会在 A 中看到历史记录)。


推荐阅读