我正在尝试查看我所在的分支,但它不起作用......
$ git checkout -b test
Switched to a new branch 'test'
$ git branch
$ git branch -a
$
那是因为你还没有提交任何东西,当你做
git checkout -b test
时,git将.git/HEAD
文件的内容从ref: refs/heads/master
修改为ref: refs/heads/test
,实际上什么也没有指向。只有在您进行提交后,git 才会为您创建 test
引用,您将找到一个 .git/refs/heads/test
文件,其中包含您刚刚所做的提交的哈希值。
这个问题现在有一些重复的链接,所以我想我应该对 neevek 接受的答案 进行一些扩展。具体来说,我们可以说为什么存在未出生的分支的概念。
让我们从这个开始:虽然 Git has 分支,并在其中提交 have 文件,但 Git 并不是真正的 about 分支或文件。 Git 的本质就是提交。
Git 存储库中的提交是有编号的,但这些数字有点奇怪。不是简单的计数——提交#1,然后是#2,然后是#3,依此类推——每个数字都是一个看起来随机的哈希ID。这些实际上根本不是随机的:现在它们都是 SHA-1 哈希值,尽管 Git 正在逐渐获得使用其他哈希值的能力(从 SHA-256 开始)。但无论如何,每次提交都会获得一个唯一的编号,该编号通常会缩短为看起来仍然随机的字母和数字序列,例如
a1f9371
或 053af72
或其他。
当您创建一个新存储库(使用
git init
,或通过克隆空存储库)时,其中还没有提交。这应该是完全合理的:提交是通过您创建提交的操作而存在的,或者,当您使用 git clone
时,通过从其他现有 Git 存储库中复制,它拥有的所有提交。
分支名称的棘手部分是分支名称的工作方式是它保存one提交的哈希ID。我们不会详细说明 Git 如何找到所有previous 提交,但确实如此。这里的要点是,要存在分支名称,它必须保存某些现有提交的哈希 ID。
哈希 ID 是不可预测的。除此之外,您所做的任何新提交的哈希 ID 都精确地取决于您进行提交的时间。因此无法提前知道第一次提交的随机哈希 ID 是什么。 由于分支名称
具有来保存某些有效的现有提交的哈希ID,并且空存储库没有提交,因此也不允许存在任何分支名称!因此,空存储库没有分支(当然也没有提交)。然而,在一个新的存储库中,您“在”一个分支上。你怎么可能在一个不存在的分支上?
Git 对这个困境的回答是把你放在一个“未出生的分支”上。你当前的分支就是这个未出生的分支。您可以选择任何您喜欢的其他未出生分支名称,使用 git checkout -b
切换到其他未出生分支名称。以前未出生的名字仍然不存在,现在已经被遗忘了。
当您在这个新存储库中进行第一次提交时,now分支名称可以存在。 Git 将未诞生的分支的名称创建为有效的分支名称,并在该名称中存储您刚刚创建的新提交的哈希 ID。而且,既然存在一个提交,您现在可以根据需要创建任意多个分支名称。所有名称都必须保存该提交的哈希 ID,直到您创建第二个提交,此时每个名称都可以保存第一个提交的 ID 或第二个提交的 ID。但在那种特殊状态下,当根本没有提交时,也不能有分支名称。
请注意,除了这种特殊情况之外,git checkout
还可以让您创建一个new未出生的分支。其标志是
--orphan
(而不是
--unborn
),但 git checkout --orphan name
所做的是将您置于未出生分支状态,当前分支名称为 name
,因此 next您创建的提交将创建该分支的名称。这将生成一个新分支,其历史记录仅包含单个新提交,因此新分支的历史记录与同一存储库中任何其他分支名称的历史记录无关。这种模式很少有任何特殊用途,但它始终可用,因为新的空存储库需要这种未出生的分支状态。 使用下面的 zsh,这个还在任何提交之前显示分支名称
function parse_git_branch() {
git symbolic-ref HEAD 2> /dev/null | awk 'BEGIN{FS="/"} {print $NF}'
}
COLOR_DEF=$'%f'
COLOR_USR=$'%F{243}'
COLOR_DIR=$'%F{197}'
COLOR_GIT=$'%F{39}'
setopt PROMPT_SUBST
export PROMPT='${COLOR_USR}%n ${COLOR_DIR}%~ ${COLOR_GIT}$(parse_git_branch)${COLOR_DEF} $ '