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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43550302/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 12:43:02  来源:igfitidea点击:

What is the base branch when a new one is created?

gitgithubbranch

提问by Alexander Fradiani

I need to confirm/correct my assumptions when creating branches. If I'm in master branch, after doing:

创建分支时,我需要确认/纠正我的假设。如果我在 master 分支,执行以下操作后:

git checkout -b some_branch

it means I have started a new branch from master.

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

On the other hand, if I checkout another branch, and create a branch there:

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

git checkout some_branch
git checkout -b other_branch

This means I've created other_branch using all the current code committed from some_branch, right?

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

And, regardless of the current branch, if this is done:

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

git branch branch_2 branch_1

Then branch_2 will be created using branch_1 as the base. Are these assumptions correct?

然后将使用 branch_1 作为基础创建 branch_2。这些假设正确吗?

回答by torek

There is no such thing in Git as a base branchof a branch. Instead, there is only a current commit, which Git calls the tip of the branch.

Git 中没有分支基础分支这样的东西。相反,只有当前提交,Git 将其称为分支尖端

Drawing the graph

绘制图形

To understand this visually, as it were, you should start by drawing (at least part of) Git's commit graph. Here's an example of a tiny repository with just three commits in it:

为了直观地理解这一点,您应该从绘制(至少部分)Git 的提交图开始。这是一个只有三个提交的小型存储库示例:

A <-B <-C   <--master

The "true name" of any given commit is one of those big ugly hash IDs, c0ffeeface1deadbead...and so on. This hash ID uniquely identifies the specific commit, and in fact is madeby hashing (hence the name "hash ID") the contentsof that commit. They look random and are impossible to remember, so here I just use single uppercase letters.

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

The way Git "sees" the graph is that it starts by reading a branch name, such as master. This branch name contains the hash IDof a commit like C. We say that masterpoints tocommit C.

Git“看到”图形的方式是它从读取分支名称开始,例如master. 此分支名称包含提交的哈希 ID,如C. 我们说那master指向commit C

Meanwhile, commit Citself contains the hash ID of its previous (or parent) commit B. So we say that Cpoints to B, the same way masterpoints to C.

同时, commitC本身包含其先前(或父级) commit的哈希 ID B。所以我们说C指向B,同样的方式master指向C

Likewise, commit Bpoints back to A. Ais the very first commit ever, so there's nowhere for it to point back to ... so it just doesn't. We call Aa rootcommit, and it lets us (and Git) stop working backwards.

同样,提交B点回到A. A是有史以来的第一次提交,所以它无处可指……所以它没有。我们称A一个承诺,它让我们(和Git)停止向后工作。

These internal arrows are kind of annoying to draw, and note that the hash ID of Bis actually part ofCitself, so it can never change (if we try to change this part of C, we get a new, differentcommit). So we can stop bothering drawing them, and write instead:

这些内部箭头画起来有点烦人,请注意 的哈希 IDB实际上C其自身的一部分,因此它永远不会改变(如果我们尝试更改 的这部分C,我们会得到一个新的、不同的提交)。所以我们可以停止绘制它们,而是写:

A--B--C   <-- master

the arrow coming out of a branch name, though, is notconstant, and that's where this whole idea of the tip commitcomes from.

未来一出箭支的名字,不过,是不是恒定的,而这也正是在这种整体思路提示提交从何而来。

Suppose we want to add a new commit to master. We do all the usual setup that Git requires (add or modify some files and use git add) and then run git commit. Git:

假设我们要向master. 我们执行 Git 所需的所有常规设置(添加或修改一些文件并使用git add),然后运行git commit. 吉特:

  • Writes out a new commit D(which gets a new, unique hash ID). This new commit points back to C:

    A--B--C     <-- master
           \
            D
    
  • Then, changesmaster(or more precisely, its stored hash ID) so that it points to the new commit we just made:

    A--B--C
           \
            D   <-- master
    

    and of course there's no reason to keep this kink in the drawing anymore:

    A--B--C--D   <-- master
    
  • 写出一个新的提交D(它获得一个新的、唯一的哈希 ID)。这个新的提交指向C

    A--B--C     <-- master
           \
            D
    
  • 然后,更改master(或更准确地说,其存储的哈希 ID),使其指向我们刚刚进行的新提交:

    A--B--C
           \
            D   <-- master
    

    当然,没有理由再在绘图中保留这个扭结了:

    A--B--C--D   <-- master
    

So this is how branches grow, in Git.

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

To make a newbranch, Git simply creates the branch name pointing to some existing commit:

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

