Chr*_*oba 5 git merge branch git-branch
我目前有一个 git 提交树,看起来像这样,括号中带有指针(?):
* 305f Merge branch 'develop' (HEAD->master, origin/master, origin/HEAD)
|\
| * d97b Some other commit on dev branch (develop)
| * df14 Some commit on dev branch
|/
* 7a761b6 Initial commit
Run Code Online (Sandbox Code Playgroud)
我已将 master 分支推送到远程(Gitlab,如果重要的话),当我在 Gitlab UI 中查看 master 分支上的提交时,所有 4 个提交都存在,而我原本期望只有“合并分支 'develop” '”和“初始提交”提交出现在主分支上。
我的理解是,它master指的是我刚刚列出的两个提交,而develop指的是“其他一些...”,“一些提交...”,也可能是“初始提交”,因为它是祖先。
我哪里错了?
在某些版本控制系统中,当您在分支B上提交C时,提交C永远在分支B上。任何获得提交C的人都会获得分支B。如果他们之前有自己的分支B,那么现在他们的分支B中有一个新的提交C。
\n\nGit不这样做。提交不会永久附加到分支。然而,提交大多是永久性的,1并且永久地固定在它们出现在提交图中的位置。为了使这项工作正常进行,并没有在任何分支上真正进行提交。相反,分支名称只是一个标签。多个标签可以都指向同一个 commit,如下所示:
\n\n\n\n\nRun Code Online (Sandbox Code Playgroud)\n* 305f Merge branch 'develop' (HEAD->master, origin/master, origin/HEAD)\n
这里master和origin/master2都标识 commit 305f。br2如果您现在创建一个新分支,该名称也将指向 commit 305f。
Commit305f有两个父级:(7a761b6它的第一个父级)和d97b(它的第二个父级)。的全名305f是其完整哈希 ID 的值。这一点永远不会改变;并且该哈希 ID 永远保留给该提交,该提交始终具有相同的两个父代。该承诺将永远冻结并且永远不会移动。
Git 中移动的东西是分支名称。目前,master意味着305f. 然而,刚才的master意思是7a761b6。提交永远保留在原位,如通过其原始哈希 ID 发现的那样。分支名称四处移动。
所有这一切的结果是,当我们创建和销毁分支名称时,包含一些提交的分支集会动态更改。此时,该名称master可以让您找到所有四个提交。master如果您允许 Git以 Git 喜欢的方式移动名称,那么这四个提交将继续可访问,方法是305f从其两个父级开始,然后查看其父级d97b(然后从d97b您返回到7a761b6您已经锯)。请注意,新提交只会添加到图表中。一般来说,每个新提交都会有一些现有提交作为其父级\xe2\x80\x94,如果它是典型提交,则它是唯一的父级,如果它是合并提交,则它是两个父级之一。3
如果我们把这些东西画在侧面,就会容易一些。为了让它变得更简单,我们可以使用单个大写字母来代替 Git 使用的难以理解的哈希 ID:
\n\n D--E <-- br1\n /\nA--B--C\n \\\n F--G <-- br2\nRun Code Online (Sandbox Code Playgroud)\n\n在这里,名称br1允许我们找到 commit E,它会找到D、then C、then B、then A(并停止,因为A这是第一次提交)。该名称br2允许我们找到G、then F、then C、then B、then A(然后停止)。因此,前三个提交都在两个分支上,而两个提交每个都只有一个分支。
删除名称 br1会导致提交D并E变得无法找到。最终 Git 会真正把它们扔掉。git checkout br1如果我们通过执行 、 、git add、 和来添加新的提交git commit,我们会得到一个新的哈希 IDH并提前名称br1以包含它:
D--E--H <-- br1\n /\nA--B--C\n \\\n F--G <-- br2\nRun Code Online (Sandbox Code Playgroud)\n\n现在有 6 个提交可以从 到达br1,从 开始H并向后进行。如果我们创建一个新名称br3来记住位置E,我们将需要重新绘制图形:
H <-- br2\n /\n D--E <-- br3\n /\nA--B--C\n \\\n F--G <-- br2\nRun Code Online (Sandbox Code Playgroud)\n\n请注意,所有提交实际上都没有改变:我们只是H向上推,为标签腾出空间br3。
如果我们稍后删除该名称 br3,那也没关系:没有通过唯一br3找到的提交。提交E不会消失,因为br1找到了H哪个找到了E。
1主要是通过可达性实现的。您可以从某个分支或标记名称开始查找提交,这些名称提供原始哈希 ID。然后,找到提交后,您可以使用其父哈希 ID 来查找其前任提交。然后你使用这些提交来找到他们的父母,等等。
\n\n通过从每个引用执行此过程\xe2\x80\x94see脚注2\xe2\x80\x94Git找到所有可到达的提交。存储库中存在的任何提交(此过程无法访问)最终都会被垃圾收集并删除。
\n\n2该名称master是分支机构名称。它的全名是 real refs/heads/master,全名开头的名称refs/heads/是分支名称。相比之下,origin/master实际上是一个远程跟踪名称:它的全名以 开头refs/remotes/,然后继续说origin/master。Git 有时只删除refs/该名称的一部分,以便您看到remotes/origin/master.
标签(如果有的话)位于refs/tags/. 这些东西统称为refs或references。reflogs中还保存了其他隐藏的引用。reflog 只是一个日志文件,保存值\xe2\x80\x94(之前的哈希 ID\xe2\x80\x94),这些值在您或 Git 更新之前存储在 ref 中。这些引用日志条目最终会过期,这就是故意放弃的提交\xe2\x80\x94(您已替换为具有新哈希 ID 的新改进版本(例如\xe2\x80\x94))最终被清除的原因。
3合并提交的技术定义是它至少有两个父项。因此,您也可以创建具有 3 个或更多父级的合并提交\xe2\x80\x94,但很少有理由这样做。我还应该提到的是,可以创建一个没有父提交的新提交。除了第一个提交\xe2\x80\x94(我A在横向图形绘图中标记\xe2\x80\x94)之外,在正常实践中你也不会这样做。
| 归档时间: |
|
| 查看次数: |
1306 次 |
| 最近记录: |