我通过以下方式将回购从mercurial迁移到git:
git init gitrepo
cd gitrepo
hg_fastexport -r <../hgclone>
(我希望我没有忘记任何事情)然后我在GitLab中创建了一个存储库并在gitrepo(hg-fastexport导出源代码的地方)我创建了分支并推送它们像
git checkout -b v4.1
git push origin refs/heads/v4.1:refs/heads/v4.1
虽然这是在2个分支上工作,但它在Gitab中显示,最后一个分支总是获取主分支的内容,而不是v4.1分支。
答案 0 :(得分:1)
It's still not clear what your actual question is,所以我会为你做一件事:
这样做的原因是,在Mercurial中,提交在其分支中没有独立存在,并且分支完全由其提交组成。也就是说,每次提交都属于恰好一个分支。分支名称是一个实体,意味着&#34;每个提交的记录分支都是此实体。&#34;
相反,在Git中,提交独立于分支。提交存在或不存在,只是因为它存在或不存在。提交不会记录哪些分支(如果有)包含它。分支名称只是一(1)个哈希ID的别名,而哪个哈希ID是别名,可以随时更改。
在两个VCS中,每个提交都记录其父提交ID:如果提交是普通的非合并提交,则为一个ID,Git中至少为两个或两个以上,Mercurial中只有两个 - 如果commit是一个合并提交。这意味着在任何一个VCS中,如果给出一些特定的提交,我们可以检查该提交并找到它的父或(如果是合并)父类。然后我们可以检查父母,找到他们的父母,等等。
如果我们为Mercurial调用 head 的所有内容执行此操作,我们会在Mercurial存储库中找到所有提交。提交在有向,非循环图或DAG中充当顶点(或节点);连接这些节点的弧是父ID。我们以这种方式找到的每个提交都只在一个分支上,每个提交记录(单个)分支它。
相比之下,在Git中,我们并不真正了解 的起点。我们可以详尽地枚举整个存储库以查找所有对象(Git在其存储库数据库中有四个类型对象),挑选出所有提交对象,并从此处形成DAG。但是,这些提交有 no 分支标识:我们不知道提交的分支在哪个分支上!此外,这种详尽的枚举甚至需要很长的时间 - 在一个大型存储库中 - 所以我们几乎不会打扰。
相反,我们采用完全不同的方法:我们从存储在一个分支名称中的哈希ID开始,例如master
。使用那个分支名称,我们找到一个提交。根据定义,该提交在master
上。然后我们使用存储在该提交中的哈希ID找到提交的父级。根据定义,这些提交也在master
上。我们重复此过程,直到通过DAG跟踪了所有可到达的父弧,我们已经确定了可以从名称master
访问的每个提交,并且所有这些提交都在master
上。< / em>的
但是可能有更多的分支名称。所以我们从另一个名称开始,例如v4.1
。此名称包含一个哈希ID,用于查找提交。根据定义,该提交在v4.1
上。然后我们像以前一样找到提交者的父母。根据定义,这些提交也在v4.1
上。我们重复此过程,直到通过DAG跟踪了所有可到达的父弧,我们已经确定了可以从名称v4.1
访问的每个提交,并且所有这些提交都在v4.1
上。< / em>的
请注意,在大多数提交DAG中,通常会有一个初始提交,所有其他提交都会从该提交中继承。在Mercurial中,这一个提交位于一个分支上,可能是名为default
的分支。在Git中,这一个提交在每个分支上都是 。
因此, Git提交和Mercurial提交之间的根本区别在于Git提交同时在许多分支上。包含任何给定Git提交的分支集合是通过咨询动态确定的。 所有分支,并通过DAG跟踪所有,直到我们看到此特定提交是否来自 特定提交在分支的尖端提交。如果它以这种方式可达,它就在那个分支上;如果不是,那就不是。
在Git和Mercurial中,为了创建一个新的分支,你告诉VCS&#34;创建一个新的分支&#34;但立即行动是非常不同的,除外在一个新的空库中。 1
在Git中,要存在分支名称,名称必须标识一个特定提交。 Git称之为分支的 tip ,我们说分支名称指向该特定提交。但是在一个新的空库中,没有提交,因此不存在分支名称!
Mercurial也有类似的问题:分支包含该分支中的所有提交。在一个新的空存储库中,没有提交,因此不存在分支!
尽管如此,Git和Mercurial都有当前分支的概念。当前分支是将在其上进行 new 提交的分支。这允许两个VCS将当前分支名称记录为实际上不存在的分支。完成此操作后,创建新提交会产生创建分支的副作用。两个VCS都为一个新的,完全空的存储库执行此操作:第一个提交创建当前分支(通常为default
和master
)。
在Mercurial中,这一切都非常简单和自动:你创建一个新的提交;它的分支是记录的当前分支&#34;是;如果这是第一次在分支xyzzy
上创建提交,那么,现在xyzzy
上至少有一个提交,因此存在xyzzy
。
但是当Git创建一个新的分支xyzzy
并且 一些现有的提交和分支时,Git只是立即创建xyzzy
,指向当前的提交。我们之前说过你在master
,并且刚刚创建了xyzzy
。名称xyzzy
和master
现在指向相同的提交:现在master
之前的所有提交都在上 master
和 xyzzy
。
简而言之,这在Git中是完全正常的。在分支v1.4
上创建新提交将使新提交仅在<{>> 分支{{ 1}},至少在其他事情发生之前,其他一些分支也包含该提交。在分支上创建新提交,告诉Git set 该分支提示指向新创建的提交。新创建的提交的父ID将是前一个提示(因为这是您已签出的),因此分支现在包含它之前包含的每个提交,加上刚刚创建的新提交。
1 您可以使用v1.4
使Git更像Mercurial,但是如果您这样做,您创建的 next 提交将创建一个新的 root commit - 没有父项的新提交,在提交DAG中创建单独的子图。这几乎不是你想要的:在Git中,你想要提交同时在多个分支上。有一次你总是想要这个&#34;孤儿分支&#34;行为在一个新的空存储库中,用于创建第一个提交。
答案 1 :(得分:0)
git checkout -b v4.1
-b
告诉git 创建一个新的分支,来自当时的任何分支(可能是master
),然后切换到它,这意味着branch v4.1
将指向与源分支完全相同的提交(同样可能是master
)...
似乎您在推送之前忘记提交更改。
分支v4.1
只会在您提交后进行更改。
答案 2 :(得分:0)
我发现了我犯的错误。也许问题不是那么清楚,但是当我创建一个新分支时,分支将始终拥有主人的内容。它不包含分支。这样做的原因是,我在从汞迁移到git之后忘记了检查HEAD。似乎然后我在主人或分支上工作,但是当我忘记检查(新迁移的HEAD)时,新分支和主人的内容保持不变。
我会在这里给出一张收据,该收据可以提供正确的存储库。
克隆Mercurial目录:
初始化git目录:
cd git-dir
将mercurial迁移到git: hg-fast-export -r ../ hgclone
列出要创建的分支并将其更新到远程git-directory - git branch
结帐并将分支添加到远程git目录:
这是我将mercurial存储库导出到git并将它们与正确的分支存储到远程git存储库的基本步骤。