将Mercurial项目转换为Git

299

我需要将一个Mercurial项目转换为Git项目,但我希望保留提交历史记录。我的当前解决方案是仅删除与hg相关的文件,然后git init &&手动添加所需的文件,但这样无法保留历史记录。有没有解决办法?


1
一个用于检出和跟踪mercurial仓库的git-hg工具。 https://github.com/offbytwo/git-hg - MGP
2
你也可以尝试使用Kiln Harmony,它会保留仓库的git和mercurial版本并同步所有内容,因此可以从两者中使用。 - Wilbert
2
更好的方法 https://github.com/buchuki/gitifyhg - sorin
3
@Ian 和其他人,这不是一个重复的问题,另一个问题是关于迁移特定文件夹的,而这个问题是关于整个代码库的。尽管已经在那个问题中发布了回答,但这是一个不同的问题。它应该被标记为相关问题。 - simgineer
4
仅供参考,Kiln Harmony已经停止使用。 - Tim Friesen
显示剩余2条评论
8个回答

298

您可以尝试使用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 问题


如果您使用的是低于4.6版本的 Mercurial,则adrihanu可以帮上您的忙:

正如他在评论中所述:"如果您使用的是Mercurial < 4.6并且出现了"revsymbol not found"错误,请更新您的Mercurial或通过在~/fast-export目录中运行git checkout tags/v180317来降级 fast-export。"


8
另外提醒,如果您需要将Mercurial作者映射到Git作者,请使用作者映射文件 -A - David Mohundro
12
如果您还没有安装Mercurial,请在执行第5步之前进行安装。http://mercurial.selenic.com/ - Kevin Zych
7
如果你遇到了"repository has at least one unnamed head"这样的错误,你可以使用--force选项来处理损坏的树。 - iurii
19
默认情况下无法在Windows上直接运行,因此对于97%的人来说可能也没有用 - 可能值得提一下,在这种情况下你可以使用Cygwin或类似工具(即使是这样也有隐藏的依赖关系)。 - jheriko
7
@jheriko 的工具不能直接在 Windows 上使用,因此可能有 97% 的人无法使用。你提到的这个数字(97%)来自于2005年的数据。 - Attila Fulop
显示剩余15条评论

104

好的,我终于搞清楚了。这是在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存储库推送到非裸库。


3
我遇到了推送错误:“dulwich.errors.RefFormatError: refs/heads/ref”。原来是因为我有几个书签。删除每个书签后,推送就成功了。 - GaTechThomas
11
根据hg-git文档,“TortoiseHg附带了hg-git”并且只需要启用它(如上所示)。然而,在Mercurial命令行版本中不包括它(如果需要,可以安装)。如果您同时安装了TortoiseHg和HG,请确保使用来自TortoiseHg的hg.exe,而不是来自命令行安装的版本。如果出现错误_No module named hggit_,请尝试完全限定hg命令:"C:\Program Files\TortoiseHg\hg" push c:/path/to/your/git/rep. - Javaru
2
请注意,此方法似乎只导入当前检出的分支(我正在寻找一种导入整个存储库的解决方案)。 - robyaw
12
hg bookmark -r default master” 比“ hg bookmarks hg ”更好吗? - Heikki
7
要让文件出现在仓库中,请执行以下操作:git checkout hg - user984003
显示剩余3条评论

