将Mercurial项目转换为Git

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

123814 次浏览

你可以尝试使用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来降级快速导出。

来自:

http://hivelogic.com/articles/converting-from-mercurial-to-git < a href = " http://hivelogic.com/articles/converting-from-mercurial-to-git " > < / >

迁移

这是一个相对简单的过程。首先下载快速导出(最好的方法是通过它的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路径有关(请参阅上面的说明并为您的系统自定义)。

就这样,你完成了。

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

将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后,我最终得到了一个被截断的回购。我认为这种回购有很多孤立的分支,hg-fast-export需要一种有点理想化的回购。这一切似乎有点粗糙的边缘,所以我转移到窑和谐(http://blog.fogcreek.com/announcing-kiln-harmony-the-future-of-dvcs/)

2. 窑

窑和谐似乎不存在一个免费层帐户如上所述。我可以在Git-only和mercury -only回购之间进行选择,并且没有切换的选项。我提出了支持票,如果他们回复,我会分享结果。

3.hg-git

Hg-Git mercurial插件(http://hg-git.github.io/)确实为我工作。在Mac OSX上,我通过macports安装hg-git,如下所示:

  • Sudo端口安装python27
  • Sudo端口选择——设置python python27
  • Sudo端口安装py27-hggit
  • 六世~ / . 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,在我的情况下,我继承了一个回购,他们使用“稳定”作为等效的主。此外,我还发现回购的尖端是一个尚未与“稳定”分支合并的修补程序。

如果不能正确理解Mercurial和要转换的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

好吧,我终于算出来了。这是在Windows上使用TortoiseHg。如果你不使用它,你可以在命令行上做。

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

TortoiseHg Settings

  1. 启用hggit:

enter image description here

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

  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回购推到一个非裸的。

如果你想将你现有的mercurial存储库导入到“GitHub”存储库中,你现在可以简单地使用GitHub进口国可用的在这里[需要登录]。没有更多的混乱fast-export等(虽然它是一个非常好的工具)

你将得到所有的提交分支机构标签完整。还有一件很酷的事情是,你也可以改变作者的电子邮箱。看看下面的截图:

enter image description here

enter image description here

这将是一个更好的评论,对不起,我没有评论权限。

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

注意,'/path/to/old/ mercural_repo '必须是文件系统上的路径(而不是URL),因此您必须在此之前克隆原始存储库。- 13年12月27日3月10日16:30

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

这将我们的hg项目移动到git,提交历史完整。

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

  • 我想转换我的repo的所有分支(在我的情况下:两个,或一般情况下:不止一个)。
  • 在我的提交消息和文件名中,我有非ascii和(作为Windows用户)非utf8编码的字符(好奇的是:德语变音)。

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

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

[git]
branch_bookmark_suffix=_bookmark

到我的mercury .ini,并且做了

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

(对于你想要转换的每个分支重复第二行,如果你碰巧在执行第三行之前做了另一次提交,再重复一次)。这将在.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拉到你的本地机器)。


(*)所以它看起来像之前我发现我必须收藏所有我想要导出的分支。如果你这样做并推到裸露的(!)回购,就像链接的答案所说的那样,你会得到所有的分支。