291

我需要将一个 mercurial 项目转换为一个 git 项目,但我想保持提交历史不变。我目前的解决方案是删除 hg 相关文件,然后 git init && 手动添加我需要的文件,但这不会保留历史记录。有什么解决办法吗?

4

8 回答 8

291

您可以尝试使用fast-export

cd ~
git clone https://github.com/frej/fast-export.git
git init git_repo
cd git_repo
~/fast-export/hg-fast-export.sh -r /path/to/old/mercurial_repo
git checkout HEAD

也看看这个 SO question


如果您使用低于 4.6 的 Mercurial 版本,adrihanu 会支持您:

正如他在评论中所说:“如果您使用 Mercurial < 4.6 并且遇到“找不到 revsymbol”错误。您需要通过在 ~/fast-export 目录中运行 git checkout tags/v180317 来更新 Mercurial 或降级快速导出。” .

于 2013-04-16T13:04:42.587 回答
99

好的,我终于解决了这个问题。这是在 Windows 上使用 TortoiseHg。如果您不使用它,您可以在命令行上执行此操作。

  1. 安装 TortoiseHg
  2. 右键单击资源管理器中的空白区域,然后转到 TortoiseHg 设置:

TortoiseHg 设置

  1. 启用hggit

在此处输入图像描述

  1. 打开命令行,输入一个目录。

  2. git init --bare .git(如果你不使用裸仓库,你会得到一个错误,比如abort: git remote error: refs/heads/master failed to update

  3. cd到您的 Mercurial 存储库。

  4. hg bookmarks hg

  5. hg push c:/path/to/your/git/repo

  6. 在 Git 目录中:(git config --bool core.bare false 不要问我为什么。关于“工作树”的东西。Git 非常不友好。我发誓编写实际代码比使用 Git 更容易。)

希望它会起作用,然后您可以从新的 git 存储库推送到非裸存储库。

于 2016-01-18T11:18:16.090 回答
81

如果您想将现有的 mercurial 存储库导入“GitHub”存储库,您现在可以简单地使用此处提供的GitHub Importer [需要登录]。无需再搞乱快速导出等(尽管它是一个非常好的工具)

您将完好无损地获得所有提交分支标签。另一件很酷的事情是,您也可以更改作者的电子邮件 ID。查看以下屏幕截图:

在此处输入图像描述

在此处输入图像描述

于 2016-01-21T13:43:24.717 回答
21

我将 Mercurial 转换为 Git 的一些经验。

1. hg-fast-export

使用 hg-fast-export 失败,我需要 --force 如上所述。接下来我得到了这个错误:

错误:无法锁定 ref 'refs/heads/stable':'refs/heads/stable/sub-branch-name' 存在;无法创建 'refs/heads/stable'

完成 hg-fast-export 后,我​​得到了一个截断的 repo。我认为这个 repo 有很多孤立的分支,hg-fast-export 需要一个有点理想化的 repo。这一切似乎有点粗糙,所以我转到了 Kiln Harmony ( http://blog.fogcreek.com/announcing-kiln-harmony-the-future-of-dvcs/ )

2. 窑

如上所述,Kiln Harmony 似乎不存在于免费级别帐户中。我可以在仅 Git 和仅 Mercurial 存储库之间进行选择,并且没有切换选项。我提出了一张支持票,如果他们回复,我会分享结果。

3.hg-git

Hg-Git mercurial 插件 ( http://hg-git.github.io/ ) 对我有用。在 Mac OSX 上仅供参考,我通过 macports 安装了 hg-git,如下所示:

  • 须藤端口安装 python27
  • sudo 端口选择 --set python python27
  • sudo 端口安装 py27-hggit
  • vi ~/.hgrc

.hgrc 需要这些行:

[ui]
username = Name Surname <me@mydomain.com>

[extensions]
hgext.bookmarks =
hggit = 

然后我成功了:

hg push git+ssh://git@bitbucket.org:myaccount/myrepo.git

4. 警告:了解你的仓库

以上所有都是生硬的工具,我只是推进,因为花了足够的时间让团队正确使用 git。

在第一次按 (3) 推送项目时,我最终发现所有新更改都丢失了。这是因为这行代码只能被视为指南:

$ hg bookmark -r default master # make a bookmark of master for default, so a ref gets created

理论上,当推送到 git 时,默认分支可以被视为 master,在我的例子中,我继承了一个 repo,他们使用“stable”作为 master 的等价物。此外,我还发现 repo 的提示是尚未与“稳定”分支合并的修补程序。

如果没有正确理解 Mercurial 和要转换的 repo,最好不要进行转换。

我执行以下操作以使 repo 准备好进行第二次转换尝试:

hg update -C stable
hg merge stable/hotfix-feature
hg ci -m "Merge with stable branch"
hg push git+ssh://git@bitbucket.org:myaccount/myrepo.git

在此之后,我在 git 中有一个可验证的等效项目,但是我之前提到的所有孤立分支都消失了。我不认为这太严重,但我很可能会因为疏忽而后悔。因此,我最后的想法是无论如何都要保留原件。

编辑:如果你只想要 git 中的最新提交,这比上面的合并更简单:

hg book -r tip master
hg push git+ssh://git@bitbucket.org:myaccount/myrepo.git
于 2015-12-13T19:38:42.253 回答
11

我有一个类似的任务要做,但它包含了一些其他答案没有充分涵盖的方面:

  • 我想转换我的回购的所有(在我的情况下:两个,或一般来说:多个)分支。
  • 我的提交消息和文件名中有非 ASCII 和(作为 Windows 用户)非 UTF8 编码字符(对于好奇:德语变音符号)。

我没有尝试 fast-export 和 hg-fast-export,因为它们要求你的机器上有 Python 和一些 Mercurial Python 模块,而我没有。

我确实用 TortoiseHG 尝试了 hg-init,这个答案给了我一个好的开始。但看起来它只转换当前分支,而不是一次全部转换(*)。所以我阅读了hg-init 文档这篇博文并添加了

[git]  
branch_bookmark_suffix=_bookmark

到我的 mercurial.ini,并做到了

hg bookmarks -r default master  
hg bookmarks -r my_branch my_branch_bookmark  
hg gexport

(对要转换的每个分支重复第 2 行,如果在执行第 3 行之前碰巧进行了另一次提交,请再次重复)。git这会在 中创建一个文件夹.hg,结果是一个包含所有导出分支的裸 Git 存储库。我可以克隆这个 repo 并根据需要拥有一个工作副本。

或者几乎...

跑步

git status

在我的工作副本上,所有名称中包含非 ASCII 字符的文件都显示为未跟踪文件。所以我继续研究并遵循了这个建议

git rm -rf --cached \*  
git add --all
git commit 

最后,回购准备好被推送到 Bitbucket :-)

我还尝试了此答案中提到的 Github 导入器。我使用Bitbucket作为源系统,Github做得很好,它自动转换了所有的分支。但是,它在我的提交消息(Web-UI 和本地)和文件名(仅限 Web-UI)中显示所有非 ASCII 字符的“?”字符,虽然我可以如上所述修复文件名,但我不知道如何处理提交消息,所以我更喜欢 hg-init 方法。如果没有编码问题,Github 导入器将是一个完美且快速的解决方案(只要您有一个付费的 Github 帐户,或者可以容忍您的存储库是公开的,只要将其从 Github 拉到您的本地机器)。


(*) 所以看起来我发现我必须为我要导出的所有分支添加书签之前。如果你这样做并推送到一个(!)回购,就像链接的答案说的那样,你会得到所有的分支。

于 2016-10-06T22:06:36.077 回答
10

从:

http://hivelogic.com/articles/converting-from-mercurial-to-git

迁移

这是一个相对简单的过程。首先我们下载 fast-export(最好的方法是通过它的 Git 存储库,我将直接克隆到桌面),然后我们创建一个新的 git 存储库,执行迁移,并检查 HEAD。在命令行上,它是这样的:

cd ~/Desktop
git clone git://repo.or.cz/fast-export.git
git init git_repo
cd git_repo
~/Desktop/fast-export/hg-fast-export.sh -r /path/to/old/mercurial_repo
git checkout HEAD

当您的项目在运行快速导出后迁移时,您应该会看到一长串提交。如果您看到错误,它们可能与不正确指定的 Python 路径有关(请参阅上面的注释并为您的系统自定义)。

就是这样,你完成了。

于 2013-04-16T13:06:03.797 回答
7

另一种选择是创建一个免费的 Kiln 帐户—— git 和 hg 之间的 kiln 往返行程,具有 100% 的元数据保留,因此您可以使用它进行一次转换或使用您喜欢的任何客户端访问存储库。

于 2013-04-16T13:34:08.280 回答
2

这会更好作为评论,抱歉我没有评论权限。

@mar10 评论是我需要这样做的缺失部分。

请注意,“/path/to/old/mercurial_repo”必须是文件系统上的路径(不是 URL),因此您必须先克隆原始存储库。– mar10 2013 年 12 月 27 日 16:30

此评论是关于为我解决此问题的答案,https://stackoverflow.com/a/10710294/2148757,这与此处标记为正确的答案相同,https://stackoverflow.com/a/16037861 /2148757

这将我们的 hg 项目转移到了 git,并且提交历史记录完好无损。

于 2016-06-16T15:21:03.423 回答