为什么“ git status”显示我在master分支上,而“ git branch”不在新创建的存储库中?


83

我正在尝试使过程自动化并发出git branch命令以找出我所在的分支。除了新初始化的存储库git branch什么都不返回以外,其他一切都工作正常。鉴于我对仓库没有做任何事情,甚至没有执行最初的提交,我都可以接受答案。但是,如果我运行git status它,它会告诉我我在master分支上,如下所示:

$ mkdir todelete
$ cd todelete
$ git init
Initialized empty Git repository in /u/u70021a/todelete/.git
$ git status
On branch master

No commits yet

nothing to commit (create/copy files and use "git add" to track)
$ git branch
$

难道我做错了什么?有没有我没有正确设置的设置?

我对Git也有很多新人,我无法向他们解释为什么显示他们所在的分支的命令什么都没显示,而status命令却显示。

Answers:


94

我提出了另外两个答案,但是我认为思考的方法很简单: 您可以位于不存在的分支上。 这在新的空存储库中也是正常的,因为要存在一个分支名称,该分支名称必须标识现有有效提交的哈希ID。新的空存储库没有提交,因此尚无分支名称存在。

但是,您最初是在某个分支上。您所在的分支是其名称存储在特殊名称中的分支HEAD。在一个新的空存储库中,Git将名称master(更确切地说是refs/heads/master-分支的全名)存储在中HEAD,因此您处于master,而master尚不存在。

您可以使用以下命令更改不存在的分支git checkout -b

$ git init
Initialized empty Git repository in [path]
$ git checkout -b asdf
Switched to a new branch 'asdf'
$ git checkout -b hello
Switched to a new branch 'hello'

每当您在不存在的分支上时,您进行的下一次提交都会创建该分支。这也是如何git checkout --orphan工作的。


6
谢谢。虽然我不同意git显示的内容。至少我理解为什么。您的结帐示例很有趣。根据“ git checkout”的文档,-b的意思是:创建一个新的名为<new_branch>的分支,严格来说,这不是正确的。在您的示例中,实际上没有创建分支asdf或hello。但是,如果执行了提交,它们将会是。我个人的看法是,“在分支主机上”消息应更改为“下一次提交给分支主机”,因为在执行提交之前,主分支不存在。
GOVarney19年

2
我不确定这是否与您的情况有关,但是我想指出,对于Git,可能根本不在任何分支上。
sklott

Git内部使用它cat .git/HEAD来查看它所在的分支,弄清楚该分支的存在会消耗更多的CPU和磁盘时间,所以这可能就是为什么他们不这样做的原因
Ferrybig

应当指出的是,根本不应该git branch在自动化过程中使用imo,因为它不是针对该用例设计的。看看这里的非瓷质命令是否git symbolic-ref --short HEAD具有相同的行为会很有趣。
Voo

@Voo:git symbolic-ref显示包含在其中的名称HEAD(因此称为孤儿/未出生的分支引用),但HEAD不能分离。在新的空存储库中,HEAD 无法分离,因为分离的HEAD必须包含现有有效提交的哈希ID。(在具有分离的HEAD的非空存储库中,git symbolic-ref会产生错误。)
torek

23

git branch什么都不显示,因为没有分支。但是,您可以阅读man git init

此命令将创建一个空的Git存储库-基本上是一个.git目录,其中包含对象,ref / heads,refs / tags和模板文件的子目录。还创建了引用master分支的HEAD的初始HEAD文件。

我加粗了我认为相关的部分-看起来虽然还没有master分支,但已经存在对其的引用,这就是为什么要在中显示它git status。提交后将创建一个适当的分支。


3
因此,看起来“ git status”只是显示“分支名称”,如.git / HEAD(参考:refs / heads / master)中所示,但没有通过查看.git / refs / heads来进行一致性检查确实存在。
GOVarney19年

我不确定,因为我没有检查git的代码,但是您写的内容对我来说很有意义。但是我仍然更喜欢托雷克的答案而不是我的:)。
Stanowczo

17

现有的答案解决了字面上的问题,即输出为何如此,但我认为它们已经掩盖了实际问题...

您说您正在自动化某件事,所以我建议在脚本上下文中最好的工具git status也不git branch是。

在此讨论中可以找到一些替代方法:如何以编程方式确定当前已签出的Git分支

在不知道您的需求(或您希望未出生分支的行为方式)的情况下,我不一定会提出建议,但是我要说的是,一些命令用于人机交互(瓷器),而其他命令则用于脚本(管道)


15

该分支尚未诞生。因此git branch,不显示它(git symbolic-ref HEAD表示您的HEAD指向默认的分支主机,git branch并且未显示,因此它是未出生的,即您可以位于尚不存在的分支上)。但是,提交某些内容将创建分支。

如果签出orphan分支,情况也是如此。

我想git status显示分支名称,因为这是将要创建的分支。

有关脚本的信息,请参见如何以编程方式确定当前已签出的Git分支


2

在git中,默认分支是master。当您提交git时,它将“使用”您当前所在的当前分支。由于已经初始化了一个新的存储库,因此您位于“默认”分支上,这就是为什么在分支列表中看不到它的原因,因此,一旦提交更改,它就会显示出来。

在此处输入图片说明

在此处输入图片说明


2
我了解分支,不了解为什么“ git status”说我在不存在的分支上。
GOVarney19年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.