82
如果您想将现有的mercurial存储库导入到"GitHub"存储库中,您现在可以使用GitHub Importer此处需要登录)。不再需要使用fast-export等工具来导入(尽管这是一个非常好的工具)。
您将获得所有的提交(commit)分支(branches)标签(tags)。更酷的是,您还可以更改作者的电子邮件地址(author's email-id)。请查看下面的截图: enter image description here enter image description here

它是否还迁移问题和维基页面? - thomthom
@thomthom 不仅提交,还有分支和标签。 - atulkhatri
3
在Github上创建私有存储库需要付费计划。当然,如果您要转换的是公共源代码树,那就没有问题了。 - Åsmund
@atulkhatri 谢谢你!本来我打算使用快速导出,但是看到 GitHub 可以解决这个问题! - Tommy
5
你知道如何上传和转换本地的Mercurial代码库吗? - xslittlegrass
显示剩余3条评论

21

我在将Mercurial转换为Git的过程中做了一些笔记。

1. hg-fast-export

使用hg-fast-export失败了,我需要像上面提到的那样使用--force选项。接下来我遇到了以下错误:

error: cannot lock ref 'refs/heads/stable': 'refs/heads/stable/sub-branch-name' exists; cannot create 'refs/heads/stable'

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

2. Kiln

如上面建议的那样,在免费帐户上似乎不存在Kiln Harmony。我可以选择只使用Git或Mercurial存储库,没有切换选项。我提交了一个支持票,并将分享结果(如果他们回复我的话)。

3. hg-git

Hg-Git Mercurial插件(http://hg-git.github.io/)对我起作用了。FYI,在Mac OSX上,我通过macports安装了hg-git如下:

  • sudo port install python27
  • sudo port select --set python python27
  • sudo port install 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花费了足够长的时间。

在第三步中首次推送项目后,我发现所有新更改都丢失了。这是因为这行代码必须被视为仅供参考:

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

理论上,在推送到git时,可以将默认分支视为主分支,而在我的情况下,我继承了一个将“stable”用作主分支等效的存储库。此外,我还发现该存储库的末端是一个尚未与“stable”分支合并的热修复。

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

为了使存储库准备好进行第二次转换尝试,我进行了以下操作:

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

6
Fog Creek回复了我的支持工单,确认Kiln Harmony不再可用。 - Dion Truter
http://blog.fogcreek.com 出现了SSL证书错误。我不信任那些无法正确处理SSL协议却仍然这样做的人。 - The incredible Jan

13

我有一个类似的任务需要完成,但其中一些方面并没有被其他答案充分覆盖:

  • 我想要转换所有(在我的情况下:两个,或者通常来说:多个)分支。
  • 我的提交消息和文件名中包含非ASCII字符和(作为Windows用户)非UTF8编码的字符(对于好奇的人来说:德语umlauts)。

我没有尝试使用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行之前再次重复。这将在.hg文件夹内创建一个名为git的文件夹,其中包含所有导出的分支的裸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拉到本地机器的时间内保持公开)。
(*)所以它看起来就像在我发现我必须收藏我想要导出的所有分支之前。如果您这样做并将其推送到 (!) repo,就像链接的答案所说,您将获得所有分支。

1
为了解决使用hg-fast-export(不确定是否适用于github导入器)时的编码问题,您可以像这样传递参数“e”:-e cp1251。 - Pavel
为了解决使用hg-fast-export时的文件名编码问题,您可以使用'--fe'选项,例如--fe cp1251。 - Sandre
每个你想转换的分支都要重复第二行?!真的吗?我有一个很大的旧代码库,里面有很多功能分支,都应该保留... - The incredible Jan

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
您应该会看到在运行fast-export之后,您的项目被迁移时出现了大量的提交列表。如果您看到错误,它们可能与未正确指定Python路径有关(请参见上面的注释并根据您的系统进行自定义)。
就这样,您完成了。

2
这对我有用,但我必须添加一步。fast-export仅适用于最新版本的Mercurial(无法通过apt获得),因此您必须手动安装一个闪亮的新Mercurial> 4.6或通过在上面添加“git checkout 19aa906”作为新步骤3来降级fast-export以获取到最后一个可用的提交。 - Paul K
hivelogic.com已经不存在了。 - The incredible Jan

6

另一个选择是创建一个免费的Kiln账户——Kiln可以在Git和Hg之间进行往返转换,并保留100%的元数据,因此您可以将其用于一次性转换或使用它来访问您喜欢的任何客户端的存储库。


6
如何使用窑炉进行转化? - Ofer Helman
Kiln代码仓库既可被Git又可被Hg使用。因此,您可以从一个客户端导入,然后随意多次从另一个客户端导出。 - Michael Shaw
4
Kiln Harmony在它存在的时候非常好用,但它已于2016年9月关闭。(此外,Kiln的免费套餐将于下个月关闭。) - Josh
1
Kiln最近被出售,自此以来停机时间很长。他们的状态页面并没有反映出大部分情况,但这种情况大约每个月会发生一次。只有在您绝对需要Mercurial且找不到其他主机时才建议使用。 - Josh Noe

2

很抱歉我没有评论权限,否则这将更好。

@mar10的评论是我实现此操作所需的关键部分。

请注意,“/path/to/old/mercurial_repo”必须是文件系统上的路径(而不是URL),因此您必须先克隆原始存储库。 - mar10 Dec 27 '13 at 16:30

这个评论是针对解决我的答案的,https://dev59.com/zmgv5IYBdhLWcg3wSe62#10710294 这个答案与在这里标记为正确的答案相同,https://dev59.com/fWQo5IYBdhLWcg3wdPK8#16037861

这将我们的hg项目移动到了git,并保留了提交历史记录。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接