听起来你来自 svn...主干只是另一个分支...就像你可能创建的任何其他分支一样。通常在 svn 中称为 trunk 的东西在 git 上称为master,但实际上,这是一个约定,因为没有强制要求在存储库上有一个 master 分支,只是大多数存储库都有它......并且你可能有一个git 中的分支称为 trunk,如果你喜欢的话。
Git 没有“主干”(尽管如果您愿意,您可以假装任何特定分支是您的“主干”)。
\n\n就此而言,从某种意义上说,Git 也没有分支。这实际上完全取决于您如何定义分支。请参阅“分支”到底是什么意思? 当然,如果我们以更有用的方式定义分支这个词,Git确实有分支。它们与 SVN 分支有很大不同。
\n\n有趣的是,从某种意义上说,SVN 本身也没有分支。这是红豆书里的一段话:
\n\n\n\n\n您应该记住本节中的两个重要教训。首先,Subversion 没有分支\xe2\x80\x94 的内部概念,它只知道如何制作副本。当您复制目录时,生成的目录只是 \xe2\x80\x9cbranch\xe2\x80\x9d,因为您附加了该含义。您可能会以不同的方式看待该目录,或者以不同的方式对待它,但对于 Subversion 来说,它只是一个普通的目录,恰好携带一些额外的历史信息。
\n
对于 Git,要记住的重要一点是 Git 的核心就是提交。提交是 Git 的主要主题。每次提交都包含源代码的完整快照,以及一些元数据:有关提交的信息。每个提交都有一个唯一的哈希 ID,1保留给该提交并且仅保留给该提交。例如,b697d92f56511e804b8ba20ccbe7bdc85dc66810Git 本身的 Git 存储库的任何克隆中的提交都是 Git 2.22。任何地方的其他提交都不会具有该哈希 ID。2
因为每个提交都有一个唯一的哈希 ID,所以我们\xe2\x80\x94 或至少 Git\xe2\x80\x94 可以谈论或找到仅给出哈希 ID 的提交。因此,一般来说,每个提交都会在其元数据中存储其他较早提交的哈希 ID。具体来说,我们\xe2\x80\x94或Git\xe2\x80\x94最关心的早期提交是该提交的直接父级的哈希ID:紧邻该提交之前的提交。
\n\n请注意,当我们进行新的提交时,我们确切地知道 哪个提交应该出现在我们现在正在进行的新提交之前。那是因为我们通过检查一些现有的提交来进行新的提交。git checkout然后我们处理该提交并执行git add命令并运行git commit。新提交应该将我们签出的提交的哈希 ID 作为其父提交。
让我们快速了解一下它是如何工作的。但是提交哈希 ID 又大又难看,人类无法使用(除非通过剪切和粘贴),所以让我们使用单个大写字母来代表这些提交。让我们采用一个简单的小型存储库,其中包含三个提交,并将它们称为A、B、 ,C就像我们按顺序创建的那样。每个提交都存储其父级的哈希 ID,它构成了一个向后指向的提交链:
A <-B <-C\nRun Code Online (Sandbox Code Playgroud)\n\n也就是说,提交C说我的父母是B,并B说我的父母是A。 A没有父母\xe2\x80\x94它不能,这是第一次提交。其技术术语是A根提交[root commit],当您在新存储库中进行第一次提交时,您将看到Git 打印的内容。3
如果我们检查 commit C,对其进行一些工作,然后运行git commit,Git 将:
C作为此新提交的父级也放入元数据中;和因为新提交的D父级是C,所以这会自动扩展链:
A <-B <-C <-D\nRun Code Online (Sandbox Code Playgroud)\n\n当然,D得到一个提交哈希 ID,它又大又丑,而且D是唯一的,我们不可能记住它。但我们不需要记住它:这就是计算机的用途。让计算机通过以某个名称存储实际的哈希 ID 来记住它。
该名称为\xe2\x80\x94,通常\xe2\x80\x94 是一个分支名称,例如master. 也就是说,在我们make之前D,图片确实是这样的:
A--B--C <-- master\nRun Code Online (Sandbox Code Playgroud)\n\n该名称master会记住 commit 的实际哈希 ID C。我们运行git checkout master,Git 使用名称来查找 ID,并使用 ID 来查找提交,这会将内容获取到我们的工作树中,以便我们可以对其进行处理。4
我们做我们的工作并运行git add并git commit做出新的提交D。最后一步是 Git 将实际哈希 ID\xe2\x80\x94(无论它是什么)\xe2\x80\x94 写入名称中:git commitDmaster
A--B--C--D <-- master\nRun Code Online (Sandbox Code Playgroud)\n\nmaster不再记得C,而是D;但这没关系,因为D记得C。早些时候,master记得A;然后它记起来了B,它记起来了A;然后它想起来了C。现在它想起来了D。
要在 Git 中创建新分支,您只需告诉它创建一个新名称,指向某个现有的提交,如下所示:
\n\nA--B--C--D <-- master, feature\nRun Code Online (Sandbox Code Playgroud)\n\n现在的技巧是让 Git 记住在运行时要更新哪个分支名称git commit,这就是特殊名称HEAD(全部大写字母)的用武之地。当您运行时git checkout master,Git 将名称附加HEAD到名称上master:
A--B--C--D <-- master (HEAD), feature\nRun Code Online (Sandbox Code Playgroud)\n\n当您运行时git checkout feature,Git 会附加HEAD到feature:
A--B--C--D <-- master, feature (HEAD)\nRun Code Online (Sandbox Code Playgroud)\n\n两个checkout 命令 extract commit D,这是存储所有文件的位置。两个分支都有所有四个提交,此时\xe2\x80\x94,但是如果你现在进行feature新的提交,该新提交将获得一个新的又大又难看的哈希 ID,我们将其称为E。新提交作为D其父提交,并且作为 的最后一步git commit,Git 将E哈希 ID 写入其中feature,因为这是HEAD附加的位置:
A--B--C--D <-- master\n \\\n E <-- feature (HEAD)\nRun Code Online (Sandbox Code Playgroud)\n\n如果我们现在运行git checkout master,Git 将提交放D回到我们的工作树中并附HEAD加到master. 如果我们现在进行另一个新提交,则新提交的父级D再次出现,并且master这次会更新:
F <-- master (HEAD)\n /\nA--B--C--D\n \\\n E <-- feature\nRun Code Online (Sandbox Code Playgroud)\n\n这些提交\xe2\x80\x94这些向后看的链\xe2\x80\x94形成一个图,技术上是一个有向无环图。实际上,诸如master和之类的分支名称只是指向图中特定节点的标签。当您说“分支功能”时,请注意您的意思是name、 commit 、 commits + + + +或其他什么。feature featureEEDCBA
在 Git 中,分支名称只是指向一个特定提交的标签。分支本身是通过从该提交开始并通过图表向后工作来找到的。该图由提交及其父链接组成。
\n\n在SVN中,正如红豆书上所说,分支是目录的副本(加上一些元数据)。对于 Git\xe2\x80\x94 来说,情况并非如此。分支一词是不明确的,有时表示名称,即保存提交哈希 ID 的短标签,有时表示从以下位置开始找到的整个提交图的某个子集:名称中的哈希 ID。当“分支”指的是“某些提交集”时,它是那些提交,而不是某个目录。
\n\n1这些哈希 ID 实际上是提交数据(快照和元数据)的加密校验和。因此,任何提交都无法更改。如果您实际上获取原始提交数据\xe2\x80\x94,您可以通过git cat-file -p; 尝试git cat-file -p HEAD一段时间\xe2\x80\x94并对它进行一些更改并将其存储回Git,你得到的是一个新的、不同的提交,它有自己新的、唯一的哈希ID。您可以将 Git 视为包含提交的仅附加数据库。这并不完全正确,但这是一个很好的初步近似。
2从技术上讲,这仅意味着 Git 的 Git 存储库无法重复使用该哈希 ID。如果您自己的项目不是 Git 的源并且从未连接到 Git 的 Git 存储库,则可以使用该哈希 ID。很有可能永远不会:您所做的每次提交只有 2 160中的 1机会给我们该哈希 ID。2 160是一个非常大的数字:1,461,501,637,330,902,918,203,684,832,716,283,019,655,932,542,976,或者在短尺度上大约是五十分之一。
\n\n3分支名称必须指向某个现有的提交。这就产生了一个问题:在一个新的、完全空的存储库中,没有提交,因此不能有分支。这是进行第一次提交\xe2\x80\x94新存储库\xe2\x80\x94的根提交的行为,它创建了初始分支名称,通常是master。您可以稍后通过使用git checkout --orphan或使用git fetch具有不相关历史记录的另一个 Git 存储库来进行新的根提交,但典型的 Git 存储库往往只有一个根提交。每个分支上都有一个根提交!
4由于加密校验和哈希 ID,每次提交都会被永久冻结。但每次提交保存的快照也是如此。提交\xe2\x80\x94“内部”的文件从技术上来说只是 Git 对象数据库\xe2\x80\x94 中的更多对象,它们也将一直冻结,并保存在特殊的、只读的、Git-only 中,压缩格式。因为它们是只读的,所以可以在不同的提交之间共享,这节省了大量空间:您可能有一个包含 4000 个文件的项目,您更改了 2 个文件并进行了新的提交。Git 重新保存新提交中的每个文件,但其中 3998 个文件实际上只是重复使用之前的快照:只有 2 个新快照。
\n\n这对于归档很有用,但对于实际工作却毫无用处。这些文件都是这种冻干的仅限 Git 的形式,并且您的计算机需要其正常的日常形式的文件。因此 Git 必须解压冻干的文件,重新水化它们。这些重新水化的副本会进入您的工作树,您可以在其中查看并处理它们。您永远不会直接处理 Git 内的副本。
\n\n这个冷冻干燥文件并重新水化它们的过程使用了一个中间区域,Git 有时将其称为暂存区域,有时称为索引。这两个词是表示同一事物的术语。重要的是要认识到索引/暂存区域具有当前提交中每个文件的副本,并且 Git从索引/暂存区域而不是从工作树进行新提交,但我们不会在这里进一步讨论这一点。
\n| 归档时间: |
|
| 查看次数: |
4296 次 |
| 最近记录: |