A
 \
  B
   \
    C
     \
      D   <-- master

We can pick any one of these commits and make a new branch name point there. Let's pick Band make newbrpoint there:

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

A
 \
  B   <-- newbr
   \
    C
     \
      D   <-- master

We would do this with git branch newbr <thing-that-finds-B>.

我们会用git branch newbr <thing-that-finds-B>.

But how do we find a commit?

但是我们如何找到一个提交呢?

How do we find B? Well, one way is to run git logand cut-and-paste the hash ID. But another way is to use a branch name. The name newbrnow points to B. If we want to make another branch point to commit Btoo:

我们如何找到B?嗯,一种方法是运行git log并剪切并粘贴哈希 ID。但另一种方法是使用分支名称。该名称newbr现在指向B. 如果我们也想让另一个分支点提交B

git branch thirdbr newbr

This makes Git look up newbr, which points to B, and create the new name thirdbr, which ... also points to B:

这使得 Git 查找newbr,指向B,并创建新名称thirdbr,它...也指向B

A--B   <-- newbr, thirdbr
    \
     C--D  <-- master

This is why creating a branch in Git is so bleeping fast: it does almost nothing at all! It just makes a label that points to some existing commit.

这就是为什么在 Git 中创建分支如此快速的原因:它几乎什么都不做!它只是制作一个指向某个现有提交的标签。

The commit to which some branch-name points is called the tip commitof that branch. Note that one commit can be the tip of several branches at the same time. This is part of a larger thing about Git: some commits are on manybranches, all at the same time. For instance, commit A—the root commit—is on everybranch. (It's possible to have more than one root commit in a repository, although it's a bit tricky, and we don't need to worry about that now. You can't do it with the commands shown this far.)

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

What makes branch names special

是什么让分支名称特别

The special property of branch labels, though, is that they move. Not only do they move, they move automatically.

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

We already saw this when we made new commit D. Git wrote the new commit's ID into master. But: How did Git know to use master?For that matter, how did Git know to make D's parent be C?

我们在进行 new commit 时已经看到了这一点D。Git 将新提交的 ID 写入master. 但是:Git 怎么知道使用master就此而言,Git 怎么知道 makeD的父母是C

Well, of course we only had one branch at the time, but let's make a new commit now, now that we have three labels master, newbr, and thirdbr. First, though, let's do git checkout thirdbr, and draw the result:

嗯,当然我们只是在当时一个分支,但让我们做一个新的承诺,现在,现在我们有三个标签masternewbrthirdbr。首先,让我们做git checkout thirdbr,并得出结果:

A--B   <-- newbr, thirdbr (HEAD)
    \
     C--D  <-- master

Nothing really changed in the drawing,1except that I added the word HEADhere. HEAD is how Git knows which branch-and-commit are the currentbranch and commit.

绘图中没有什么真正改变,1除了我在HEAD这里添加了这个词。HEAD 是 Git 知道哪个分支和提交是当前分支和提交的方式。

So now we do our usual modify-some-files, git add, and git commit. Git writes out the new commit, with its parent set to commit B. Git sees that the currentbranch is thirdbrand thirdbrpoints to B, so the current commitis B. Let's draw in the new commit E:

所以现在我们做我们通常的修改一些文件git add、 和git commit。Git 写出新提交,其父项设置为 commit B。Git 看到当前分支是thirdbr并且thirdbr指向B,所以当前提交B。让我们绘制新的提交E

     E
    /
A--B   <-- newbr
    \
     C--D  <-- master

The only thing left is to move the current branch namethirdbrso that it points to new commit E:

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

     E   <-- thirdbr (HEAD)
    /
A--B   <-- newbr
    \
     C--D  <-- master

and we're all done: we've added a new commit to branch thirdbr(which is still HEAD, and hence still the current branch, but now Eis the current commit).

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

When you add a commit to the current branch, it's HEAD that tells what the current commit was and where the new commit goes.HEAD normally contains the name of a branch, and that's what git checkoutdoes: it checks out a specific commit—usually, the tip commit of an existing branch—and then sets up the file HEADto remember the nameof the branch. It's the branch name itself that remembers the tip commit.

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

Using git checkout -b newnamecommitmeans: "check out the specified commit, then make a new branch name newnamethat points to that commit, and then set HEAD to that new name." If you leave out the commitpart, the default is to use HEAD. Since HEAD is(always) the current commit, Git gets to skip the "check out" part and just create the new branch name and store it into the HEADfile.

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



1While nothing changed in the graph, Git did have to update our work-tree, and the index, so that we could have the files as of the way they were at commit B.

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