Git推出了包含主内容的新分支

时间:2018-01-31 16:20:01

标签: git mercurial

我通过以下方式将回购从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分支。

3 个答案:

答案 0 :(得分:1)

It's still not clear what your actual question is,所以我会为你做一件事:

Git如何在两个不同的分支中拥有相同的提交? (Mercurial可以&#39; t。)

这样做的原因是,在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都为一个新的,完全空的存储库执行此操作:第一个提交创建当前分支(通常为defaultmaster)。

在Mercurial中,这一切都非常简单和自动:你创建一个新的提交;它的分支是记录的当前分支&#34;是;如果这是第一次在分支xyzzy上创建提交,那么,现在xyzzy上至少有一个提交,因此存在xyzzy

但是当Git创建一个新的分支xyzzy并且 一些现有的提交和分支时,Git只是立即创建xyzzy,指向当前的提交。我们之前说过你在master,并且刚刚创建了xyzzy。名称xyzzymaster现在指向相同的提交:现在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目录:

  • hg clone http:mercurial.com ./hgclone

初始化git目录:

  • git init git-dir
  • cd git-dir

  • 将mercurial迁移到git: hg-fast-export -r ../ hgclone

  • git checkout HEAD
  • 添加git存储库: git remote add origin $ remoterepo
  • 添加当前目录: git add。
  • 提交: git commit -m“初始提交”
  • 推送: git push -u origin master

列出要创建的分支并将其更新到远程git-directory    - git branch

结帐并将分支添加到远程git目录:

  • git checkout 分支
  • git add。
  • git push origin refs / heads / branch :refs / heads / branch

这是我将mercurial存储库导出到git并将它们与正确的分支存储到远程git存储库的基本步骤。