git - Git - 在特定提交之前压缩历史中的所有提交
问题描述
我有一个正在转换为 Git 的 Mercurial 存储库。提交历史非常大,我不需要新仓库中的所有提交历史。一旦我将提交历史记录转换为 Git(并且在推送到新的 repo 之前),我想将某个标记之前的所有提交压缩为一个提交。
所以,如果我有:
commit 6
commit 5
commit 4
commit 3
commit 2
commit 1 -- First commit ever
我想结束:
commit 6
commit 5
commit X -- squashed 1, 2, 3, 4
注意:我需要压缩数千个提交。因此,不能一个一个地手动选择/标记它们。
解决方案
到目前为止,其他答案建议变基。在某些情况下,这可能会起作用,具体取决于转换为 Git 存储库中的提交图。新的鸽友变基--rebase-merges
绝对可以做到。但这是一种笨拙的方式。执行此操作的理想方法是从您要保留的第一个提交开始转换提交。 也就是说,让您的 Mercurial 导出器导出到 Git,作为 Git 的第一次提交,您想要假装的修订是根。让 Mercurial 导出器继续导出该提交的后代,一次一个到导入器,就像导出器总是要做这项工作一样(不管是什么方式)。
您是否以及如何做到这一点取决于您用于转换的工具。(我实际上并没有进行任何这些转换,但大多数人似乎都使用hg-fast-export
and git fast-import
。我没有看太多的内部细节,hg-fast-export
但没有明显的原因它不能这样做。)
从根本上(内部),Mercurial 将提交存储为变更集。Git不是这种情况:Git 存储的是快照。但是,Mercurial通过根据需要将变更集汇总在一起来检查(即提取)快照,因此,如果您的工具通过 do hg checkout
(或其内部等效项)工作,那么首先这里没有问题:您只需避免检查修订在您想要的第一个快照之前,并将它们导入 Git,生成的 Git 历史记录将从所需的点开始。
但是,如果您使用的工具使这不方便,请注意,在将整个存储库历史记录(包括所有分支和合并)转换为 Git 快照后,您的Git存储库会相对容易地进行第二次操作。例如,您的 Git 历史可能如下所示:
o-..-o o--o <-- br1
/ \ /
...--o--o--....--o--*--o--o--o--o <-- br2
\ / \
o--...--o o <-- master
其中 commit*
是您希望在 Git 存储库中看到的第一个提交。(请注意,如果有多个历史可以追溯到之前*
,那么您会遇到不同的问题,并且如果没有额外的历史修改,首先就无法进行这种转换。但只要*
处于某种瓶颈,就像它在这个图,很容易在这里剪断图。)
要删除之前的所有内容*
,只需使用进行与commitgit replace
非常相似*
但没有父级的替代提交:
git replace --graft <hash-of-*>
您现在有了一个大多数 Git 将使用的替代品,而不是*
没有父提交的替代品。然后git filter-branch
使用 no-op 过滤器遍历所有分支和标签:
git filter-branch --tag-name-filter cat -- --all
或者,曾经git filter-repo
包含在 Git 中(或者如果你已经安装了它):
git filter-repo --force
(使用 : 时要小心--force
选项,filter-repo
这会破坏这个存储库中的旧历史,但在这个 csae 中,这就是我们想要的)。
这会将每个可访问的提交(包括替代*
但不包括在内)*
及其自己的历史记录复制到新提交,然后更新您的分支和标签名称。
如果使用过滤器分支,请删除refs/originals/
名称空间(有关详细信息,请参阅文档git filter-branch
),如果您愿意,可以强制早期清除原始对象(额外的提交最终会自行消失),您就完成了。
推荐阅读
- payment-gateway - 使用 ssl_recurring_flag 融合付款不起作用
- python - 无法在真实主机上使用 pyttsx3
- node.js - 通过 Shopify ScriptTag API 读取产品元字段
- sql - 现有索引计数是否会影响索引创建时间?
- javascript - 有没有办法在键盘事件中检索按下的键的显示值
- jenkins - 从 .txt 文件中提取一行并将其粘贴到 Jenkins email-ext Default-Content 字段中
- r - 如何使用数字选择数据框的列
- google-apps-script - Using authorization token from G Suite add-on for use on my api service
- c - can't figure out the sizeof(long double) in C is 16 bytes or 10 bytes
- amazon-web-services - S3 GetObjectTagging error for only subset of similar files