2013-07-02 61 views
2

我们正在开发一个巨大的项目。在开发初期,我们决定使用Mercurial以及子库特征。经过2年的发展,我们有10个独立的模块,每个模块都有一个存储库。我们发现,子库不是我们的最佳解决方案,并且还发现Git对我们比Mercurial更好。Git:重写历史以使用相同的消息和时间提交崩溃提交(合并子模块)

所以,我们要:1。 水银加入到subrepositories一个主要 Mercurial库与保留完整的历史 2.转换此主要库来的Git仓库(也有保存历史)

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

第二步也是使用快速导出/ 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: -AFK-BGK-CHK-DIL-EJM-----> 

所以一个承诺应该在几个模块代表分组的变化。

问题:

  1. 是否有可能由任何单一命令的Git崩溃各组在历史上一个提交的?这些提交具有相同的时间,消息和作者。

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

  2. 如果它是不可能有一个的Git命令做的,那么是不是可以编写基于几个的Git命令的脚本?

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

在此先感谢。

回答

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
+0

不,它不是 - autosquash需要'fixup!'或'squash!'在提交信息中。 – Chronial

+0

我们的回购仅约5000个提交和700Mb的大小,所以git可以轻松处理这个问题。 –

0

对此没有单一命令。您需要使用filter-branchcommit-filter。这里有您需要的部分:

  1. 运行git log -1 --pretty=format:'%H %ct %P' --full-history --all获得的提交,它们的时间戳和他们的父母的解析的列表。
  2. 编写一个脚本,查找同一时间​​非合并提交字符串的最后:对于每个提交,检查它的父代是否具有相同的时间戳并且不合并(=只有一个父本身)。如果是,请将其添加到“删除”列表中。
  3. 您的提交过滤器将获得提交的内容及其父提交(请参阅git help filter-branch)。从(2)你应该有你需要的所有信息存储在某个地方。只保留最后一个的一串相同时间提交,通过呼叫skip_commit所有其他人和git commit-tree(无参数)为你想保留的。

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

+0

我已更新问题。你的解决方案是否仍然适用?无论如何,感谢您的回复:) –