git - git:将一个存储库的(cherry-pick)历史记录复制到另一个存储库的目录中
问题描述
我有两个回购。第一个回购(我们称它为A)不久前开始;第二个回购(B)是最近开始的。现在我们想我们宁愿让 B 成为 A 的子目录。所以我想这样做,但保留 B 的提交历史。
- 我想要完整的提交历史。即我不想只是将 B 的历史压缩到一个补丁中并将其作为 A 中的新提交丢弃。
- 我不在乎保留 B 的确切 SHA1(我知道这可能是不可能的)。
- 我不在乎保留 B 提交的时间戳(尽管这样会很好)。
- 我不在乎保留作者身份。
- 我只想保留 B 的每个提交的差异/补丁。
- 我不在乎保留两个独立存储库的任何概念。事实上,我希望只有 A 继续前进。
- 我不需要 B 是 A 的 git 子模块,它有自己的
.git
目录或类似的东西。
在完成任何操作后,我希望满足三个标准:
HEAD
在B 中看到的文件和目录位于A 的子目录中,即/path/to/repoB/somefile.js
在/path/to/repoA/B/somefile.js
- B 的所有提交消息按顺序显示在 A 提交的时间结束处
- 每个提交的差异都是可用的(可通过
git log
等查看)
一些例子可以澄清我的意图:
- 在 repo B 中,commit 1 是添加
file.txt
- 提交 2 是编辑
file.txt
- 所以在 repo A 中,我想要两个新的提交:
- 回购 A 提交 98:添加
B/file.txt
- 回购 A 提交 99:编辑
B/file.txt
编辑:
已提议合并子目录中的 git 存储库作为我的问题的副本。我承认它与我的要求非常接近,并且有几个很好的答案。我在那里尝试了subtree
答案,以及rebase --onto
答案。两者都非常接近,但都不令人满意:subtree
不允许在不提及(我将 B 移入的位置)git log
的情况下查看存储库历史中的历史;并且没有使 B 的历史从 A 中可见。path/to/file/without/repo-subdir
repo-subdir
rebase --onto
HEAD
解决方案
这就是我最终做的事情。感谢Freenode (IRC) 中的atrus
from引导我朝着正确的方向前进。#git
- 在 repo B中,创建一个新分支:
git checkout -b indir
- 在 repo B,中,我打算让 B 在 A 的目录树中结束的目录
mkdir b-subdir
在哪里。b-subdir
- 在 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
git fetch repo-b
git merge --allow-unrelated-histories repo-b/indir
这使我可以查看来自 repo B 的任意文件的完整历史记录(使用 的--follow
开关git log
) ,而无需从文件路径中删除b-subdir/
前缀。使用git subtree
,如果你去掉它,你只会在 B 中看到文件的历史记录(如果你不这样做,你会在 A 中看到历史记录)。
推荐阅读
- javascript - 为什么 touch 方法不能接收到 className 的参数?
- azure-web-app-service - Blazorhosted ASP.NET Core 3 作为 Azure 应用服务
- c++ - 静态初始化插件工厂
- javascript - 如何在不同的页面有来自你的不同评论
- javascript - 如何从 javascript 字符串的末尾删除可变数量的字符
- google-apps-script - 从 A1 表示法转换为字符串/列表表示法?
- oracle - PL/SQL 记录填充
- xml - XSLT 使用单引号
- c# - 如何枚举 NVMe (M2) 驱动器并在 c# 中获取它们的温度?
- flutter - 页面重新加载后 Flutter StreamBuilder 无法正常工作