我有一个git repo,其程序源代码为v2.0作为初始导入,如
v2.0(master) - o - o - ...
我可以在v2.0初始导入提交之前创建v1.0代码的分支吗?像:
v1.0 - o - o - ...
\
v2.0(master) - o - o - ...
答案 0 :(得分:2)
简短的回答是否定的。
长答案是有益的:在Git中,分支名称只是指向提交的指针。这意味着,无论您的意思是什么,"分支" -see What exactly do we mean by "branch"? - 您都无法拥有一个没有至少一个提交的分支在它上面。
此外,这张图基本上是错误的:
v2.0(master) - o - o - ...
这意味着分支名称位于左侧,新提交一次一个地增长到右侧。确实,新提交做一次一个地增长到右边 - 但分支名称也位于右侧!也就是说,名称master
最初指向您的第一个提交。你从一个完全空的存储库开始:
master (HEAD)
名称HEAD
存在并附加到分支名称master
,但分支本身不存在,因为没有提交! 1 < / sup>分支名称必须指向现有的有效提交,并且根本没有。
最后,你进行了第一次提交,Git立即将名称master
指向它。提交有一些很难看的哈希ID,实际上是提交内容的加密校验和 - 取决于你的名字和电子邮件地址,存储在该提交下的所有文件,以及日期和时间,使其基本上无法预测 - 但让我们称之为A
:
A <-- master (HEAD)
然后,过了一段时间,你做了一个新的提交。我们在这里称它为B
。新提交B
记录了提交A
的实际哈希ID,因此我们说B
指向 A
:
A <-B
此时分支名称的变化是关键。名称master
停止指向提交A
,因为Git会立即使用新提交master
的新哈希ID覆盖B
:
A <-B <-- master (HEAD)
此时,如果您创建新的分支名称,则可以将其设置为指向这两个现有提交之一。然后,您可以将名称HEAD
附加到其中:
A <-B <-- master, xyz (HEAD)
现在,如果您进行新的提交,请将其称为C
- 新提交将指向B
,Git将写入C
&#39;将哈希ID分配到附加HEAD
的名称:
A <-B <-- master
\
C <-- xyz (HEAD)
请注意,提交A
永远不会指向任何其他提交:提交一旦进行,就是只读的。提交A
没有父,它将永远保持这种状态。
(您可以随时制作一系列新的和不同的提交,Git会让您更改所有分支名称以指向完全新的和不同的提交提交,所以你可以进入并创建:
G--H--I <-- branch-for-v1
\
J--K--L <-- master (HEAD)
永久保留A-B-C
提交,最终这三个提交已过期并被删除 - 但这并不是更改提交A-B-C
,这些提交仍由它们的实际哈希ID,无论它们是什么。这个想法的一般术语 - 制作全新的提交链,然后使分支名称指向新链而不是旧链 - 被称为重写历史。如果概念有效,那么它就是这样做的,因为我们人类只是从 name 所指向的任何提交开始,并且就像Git一样,通过这些向后指向的内部提交箭头向后工作。 )
1 这意味着如果你问Git你在哪个分支上(git status
会告诉你),它会说master
,但如果你问Git哪些分支存在,它会告诉你 no 分支存在。你确实在一个不存在的分支上。 Git不同地称之为未出生的分支或孤儿分支。至少在我看来,前者实际上是更好的名称;名称&#34;孤儿分支&#34;是一个我们一直困扰的错误,因为有人在Git的开发过程中早早搞砸了。