Почему «git status» показывает, что я нахожусь в основной ветке, а «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 показывает.

Ответы:


94

Я поддержал два других ответа, но думаю, что это просто: вы можете быть в ветке, которой не существует. Это нормально и для нового пустого репозитория, потому что для существования имени ветки это имя ветки должно идентифицировать хэш-идентификатор существующей действительной фиксации. В новом пустом репозитории нет коммитов, поэтому имена веток еще не могут существовать.

Тем не менее, вы изначально находитесь в какой-то ветке. Вы находитесь в той ветке, имя которой хранится в специальном имени 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. Но они будут, если выполнить коммит. Лично я считаю, что сообщение «На главном узле ветки» следует изменить на «Следующая фиксация на мастере ветки», потому что до тех пор, пока не будет выполнена фиксация, основная ветка не существует.
— GOVarney

2
Я не уверен, имеет ли это отношение к вашему случаю или нет, но я хочу указать, что для Git можно вообще не находиться ни в какой ветке.
— sklott

Git внутренне использует, cat .git/HEADчтобы узнать, в какой ветке он находится, выяснение того, что ветка существует, потребует больше времени на ЦП и диск, так что, вероятно, поэтому они этого не сделали
— Феррибиг

Следует отметить, что вы вообще не должны использовать git branchавтоматизированный процесс, потому что он не предназначен для этого варианта использования. Было бы интересно посмотреть, что показывают здесь не-фарфоровые команды, имеет git symbolic-ref --short HEADли такое же поведение?
— Voo

@Voo: git symbolic-refпоказывает имя, содержащееся в HEAD(отсюда ссылка на сиротскую / нерожденную ветку), при условии, что HEADоно не отсоединено. В новом пустом репозитории HEAD его нельзя отсоединить, поскольку отсоединенный HEAD должен содержать хэш-ID существующей действительной фиксации. (В непустом хранилище, с отдельными ГОЛОВАМИ, git symbolic-refвыдает ошибку.)
— Торек

23

git branchничего не показывает, потому что ветки нет. Но, как вы можете прочитать man git init:

Эта команда создает пустой репозиторий Git - в основном каталог .git с подкаталогами для объектов, ссылок / заголовков, ссылок / тегов и файлов шаблонов. Также создается начальный файл HEAD, который ссылается на HEAD главной ветви.

Я выделил жирным шрифтом ту часть, которую считаю актуальной - похоже, хотя основной ветки еще нет, ссылка на нее уже существует, и поэтому она показана в git status. При фиксации будет создана соответствующая ветка.


3
Таким образом, похоже, что «git status» просто отображает «имя ветки», как показано в .git / HEAD (ref: refs / heads / master), но не проверяет согласованность, просматривая .git / refs / Heads, чтобы узнать, не действительно существует.
— GOVarney

Я не могу сказать наверняка, так как я не проверял код 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" говорит, что я нахожусь в несуществующей ветке.
— GOVarney
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.