2

我们正在做一个巨大的项目。在开发之初,我们决定使用带有子存储库功能的Mercurial 。经过 2 年的开发,我们有 10 个独立的模块,每个模块都有一个存储库。我们发现,子存储库对我们来说不是最好的解决方案,并且还发现GitMercurial更适合我们。

因此,我们想要: 1. 将 mercurial 子存​​储库加入一个mercurial 存储库,并保留完整历史记录 2. 将此存储库转换为Git存储库(也保留历史记录)

第一步已经完成(在 stackoverflow 上有一个很好的答案),对每个子存储库使用 hg-convert 扩展并将它们合并为一个。

第二步也完成了,使用 fast-export/hg-fast-export 工具。而且...一切都很好,除了一件事。由于带有子存储库的 Mercurial 具有使用一个命令提交到所有子存储库的功能,因此我们经常使用它。现在历史看起来是这样的:

commit c6a33eb195c574cfa81469f2109c0840852a5571
Author: John
Date:   Mon Jul 1 20:26:14 2013 +0200

Add another one feature

commit fc5390a726847ef2971edd591020c5c1d2aa168b
Author: John
Date:   Mon Jul 1 20:26:14 2013 +0200

Add another one feature

commit 2477c27b361657dabeb28802f5f510f170378fc0
Author: John
Date:   Mon Jul 1 20:26:14 2013 +0200

Add another one feature

原因是这些提交中的每一个都来自不同的原始子存储库。我们的历史树看起来像这样:

subrepo_1/master: -A-B-C-D-E--EJ---EJM---merged---->
                              /     /
subrepo_2/master: -F-G-H-I-J--     /
                                  /
subrepo_3/master: -K-----L-M------

因此,来自不同子模块的主分支完全分离。如果我签出例如提交F,则工作目录不包含来自 *subrepo_1* 和 *subrepo_3* 的任何代码。

我们希望只有一个 master 分支,应该是这样的:

master: -AFK-BGK-CHK-DIL-EJM----->

所以一个提交应该代表几个模块中的分组更改。

问题:

  1. 是否可以通过使用Git的任何单个命令将历史记录中的每组提交折叠为一个?这些提交具有相同的时间、消息和作者。

    注意:“git rebase -i”似乎不是一个解决方案,因为我们有太多的提交来手动进行压缩。

  2. 如果一个Git命令无法完成,那么是否可以基于几个Git命令编写脚本?

  3. 我的想法(感谢@Chronial 的回复)是:收集所有主分支的提交列表并按时间排序,从列表中挑选每个提交到新的干净分支。然后使用 filter-branch 和 commit-filter 过滤每组具有相同时间/消息的提交,只留下一个。可以吗?

提前致谢。

4

2 回答 2

1

没有单一的命令。您需要filter-branchcommit-filter. 以下是您需要的部分:

  1. 运行git log -1 --pretty=format:'%H %ct %P' --full-history --all以获取可解析的提交列表、它们的时间戳和它们的父项。
  2. 编写一个脚本,查找一串同时非合并提交中的最后一个:对于每个提交,检查其父级是否具有相同的时间戳并且不是合并(=自己只有一个父级)。如果是这样,请将其添加到“要删除”列表中。
  3. 您的提交过滤器将获得提交及其父提交的 shas(请参阅 参考资料git help filter-branch)。从 (2) 开始,您应该将所需的所有信息存储在某个地方。通过调用所有其他提交和(都没有参数)你想要保留的提交,只保留一串同时提交中的最后一个。skip_commitgit commit-tree

我会忽略合并,因为它们会使事情复杂化,我假设您真的没有合并的问题?

于 2013-07-02T23:14:39.473 回答
0

解决方案之前我的第一个问题:这 10 个模块有多大?Git 对于一个庞大的存储库并不是那么好。相反,建议完全按照您现在的情况进行:许多子模块。在完成迁移之前考虑一下。请参阅此讨论:http ://comments.gmane.org/gmane.comp.version-control.git/189776

关于你的问题:

  1. 我认为使用--autosquash参数是可能的。请参阅: http: //mcpierce.blogspot.com.br/2012/08/git-fixup-and-autosquash.html
于 2013-07-02T21:56:34.467 回答