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
What is the base branch when a new one is created?
提问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 master
points tocommit C
.
Git“看到”图形的方式是它从读取分支名称开始,例如master
. 此分支名称包含提交的哈希 ID,如C
. 我们说那master
指向commit C
。
Meanwhile, commit C
itself contains the hash ID of its previous (or parent) commit B
. So we say that C
points to B
, the same way master
points to C
.
同时, commitC
本身包含其先前(或父级) commit的哈希 ID B
。所以我们说C
指向B
,同样的方式master
指向C
。
Likewise, commit B
points back to A
. A
is the very first commit ever, so there's nowhere for it to point back to ... so it just doesn't. We call A
a 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 B
is actually part ofC
itself, 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 toC
:A--B--C <-- master \ D
Then, changes
master
(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 B
and make newbr
point there:
我们可以选择这些提交中的任何一个,并在那里创建一个新的分支名称。让我们在那里挑选B
并newbr
指出:
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 log
and cut-and-paste the hash ID. But another way is to use a branch name. The name newbr
now points to B
. If we want to make another branch point to commit B
too:
我们如何找到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:
嗯,当然我们只是在当时一个分支,但让我们做一个新的承诺,现在,现在我们有三个标签master
,newbr
和thirdbr
。首先,让我们做git checkout thirdbr
,并得出结果:
A--B <-- newbr, thirdbr (HEAD)
\
C--D <-- master
Nothing really changed in the drawing,1except that I added the word HEAD
here. 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 thirdbr
and thirdbr
points 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 namethirdbr
so 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 E
is 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 checkout
does: it checks out a specific commit—usually, the tip commit of an existing branch—and then sets up the file HEAD
to 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 newnamecommit
means: "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 HEAD
file.
使用方法是:“检查指定的提交,然后创建一个指向该提交的新分支名称newname,然后将 HEAD 设置为该新名称。” 如果省略提交部分,则默认使用 HEAD。由于HEAD是(总是)当前提交,Git会得到跳过“退房”的一部分,只是创建新的分支名,并将其存储到文件中。git checkout -b newnamecommit
HEAD
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
。