在执行git checkout -b时,当前分支是否重要?

时间:2018-01-23 11:28:16

标签: git

如果我在创建新分支C之前在分支A或分支B中是否重要?

这样做:

git checkout A
git pull
git checkout -b "C"

给出与以下相同的结果:

git checkout B
git pull
git checkout -b "C"

4 个答案:

答案 0 :(得分:2)

分支只是指向提交的指针,branch / checkout -b创建一个分支,指向与您当前所在分支相同的提交 - 所以你确实很重要

答案 1 :(得分:1)

他们不一样。在第一种情况下,您从分支C分支A,而在第二种情况下,您从分支C分支B

答案 2 :(得分:1)

git checkout -b C

git checkout -b C HEAD

是平等的。

您碰巧检查过的分支没有任何关联。如果分支A和分支B指向同一个提交,则两个案例是相同的。

但是,如果你这样做:

git checkout -b C A

git checkout -b C B

然后它们不再相等,即使分支A和B指向同一个提交。当一个分支作为第三个参数给出时,它被设置为要跟踪的上游分支。

答案 3 :(得分:1)

你现在有几个正确的答案,但我认为你仍然感到困惑。绘图可能有所帮助。

在Git中,每个提交都有一个"真实名称":它的哈希ID。您现在已在git log输出中看到了这些哈希ID。它们大而丑,在Git的Git存储库中看起来像随机一样提交36438dc19dd2a305dddebd44bf7a65f1a220075b - 它们通常对人类没用,但它们是Git本身如何定位提交,因此它们非常重要。

但仅仅是人类更喜欢名称。所以我们有master这样的名字:分支名称。分支名称只存储其中一个哈希ID。哈希ID本身提交;名称master会为我们记住 36438dc19dd2a305dddebd44bf7a65f1a220075b,因此我们只需要记住master

现在,无论何时进行 new 提交,新提交都会获得一个新的唯一哈希ID。让我们先来看看这是如何发生的,以及分支名称master会发生什么。

假设我们从一个只有三个提交的小型存储库开始,那三个提交'哈希ID为ABC。提交C本身会记住哈希标识B - 该C提交 - 并且B会记住{ {1}}作为自己的父母。作为第一个提交的提交A具有父级。这个术语的技术术语是 root commit ,虽然你不需要记住它(但是当你第一次出现时,你会在Git&#39的输出中看到它在一个新的空库中提交。)

名称A当然会为我们记住master,所以这就是现在整个事情的样子:

C

我们说A <-B <-C <-- master 指向 masterC指向CB指向{{1} }}。 B的父级为AB的父级为A的事实嵌入CB {1}}他们自己。提交必须总是指向后方,所以我们可以在没有箭头的文本中更容易地绘制它:

B

分支名称,例如C,但移动。让我们看看当我们添加新提交A--B--C <-- master 时会发生这种情况:

master

新提交获取一个新的哈希ID,对我们来说幸运的是D而不是一些实际可怕的长提交哈希。 [do some work, so that we have something to commit] $ git add -u # pick up all the updates $ git status [git status output] $ git commit -m 'some message' [git commit output] 指向D,因为我们开始时D C的提示:

C

但现在master需要记住A--B--C--D ,而不是master,因为D现在是C的提示。因此,Git将哈希标识D放入master

D

分支名称指向提交,因此 new 分支名称必须指向提交

所以,让我们假设我们有一个更大的存储库,其中有十几个提交:

master

(好的,11次提交,如果他们以A--B--C--D <-- master 开头)。名称...--F--G--H <-- master \ I--J--K <-- develop 标识(指向)一个特定提交 - A,现在 - 名称master指向另一个特定提交,H

如果我们要创建一个 new 分支名称,例如develop,我们必须选择一些提交,以指向

我们现在说K正如feature所说的那样。 Git知道这一点的方式是特殊名称on branch master是&#34;附加到&#34; git status

HEAD

如果我们运行master,Git会创建新名称...--F--G--H <-- master (HEAD) \ I--J--K <-- develop ,然后通过将git checkout -b feature附加到该分支来切换到该分支。 当前提交feature在这里保持不变。

HEAD

让我们说我们现在进行第12次提交,获取哈希ID H。 Git通过附加...--F--G--H <-- master, feature (HEAD) \ I--J--K <-- develop 的事实知道要更新的分支

L

请注意HEAD没有移动:当我们进行新提交时,只有附加 L <-- feature (HEAD) / ...--F--G--H <-- master \ I--J--K <-- develop 的名称会移动。

如果我们希望我们的新提交master在提交HEAD之后提交,那么现在很清楚我们应该L,因为K会说,当我们命名为on branch develop时。然后我们开始:

git status

和以前一样,但先做feature,这会同时做两件事:

  • 检查提交...--F--G--H <-- master (HEAD) \ I--J--K <-- develop ,而不是提交git checkout develop
  • 将名称K附加到H

现在看起来像这样:

HEAD

已提交的内容已更改,但我们现在develop,我们当前的提交为...--F--G--H <-- master \ I--J--K <-- develop (HEAD) ,而不是on branch develop。现在,如果我们使用当前的提交创建一个新的分支K,我们就会得到这个:

H

我们现在准备像以前一样进行新的提交。不过,这一次,我们最终会:

feature

作为Martin said in his answer,您实际上可以组合&#34;交换机提交&#34;和&#34;创建新分支&#34;使用...--F--G--H <-- master \ I--J--K <-- develop, feature (HEAD) 迈出一大步。也就是说,如果您在...--F--G--H <-- master \ I--J--K <-- develop \ L <-- feature (HEAD) (提交git checkout -b new-name commit-specifier)并且希望master从提交H开始,则可以使用:

feature

告诉Git:*我想创建K,但不是我现在的位置,我想切换到名称git checkout -b feature develop 标识的提交创建feature并同时将develop附加到feature。*

首先这可能会令人困惑

每隔一段时间停止并提取部分提交图确实很有帮助。请记住,在Git中,一旦您进行提交,该提交就永远不会被改变。这个哈希ID,就像HEAD一样无用,对于人类而言,具体地识别 提交,永远!您对存储库所做的任何操作都不会改变这一点,feature仍然始终 提交。

提交本身是永久性的,不变的。分支名称移动。 Git 通过从分支名称开始查找提交 - 从提交中找到分支提示提交 - 并向后工作到父母,然后到父母的父母,依此类推。 (你可以洗牌分支名称,以便某些现有的提交不再能够找到。实际上,这会放弃提交.Git最终通常会在30天或更长时间后 - 删除它是真的,之后它真的消失了。但是在那之前,哈希ID仍然可以找到它,只要你在某处写下了哈希ID。)

对于(更多),请参阅Think Like (a) Git