创建新分支时的基本分支是什么?

Ale*_*ani 15 git branch github

我需要在创建分支时确认/更正我的假设.如果我在主分公司,做完之后:

git checkout -b some_branch
Run Code Online (Sandbox Code Playgroud)

这意味着我已经从master开始了一个新的分支.

另一方面,如果我签出另一个分支,并在那里创建一个分支:

git checkout some_branch
git checkout -b other_branch
Run Code Online (Sandbox Code Playgroud)

这意味着我使用some_branch提交的所有当前代码创建了other_branch,对吧?

并且,无论当前分支如何,如果这样做:

git branch branch_2 branch_1
Run Code Online (Sandbox Code Playgroud)

然后使用branch_1作为基础创建branch_2.这些假设是否正确?

tor*_*rek 21

在Git中没有这样的东西作为分支基本分支.相反,只有一个当前提交,Git称之为分支提示.

绘制图形

要理解这一点,你应该从绘制(至少部分)Git的提交图开始.这是一个只有三个提交的小型存储库的示例:

A <-B <-C   <--master
Run Code Online (Sandbox Code Playgroud)

任何给定提交的"真实名称"是那些丑陋的哈希ID之一,c0ffeeface1deadbead...依此类推.该散列ID唯一地识别特定的提交,并且实际上是通过散列(因此命名为"散列ID")的内容的该提交.它们看起来是随机的,不可能记住,所以在这里我只使用单个大写字母.

Git"看到"图形的方式是它通过读取分支名称开始,例如master.此分支名称包含提交的哈希IDC.我们说master 提交C.

同时,commit C本身包含其先前(或)提交的哈希ID B.所以我们说CB,以同样的方式master指向C.

同样,提交B点返回A. A是有史以来第一次提交,所以没有任何地方可以指向......所以它不会.我们称A一个承诺,它让我们(和Git)停止向后工作.

这些内部箭头有点令人讨厌,并注意到哈希ID B实际上 C其自身的一部分,所以它永远不会改变(如果我们试图改变这一部分C,我们会得到一个新的,不同的提交).所以我们可以停止打扰它们,然后写:

A--B--C   <-- master
Run Code Online (Sandbox Code Playgroud)

出来一个的箭头分行的名称,不过,是不是恒定的,而这也正是在这种整体思路提示提交从何而来.

假设我们要添加一个新的提交master.我们执行Git所需的所有常规设置(添加或修改某些文件并使用git add),然后运行git commit.Git的方法:

所以这就是Git中分支增长的方式.

要创建一个分支,Git只需创建指向某个现有提交的分支名称:

A
 \
  B
   \
    C
     \
      D   <-- master
Run Code Online (Sandbox Code Playgroud)

我们可以选择其中任何一个提交,并在那里创建一个新的分支名称.让我们来挑选Bnewbr指出:

A
 \
  B   <-- newbr
   \
    C
     \
      D   <-- master
Run Code Online (Sandbox Code Playgroud)

我们会这样做git branch newbr <thing-that-finds-B>.

但是我们如何找到提交?

我们怎么找到B?好吧,一种方法是运行git log并剪切并粘贴哈希ID.但另一种方法是使用分支名称.这个名字newbr现在指向B.如果我们想要另一个分支点也提交B:

git branch thirdbr newbr
Run Code Online (Sandbox Code Playgroud)

这使Git查找newbr,指向B并创建新名称thirdbr,其中......也指向B:

A--B   <-- newbr, thirdbr
    \
     C--D  <-- master
Run Code Online (Sandbox Code Playgroud)

这就是为什么在Git中创建一个分支的速度非常快:它几乎什么都没做!它只是制作一个指向某个现有提交的标签.

一些分支名称点的提交称为该分支的提示提交.请注意,一次提交可以同时是几个分支的提示.这是关于Git的一个更大的事情的一部分:一些提交在许多分支上,所有这些都在同一时间.例如,提交A- 根提交 - 在每个分支上.(它可能在存储库中有多个root提交,虽然它有点棘手,我们现在不需要担心.你不能用到目前为止显示的命令来做到这一点.)

是什么让分支名称特别

然而,分支标签的特殊属性是它们会移动.它们不仅会移动,而且会自动移动.

我们在做出新提交时已经看到了这一点D.Git将新提交的ID写入master.但是:Git是如何使用的master 就此而言,Git是如何让D父母知道的C

嗯,当然,我们只是在当时一个分支,但让我们做一个新的承诺,现在,现在我们有三个标签master,newbrthirdbr.首先,让我们做git checkout thirdbr,并绘制结果:

A--B   <-- newbr, thirdbr (HEAD)
    \
     C--D  <-- master
Run Code Online (Sandbox Code Playgroud)

在图中,在没有真正改变1不同的是我加的话HEAD在这里.HEAD是Git知道哪个分支和提交是当前分支和提交的方式.

所以现在我们做我们通常的修改 - 文件git add,和git commit.Git写出了新的提交,其父设置为commit B.Git看到当前分支是thirdbrthirdbr指向B,所以当前提交B.让我们在新提交中绘制E:

     E
    /
A--B   <-- newbr
    \
     C--D  <-- master
Run Code Online (Sandbox Code Playgroud)

剩下的唯一事情就是移动当前的分支名称 thirdbr,使其指向新的提交E:

     E   <-- thirdbr (HEAD)
    /
A--B   <-- newbr
    \
     C--D  <-- master
Run Code Online (Sandbox Code Playgroud)

我们都完成了:我们已经为分支添加了一个新的提交thirdbr(它仍然是HEAD,因此仍然是当前分支,但现在E是当前的提交).

当您向当前分支添加提交时,它是HEAD,它告诉当前提交是什么以及新提交的位置. HEAD通常包含分支的名称,这就是git checkout:它检查特定的提交 - 通常是现有分支的提示 - 然后设置文件HEAD以记住分支的名称.这是分支名称本身,它记住了提示提交.

使用方法:"检查指定的提交,然后创建一个指向该提交的新分支名称newname,然后将HEAD设置为该新名称." 如果省略提交部分,则默认使用HEAD.由于HEAD (总是)当前提交,Git会得到跳过"退房"的一部分,只是创建新的分支名,并将其存储到文件中.git checkout -b newname commitHEAD


1虽然没有在改变图形,Git的根本需要更新我们的工作树和索引,这样我们就可以有文件作为他们在提交的方式B.

  • github 和其他来源上有引用“基本”分支的文档... (2认同)