Вы видите документацию Git, в которой говорится
Ветка должна быть полностью объединена в HEAD.
Но что такое Git HEAD
?
Вы видите документацию Git, в которой говорится
Ветка должна быть полностью объединена в HEAD.
Но что такое Git HEAD
?
Ответы:
Вы можете думать о ГОЛОВЕ как о "текущей ветви". Когда вы переключаете ветки с помощью git checkout
, ревизия HEAD изменяется, чтобы указывать на вершину новой ветки.
Вы можете увидеть, на что указывает HEAD:
cat .git/HEAD
В моем случае вывод:
$ cat .git/HEAD
ref: refs/heads/master
HEAD может ссылаться на конкретную ревизию, которая не связана с именем ветви. Эта ситуация называется отдельной головой .
Цитировать других людей :
Голова - это просто ссылка на объект фиксации. У каждой головы есть имя (название ветви или имя тега и т. Д.) По умолчанию в каждом репозитории есть заголовок с именем master. Хранилище может содержать любое количество головок. В любой момент времени одна голова выбрана в качестве «текущей головы». Эта голова имеет псевдоним HEAD, всегда в столицах ".
Обратите внимание на это различие: «голова» (в нижнем регистре) относится к любой из названных голов в хранилище; «ГОЛОВА» (верхний регистр) относится исключительно к текущей активной голове. Это различие часто используется в документации Git.
Другой хороший источник, который быстро охватывает внутреннюю работу git (и, следовательно, для лучшего понимания head / HEAD), можно найти здесь . Ссылки (ref :) или заголовки или ветки могут рассматриваться как заметки, прикрепленные к коммитам в истории коммитов. Обычно они указывают на конец серии коммитов, но их можно перемещать с помощью git checkout
или git reset
т. Д.
git checkout HEAD~2
), который не является идентификатором фиксации известного заголовка. См. Статью на eagain.net/articles/git-for-computer-scientists для более подробного объяснения.
git revert
это не хороший пример перемещения ветки, чтобы не быть на кончике, потому что git revert
просто создает некоторые новые коммиты и все еще оставляет текущую ветвь на (новом) кончике.
commit
с, reset
с и т. Д.
Я рекомендую это определение от разработчика github Скотта Чакона [ ссылка на видео ]:
Голова - это ваша текущая ветвь. Это символическая ссылка. Это ссылка на ветку. У вас всегда есть HEAD, но HEAD будет указывать на один из этих других указателей, на одну из ветвей, на которой вы находитесь. Это родитель вашего следующего коммита. Это то, что должно быть последним извлеченным в вашем рабочем каталоге ... Это последнее известное состояние вашего рабочего каталога.
Все видео даст хорошее представление о всей системе git, поэтому я также рекомендую вам посмотреть все, если есть время.
HEAD - это просто специальный указатель, который указывает на локальную ветку, в которой вы находитесь.
Из книги Pro Git , глава 3.1 Ветвление Git - ветви в двух словах , в разделе Создание новой ветки :
Что произойдет, если вы создадите новую ветку? Ну, это создает новый указатель для вас, чтобы двигаться. Допустим, вы создаете новую ветку под названием «Тестирование». Вы делаете это с помощью команды git branch:
$ git branch testing
Это создаст новый указатель на тот же коммит, на котором вы сейчас находитесь
Как Git узнает, в какой ветке вы сейчас находитесь? Он содержит специальный указатель под названием HEAD. Обратите внимание, что это сильно отличается от концепции HEAD в других VCS, к которым вы можете привыкнуть, таких как Subversion или CVS. В Git это указатель на локальную ветку, в которой вы находитесь. В этом случае вы все еще на мастере. Команда git branch только создала новую ветку - она не переключалась на эту ветку.
34ac2
из вышеприведенного примера, теперь HEAD будет указывать на этот коммит, и он называется отделенным HEAD. В этом состоянии вы также можете вносить изменения, экспериментировать и фиксировать изменения, но как только вы извлечете другую ветку, вы потеряете все свои изменения, если, конечно, вы не создадите новую ветку.
git log
и получили что-то подобное commit ad0265... HEAD -> foo ...
, это означало бы, что foo
ветвь является ссылкой для фиксации id ad0265
. Оформление проверки текстовой ссылки foo
не является отдельной головой. Извлечение идентификатора коммита ad0265
приведет к отстраненной голове. Может быть, мне не хватает тонкости в том, что вы говорите. Я надеюсь, что эта стена текста поможет обнаружить, где я потерялся.
Если предположить, что это не особый случай, называемый «отделенная ГОЛОВА», то, как указано в книге О'Рейли Гит, 2-е издание, стр.69, HEAD
означает:
HEAD
всегда ссылается на самый последний коммит в текущей ветке. Когда вы меняете ветки,HEAD
обновляется, чтобы ссылаться на последний коммит новой ветки.
так
HEAD
является «наконечником» текущей ветви .
Обратите внимание, что мы можем использовать HEAD
ссылку на самый последний коммит и использовать HEAD~
в качестве коммита до подсказки, и / HEAD~~
или HEAD~2
в качестве коммита еще раньше, и так далее.
В ряде этих ответов есть, возможно, тонкое, но важное заблуждение. Я думал, что добавлю свой ответ, чтобы прояснить это.
Что такое
HEAD
?
HEAD
символическая ссылка, указывающая на то, где вы находитесь в истории коммитов. Он следует за вами, куда бы вы ни пошли, что бы вы ни делали, как тень. Если вы сделаете коммит, HEAD
переедете. Если вы что-то оформите, HEAD
переедете. Что бы вы ни делали, если вы переехали куда-то новое в историю ваших коммитов, HEAD
вы перешли вместе с вами. Чтобы устранить одно распространенное заблуждение: вы не можете оторваться отHEAD
. Это не то, что состояние отделенного HEAD. Если вы когда-нибудь обнаружите, что думаете: «О, нет, я нахожусь в отдельном состоянии ГОЛОВА! Я потерял свою ГОЛОВУ!» Помните, это ваша голова. ГОЛОВА это ты. Вы не отсоединились от ГОЛОВОЙ, вы и ваша ГОЛОВА отошли от чего-то другого.
HEAD
может указывать на коммит, да, но обычно это не так. Позвольте мне сказать это снова. Обычно HEAD
не указывает на коммит. Это указывает на ссылку ветви. Он прикреплен к этой ветви, и когда вы делаете определенные вещи (например, commit
или reset
), присоединенная ветвь будет двигаться вместе с HEAD
. Вы можете увидеть, на что он указывает, заглянув под капот.
cat .git/HEAD
Обычно вы получите что-то вроде этого:
ref: refs/heads/master
Иногда вы получите что-то вроде этого:
a3c485d9688e3c6bc14b06ca1529f0e78edd3f86
Вот что происходит, когда HEAD
указывает непосредственно на коммит. Это называется отделенным HEAD, потому что HEAD
указывает на что-то, кроме ссылки на ветку. Если вы делаете коммит в этом состоянии, master
больше не привязаны к нему HEAD
, больше не будут двигаться вместе с вами. Неважно, где находится этот коммит. Вы можете использовать тот же коммит, что и ваша основная ветка, но если HEAD
он указывает на коммит, а не на ветку, он отсоединяется, и новый коммит не будет связан со ссылкой на ветку.
Вы можете посмотреть на это графически, если попытаетесь выполнить следующее упражнение. Запустите это из репозитория git. Вы получите что-то немного другое, но они будут иметь ключевое значение. Когда пришло время напрямую извлекать коммит, просто используйте любой сокращенный хеш, который вы получите из первого вывода (здесь он есть a3c485d
).
git checkout master
git log --pretty=format:"%h: %d" -1
# a3c485d: (HEAD -> master)
git checkout a3c485d -q # (-q is for dramatic effect)
git log --pretty=format:"%h: %d" -1
# a3c485d: (HEAD, master)
Итак, здесь небольшая разница в выводе. Проверка коммита напрямую (вместо ветки) дает нам запятую вместо стрелки. Как вы думаете, мы находимся в отдельном состоянии головы? HEAD все еще ссылается на конкретную ревизию, связанную с именем ветви. Мы все еще на главной ветке, не так ли?
Теперь попробуйте:
git status
# HEAD detached at a3c485d
Нет. Мы находимся в состоянии «отсоединенная ГОЛОВА».
Вы можете увидеть то же представление (HEAD -> branch)
против (HEAD, branch)
с git log -1
.
HEAD
это ты. Это указывает на то, что вы проверили, где бы вы ни находились. Как правило, это не коммит, это ветка. Если HEAD
он указывает на коммит (или тег), даже если это тот же коммит (или тег), на который указывает ветка, вы (и HEAD
) были отсоединены от этой ветви. Поскольку к вам не прикреплена ветка, ветка не будет следовать за вами, когда вы делаете новые коммиты. HEAD
Впрочем, будет.
.git/HEAD
это то, что программное обеспечение считает головой.
HEAD
относится к текущему коммиту, на который указывает ваша рабочая копия, т.е. к коммиту, который вы в данный момент извлекли. Из официальной документации Linux Kernel по указанию ревизий Git :
HEAD
называет коммит, на котором вы основали изменения в рабочем дереве.
Тем не менее, обратите внимание, что в следующей версии Git 1.8.4 @
также можно использовать для краткости HEAD
, как отметил участник Git Джунио С. Хамано в своем блоге Git Blame :
Вместо того, чтобы вводить «HEAD», вы можете сказать «@», например, «git log @».
Пользователь Stack Overflow VonC также нашел интересную информацию о том, почему он @
был выбран в качестве краткого описания в своем ответе на другой вопрос .
Также интересно, что в некоторых средах нет необходимости использовать заглавные буквы HEAD
, особенно в операционных системах, использующих файловые системы без учета регистра, особенно в Windows и OS X.
Посмотрите на Создание и игра с ветками
HEAD - это файл, содержимое которого определяет, куда ссылается переменная HEAD:
$ cat .git/HEAD
ref: refs/heads/master
$ cat .git/refs/heads/master
35ede5c916f88d8ba5a9dd6afd69fcaf773f70ed
В этом хранилище содержимое файла HEAD ссылается на второй файл с именем refs /head / master . Файл refs /глав / мастер содержит хэш самого последнего коммита в ветке master.
В результате HEAD указывает на коммит главной ветки из файла .git / refs /head / master .
Я просто хотел бы подробно рассказать о нескольких вещах в принятом ответе Грега Хьюджила. Согласно Git Pocket Guide
Филиал:
Сама ветвь определяется как все точки, достижимые в графе коммитов из именованного коммита («кончик» ветки).
ГОЛОВА: особый тип Реф
Специальный ref HEAD определяет, на какой ветке вы находитесь ...
Refs
Git определяет два вида ссылок или именованных указателей, которые он называет «refs»:
- Простой реф, который указывает непосредственно на идентификатор объекта (обычно коммит или тэг)
- Символический ref (или symref), который указывает на другой ref (простой или символический)
Как упомянул Грег, HEAD может находиться в «обособленном состоянии». Таким образом, HEAD может быть либо простым ref (для отдельного HEAD), либо symref.
если HEAD является символической ссылкой на существующую ветвь, то вы находитесь «на» этой ветке. Если, с другой стороны, HEAD - это простой реф, непосредственно именующий коммит его идентификатором SHA-1, то вы находитесь не в «любой» ветви, а в режиме «отсоединенного HEAD», который происходит, когда вы проверяете некоторые ранее. поручить изучить.
Я думаю, что «HEAD» - это текущий коммит. Другими словами, «HEAD» указывает на коммит, который в данный момент извлечен.
Если вы только что клонировали и не проверили, я не знаю, на что это указывает, возможно, какое-то неверное местоположение.
HEAD
- это любой коммит, который вы в данный момент получили. Подробности см. В руководстве (соответствующий пункт следует сразу за Рис. 3.4).
master
ветку - поэтому HEAD будет указывать на master.
master
, но это не всегда. Смотритеremote set-head
remote set-head
, которая влияет только на локальную ветку по умолчанию и не меняет настройки по умолчанию на сервере.
Голова указывает на верхушку проверенной ветки.
В вашем репозитории есть папка .git. Откройте файл в этом месте: .git \ refs \head. Код (sha-1 hash) в этом файле (в большинстве случаев master) будет самым последним коммитом, то есть тем, который виден в выходных данных команды git log
. Дополнительная информация о папке .git: http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html.
git reset HEAD^
, и тогда самый последний коммит (предыдущий совет) больше не указывается кончиком ветви.
Прочитав все предыдущие ответы, я все еще хотел большей ясности. Этот блог на официальном сайте Git http://git-scm.com/blog дал мне то, что я искал:
HEAD в Git - это указатель на текущую ссылку на ветвь, которая, в свою очередь, является указателем на последний сделанный вами коммит или последний коммит, который был извлечен в ваш рабочий каталог. Это также означает, что это будет родитель следующего коммита, который вы делаете. Как правило, проще всего думать об этом, поскольку HEAD - это снимок вашего последнего коммита.
HEAD
это не коммит; это указывает на один.
checkout HEAD^
, то теперь HEAD даже не указывает на последний моментальный снимок коммита в любой ветви.
commit
, merge
, rebase
, log
и т.д. Но концептуально может быть «(указатель) текущее положение» представляет собой резюме хорошо.
Такое ощущение, что HEAD
это всего лишь тег для последнего зафиксированного вами коммита.
Это может быть кончик определенной ветви (например, «master») или некоторый промежуточный коммит ветви («detached head»)
В дополнение ко всем определениям у меня в голове застряло то, что когда вы делаете коммит, GIT создает объект фиксации в репозитории. У объектов коммитов должен быть родитель (или несколько родителей, если это коммит слияния). Теперь, как git узнает родителя текущего коммита? Таким образом, HEAD является указателем на (ссылку на) последний коммит, который станет родителем текущего коммита.
Эти двое могут сбить вас с толку:
глава
Указывая на именованные ссылки ветка недавно представленная. Если вы не используете ссылку на пакет, заголовки обычно хранятся в $ GIT_DIR / refs /head /.
ГЛАВА
Текущая ветвь или ваше рабочее дерево обычно генерируется из дерева, на которое указывает HEAD. ГОЛОВА должна указывать на голову, за исключением того, что вы используете отдельную ГОЛОВУ.
Взгляните на http://git-scm.com/book/en/Git-Branching-What-a-Branch-Is
Рисунок 3-5. Файл HEAD, указывающий на ветку, в которой вы находитесь.
HEAD
относится к этому, зависит от того, говорите ли вы о «голом» или «не голом» репо. В контексте репозитория non-bare, он фактически ссылается на текущий извлеченный коммит, который не требует, чтобы к нему была присоединена ветвь (т. Е. В отключенном HEAD
состоянии).
Ветвь фактически является указателем , который держит совершить ID , такие как 17a5 . HEAD - указатель на ветку, над которой в данный момент работает пользователь.
ГЛАВА есть ссылка на ссылку, которая выглядит следующим образом:
ссылка:
Вы можете проверить эти файлы, зайдя .git/HEAD
.git/refs
в репозиторий, в котором вы работаете.
Git
это все о коммитах.
И Head
указывает на коммит, который вы в настоящее время извлекли.
$ git cat-file -t HEAD
commit
Всякий раз, когда вы извлекаете ветку, HEAD указывает на последний коммит в этой ветке. Содержимое HEAD можно проверить, как показано ниже (для основной ветки):
$ cat .git/refs/heads/master
b089141cc8a7d89d606b2f7c15bfdc48640a8e25
Как концепция, глава является последней ревизией в отрасли. Если у вас есть более одного заголовка на именованную ветвь, вы, вероятно, создали его при выполнении локальных коммитов без слияния, фактически создавая неназванную ветвь.
Чтобы иметь «чистый» репозиторий, у вас должна быть одна голова на именованную ветвь и всегда сливаться с именованной ветвью после локальной работы.
Это также верно для Mercurial .