Що таке ГОЛА в Git?


1026

Ви бачите документацію Git, яка говорить про такі речі

Гілка повинна бути повністю об'єднана в HEAD.

Але що таке HEADсаме Git ?



Відповіді:


774

Ви можете думати про ГОЛОВУ як про "поточну гілку". Коли ви перемикаєте гілки на git checkout, редагування HEAD змінюється, щоб вказувати на кінчик нової гілки.

Ви можете бачити, на що вказує HEAD:

cat .git/HEAD

У моєму випадку результат:

$ cat .git/HEAD
ref: refs/heads/master

HEAD може посилатися на певну редакцію, яка не пов'язана з назвою гілки. Таку ситуацію називають відокремленою ГОЛОВОЮ .


52
Отже, git HEAD залежить від контексту, на якому ви працюєте, правильно? Ще далі, ви як розробник? Я думаю, я запитую, чи Git HEAD стане глобальним репозиторієм або індивідуальним для кожного розробника?
бобобобо

90
@bobobobo: Правильно, HEAD - це як вказівник, який вказує на поточну гілку. Коли ви перевіряєте іншу гілку, HEAD змінюється, щоб вказувати на нову. Поточна HEAD є локальною для кожного сховища, і тому індивідуальна для кожного розробника.
Грег Х'югілл

16
@Meng Це один допоміг мені, сподіваюся , що це допомагає: marklodato.github.com/visual-git-guide/index-en.html
Raphael

53
@ 動靜 能量: HEAD може вказувати на будь-яку команду , вона не повинна бути останньою в будь-якій галузі. (Коли HEAD вказує на команду, яка не є останньою коміткою у гілці, це "відокремлена HEAD").
Грег Х'югілл

126
HEAD - це не "поточна галузь". Is - це ім'я, яке надається коміту, з якого був ініціалізований поточний стан робочого дерева. У більш практичному плані це може вважатися символічним посиланням на перевірений комітет.
Бен Коллінз

184

Щоб цитувати інших людей :

Голова - це просто посилання на об'єкт фіксації. Кожна голова має ім’я (назва філії чи назва тегу тощо). За замовчуванням у кожному сховищі, званому master, є заголовок. Репозиторій може містити будь-яку кількість заголовків. У будь-який момент часу одна голова вибирається як "поточна головка". Ця голова чужа для ГОЛОВИ, завжди в столицях ".

Зверніть увагу на цю різницю: "заголовок" (малий регістр) позначає будь-яку з названих заголовків у сховищі; "HEAD" (велика літера) стосується виключно активної голови. Ця відмінність часто використовується в документації на Git.

Ще одне хороше джерело, яке швидко охоплює внутрішню роботу git (і для цього краще розуміння голів / HEAD), можна знайти тут . Посилання (ref :) або голови або гілки можна вважати такими, як пост-нотатки, наклеєні на коміти в історії комісій. Зазвичай вони вказують на кінчику серії фіксацій, але вони можуть бути переміщені з git checkoutабо git resetт.д.


Звідси: "Кожна голова має ім'я". І "одна голова вибрана як" поточна голова ". Цю голову псевдонімом для ГОЛОВИ ". Тож я роблю з цього висновок, що "HEAD" не відноситься до ситуації "відокремленої HEAD".
gxyd

1
@gxyd, якщо випадок, що HEAD не вказує на "голову", це відокремлена ГЛАВА. Він вказує на ідентифікатор фіксації вказаного вами комітету (використовуючи, наприклад, git checkout HEAD~2), який не є ідентифікатором фіксації відомого керівника. Дивіться статтю на eagain.net/articles/git-for-computer-scientists для більш ретельного пояснення.
Silfheed

1
@Silfheed: Як правило, я вважаю, що ця відповідь концептуально більш звукова, ніж прийнята (навіть якщо використання нижньої літери "голова" для позначення гілки бентежить багатьох людей). Однак git revertце не гарний приклад переміщення гілки, щоб не бути на кінчику, тому що git revertпросто створює деякі нові коміти та залишає поточну гілку на (новій) підказці.
LarsH

1
"який не є ідентифікатором фіксації відомого керівника" - Насправді відокремлений HEAD може вказувати на ідентифікатор фіксації, який також є ідентифікатором фіксації відомого керівника (або декількох голів). Що робить його відокремленим, це те, що HEAD вказує безпосередньо на посвідчення комітету, а не на голову. Це вплине на поведінку майбутніх commitс, resetс і т. Д.
LarsH

1
@LarsH: Хороша точка на відокремленій HEAD, що вказує на ідентифікатор комісії замість посилання. Ви можете переконатись у цьому, переглянувши .git / HEAD. Якщо він від'єднаний, він буде містити хеш коміту, навіть якщо це той самий фікш, як відомий голова. Якщо він додається, він буде містити шлях до голови (тобто 'ref: refs / heads / bob'). Що стосується команди повернення, то після 8 років я ніколи не ловив цю помилку. Скидання Git - це те, що дозволяє налаштувати певну голову так, щоб вона вказувала на певну фіксацію.
Silfheed

62

Я рекомендую це визначення від розробника github Скотта Чейкона [ відео посилання ]:

Керівник - ваша нинішня галузь. Це символічна довідка. Це посилання на галузь. У вас завжди є HEAD, але HEAD буде вказувати на один з цих інших покажчиків, на одну з гілок, на яку ви працюєте. Це батько вашого наступного зобов'язання. Це те, що повинно бути те, що востаннє було зареєстровано у вашому робочому каталозі ... Це останній відомий стан того, яким був ваш робочий каталог.

Ціле відео дасть змогу добре ознайомитись із усією системою git, тому я також рекомендую переглянути все, якщо є час.


34
Тож справжній def - це "батько вашого наступного вчинення"
Ніколас

1
а також "річ, яка вказує на наступну гілку, яка рухатиметься"
Ніколас

@nicolas - Я не думаю, що це правда. HEAD може вказувати на будь-яку команду, не обов'язково вказувати на гілку - коли це не так, ви перебуваєте в режимі "відокремленої HEAD".
scubbo

23
Відео чудове, але, на жаль, воно дає невідповідну відповідь для Stack Overflow. Що робити, якщо відео знято десь у майбутньому? Тоді ваше посилання вказуватиме ні на що. Краща відповідь міститиме стенограму того, що говорить Скотт у відео.

2
Скотт каже, що HEAD - вказівник на гілку. Але HEAD може вказувати і на старі вчинки. Це так заплутано.
Fixee

60

HEAD - це лише спеціальний покажчик, який вказує на локальну гілку, на якій ви зараз перебуваєте.

З книги Pro Git , розділ 3.1 Розгалуження Git - гілки в горішці , в розділі Створення нової гілки :

Що станеться, якщо ви створите нову гілку? Що ж, таким чином створюється новий вказівник для пересування. Скажімо, ви створили нову галузь під назвою тестування. Ви робите це за допомогою команди гілки git:

$ git branch testing 

Це створює новий вказівник на ту саму комісію, яку ви зараз виконуєте

введіть тут опис зображення

Як Git знає, в якій галузі ви зараз перебуваєте? Він зберігає спеціальний покажчик під назвою HEAD. Зауважте, що це сильно відрізняється від поняття HEAD в інших СКС, до яких ви можете звикати, наприклад, Subversion або CVS. У Git це вказівник на локальну гілку, на якій ви зараз перебуваєте. У цьому випадку ти все ще на господаря. Команда гілки git створила лише нову гілку - вона не перейшла на цю гілку.

введіть тут опис зображення


4
Приємно, міг би використати малюнок, на якому зображено відокремлений корпус HEAD
Дон Хетч

@DonHatch, гарне пояснення окремих ГОЛОВИ stackoverflow.com/a/35301963/1074179
Олександр

3
Гарна відповідь. Гілки - це не що інше, як марковані коміти, коли ви робите нові комісії, ця мітка переміщується до нової нової комісії. Коли ви оформляєте покупку на комісію, яка не має мітки, вона знаходиться в відірваному стані HEAD. Це означає, що HEAD вказує на документ, який не має мітки гілки. Якщо ви зареєструєтесь 34ac2у наведеному вище прикладі, тепер HEAD буде вказувати на цю комісію і називається відокремленою HEAD. У такому стані ви можете вносити зміни, експериментувати та вносити зміни теж, але, оформивши іншу гілку, ви втратите всі свої зміни, якщо, звичайно, не створите нову гілку.
sleepwalkerfx

1
@sleepwalkerfx, але ви можете оформити комісію, яка має мітку гілки, і все ще знаходиться у відокремленому заголовку, оскільки HEAD більше не вказує на мітку гілки, а ідентифікатор філії відділення
Marc

1
@sleepwalkerfx Я думаю, що ми зараз говоримо про семантику. Ви правильні, мітка гілки - це текстове посилання на певний комітет. Однак це не зобов'язання. Отже, якщо ви зробили git logта отримали щось подібне commit ad0265... HEAD -> foo ..., це означатиме, що fooгілка - це посилання на фіксацію ідентифікатора ad0265. Здійснення замовлення текстового посилання fooне є відірваною головою. Здійснення замовлення посвідчення комітету ad0265призведе до відокремленої голови. Можливо, мені не вистачає дещо тонкості того, що ви спілкуєтесь. Я сподіваюся, що ця стіна тексту допоможе виявити, де я загубився.
Марк

40

Якщо припустити, що це не окремий випадок під назвою "відокремлена голова", то, як зазначено в книзі O'Reilly Git, друге видання, стор.69, HEADозначає:

HEADзавжди посилається на найновіший комітет у поточній галузі. Коли ви змінюєте гілки, HEADвона оновлюється, щоб посилатися на останню фіксацію нової гілки.

тому

HEADє "підказкою" поточної гілки .

Зауважте, що ми можемо використовувати HEADдля позначення останньої фіксації та використовувати HEAD~як фіксацію перед підказкою, HEAD~~або HEAD~2як фіксацію ще раніше, тощо.


26

У ряді цих відповідей є, можливо, тонке, але важливе хибне уявлення. Я думав, що додам свою відповідь, щоб очистити її.

Що таке HEAD?

ГОЛОВА - ВАС

HEADце символічна довідка, яка вказує на те, де ви знаходитесь в історії вчинення. Це стежить за вами, куди б ви не поїхали, чим би ви не займалися, як тінь. Якщо ви візьмете на себе зобов’язання, HEADбуде рухатися. Якщо ви щось замовите, HEADпереїдете. Що б ви не робили, якщо ви переїхали кудись нове в історії своїх зобов’язань, HEADвін перемістився разом з вами. Щоб вирішити одне поширене помилкове уявлення: від цього не можна відлучатися HEAD. Це не такий стан відокремленої HEAD. Якщо ви коли-небудь задумуєтесь про те, що думаєте: "О, ні, я перебуваю в стані окремої ГЛАВИ! Я втратив ГОЛОВУ!" Пам'ятайте, це ваша ГОЛОВА. ГОЛОВА - це ти. Ви не відірвалися від ГОЛОВИ, ви та Ваша ГОЛОВА відійшли від чогось іншого.

До чого може прикріпити HEAD?

HEADТак, але зазвичай це не так. Дозвольте сказати це ще раз. Зазвичай HEADне вказує на скоєння. Це вказує на посилання на галузь. Він додається до цієї гілки, і коли ви робите певні речі (наприклад, commitабо reset), додана гілка рухатиметься разом із HEAD. Ви можете побачити, на що вказує, заглянувши під капот.

cat .git/HEAD

Зазвичай у вас вийде щось подібне:

ref: refs/heads/master

Іноді ви отримаєте щось подібне:

a3c485d9688e3c6bc14b06ca1529f0e78edd3f86

Ось що відбувається, коли 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однак, буде.


1
Мені подобається ця відповідь, оскільки, хоча документація описує істину, програмне забезпечення визначає істину. .git/HEADце те, що програмне забезпечення вважає HEAD.
Дон Бренсон

2
Це стосується лише концептуального визначення цього питання.
ата

22

HEADвідноситься до поточного зобов’язання, на яке вказує ваша робоча копія, тобто до зобов’язання, яке ви наразі зареєстрували. З офіційної документації Linux Kernel щодо уточнення версій Git :

HEAD називає комісію, на якій ви базували зміни в робочому дереві.

Однак зауважте, що у майбутній версії 1.8.4 Git @також можна використовувати як скорочення HEAD, як зазначив дописувач Git Хуніо C Hamano у своєму блозі Git Blame :

Замість того, щоб набрати "HEAD", ви можете сказати "@", наприклад "git log @".

Користувач Stack Overflow VonC також знайшов цікаву інформацію про те, чому @був обраний як стенограма у своїй відповіді на інше питання .

Також цікаво, що в деяких середовищах не потрібно використовувати великі капітали HEAD, особливо в операційних системах, які використовують файлові системи, нечутливі до регістру, зокрема Windows та OS X.


17

Погляньте на Створення та гра з гілками

HEAD - це фактично файл, вміст якого визначає, куди посилається змінна HEAD:

$ cat .git/HEAD
ref: refs/heads/master
$ cat .git/refs/heads/master
35ede5c916f88d8ba5a9dd6afd69fcaf773f70ed

В цьому сховищі вміст файлу HEAD посилається на другий файл з назвою refs / heads / master . Файл refs / heads / master містить хеш останнього комітету в гілці master.

Результат - HEAD вказує на головний фільтр з файлу .git / refs / heads / master .

введіть тут опис зображення


1
Обережно: посилання gitguys.com, схоже, вказує на припаркований домен.
MKesper

14

Я просто хотів би детально описати кілька речей у прийнятій відповіді Грега Х'югіла. Згідно з посібником Git Pocket

Відділення:

сама гілка визначається як усі точки, доступні в графіку фіксування з названого фіксування ("підказка" гілки).

ГОЛОВА: Особливий тип Ref

Спеціальний перелік HEAD визначає, на якій галузі ви знаходитесь ...

Реф

Git визначає два види посилань або названі покажчики, які він називає "refs":

  • Простий посилання, який вказує безпосередньо на ідентифікатор об'єкта (як правило, на коміт або тег)
  • Символічний відбиток (або symref), який вказує на інший номер (простий або символічний)

Як згадував Грег, HEAD може перебувати в "відірваному стані". Таким чином, HEAD може бути або простим (для відокремленої ШАГИ), або symref.

якщо HEAD є символічним переліком для існуючої гілки, то ви "на" цю гілку. Якщо, з іншого боку, HEAD - це простий відрив, який безпосередньо називає комісію за своїм ідентифікатором SHA-1, то ви не перебуваєте в "жодній гілці", а в режимі "відокремленої HEAD", що відбувається, коли ви перевіряєте деякі раніше зобов’язатись вивчити.


Дякую, @mike! Це перша відповідь, яка роз'яснює, що відбувається, коли ви перевіряєте попереднє виконання. Переглядаючи книгу на веб-сайті git, у мене склалося враження, що «відшарована ШАБА» - це патологічний стан, у який ти потрапив, лише якщо робиш якусь дивну репануючу річ. Але перевірка більш раннього вчинення не дивна річ, і коли ви це робите, HEAD не є "верхівкою поточної гілки". Тож це перший раз, коли я відчуваю, що насправді розумію.
Нат Кун

7

Я думаю, що "HEAD" - це поточна перевірка. Іншими словами, "HEAD" вказує на зобов'язання, які зараз перевіряються.

Якщо ви щойно клонували і не перевірили, я не знаю, на що це вказує, ймовірно, недійсне місце.


Так, спеціальна довідка HEAD- це будь-яке зобов’язання, яке ви наразі зареєстрували. Деталі див. У посібнику (відповідний параграф одразу слідує на рис. 3.4).
Калріон

1
Якщо ви клонуєте сховище, git за замовчуванням перевірить masterгілку - так HEAD вкаже на майстер.
sleske

1
@sleske якщо ви клонуєте сховище без спеціальних опцій, git перевірить віддалену голову. це зазвичай master, але це не завжди. Дивітьсяremote set-head
De Novo

Мій попередній коментар був правильним, за винятком посилання на remote set-head, яке впливає лише на локальну гілку за замовчуванням, і не змінить типовий сервер на сервері.
De Novo

5

Голова вказує на кінчик перевіреної в даний час гілки.

введіть тут опис зображення

У вашому сховищі є папка .git. Відкрийте файл у цьому місці: .git \ refs \ heads. Код (ша-1 хеш) у цьому файлі (головний у більшості випадків) буде останньою фіксацією, тобто тим, що бачиться у висновку команди git log. Докладніше про папку .git: http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html


1
Поширена помилкова думка, що кінчик поточної гілки вказує на останнє введення. Як правило, це правда, але це також не рідкість git reset HEAD^, і тоді остання фіксація (колишня підказка) вже не вказується кінчиком гілки.
LarsH

4

Чудовий спосіб загнати додому точку, зроблену в правильних відповідях, - це запустити git reflog HEAD, ви отримаєте історію всіх місць, на які вказував HEAD.


4

Прочитавши всі попередні відповіді, я все ж хотів більшої ясності. Цей блог на офіційному веб-сайті git http://git-scm.com/blog дав мені те, що я шукав:

THE HEAD: Вказівник на останній знімок, наступний батько

HEAD в Git - це вказівник на поточну посилання гілки, яка, в свою чергу, вказує на останнє, яке ви здійснили, або на останнє зобов’язання, яке було зареєстровано у вашому робочому каталозі. Це також означає, що це буде батьком наступного зобов’язання, яке ви виконуєте. Як правило, це найпростіше думати про це, оскільки HEAD - це знімок останнього вчинку.


1
ГОЛОВА: останній знімок фіксації, наступний батько не точний. HEADне є зобов’язанням; це вказує на одне.
jub0bs

Не потрібно сарказму; перед редагуванням, хоча цитата була точною, великі жирні листи були спрощенням і трохи оманливими. Тепер краще.
jub0bs

1
ЯКЩО ви читаєте наступний рядок: HEAD в Git - це вказівник на поточну посилання гілки, яка, в свою чергу, вказує на останнє, яке ви здійснили, або на останнє зобов’язання, яке було зареєстровано у вашому робочому каталозі. - Зверніть увагу на вживання там слова "вказівник".
user3751385

Незважаючи на те, що опис "останніх знімків фіксації" дає концептуальне відчуття того, як зазвичай використовується HEAD, це дійсно не точно. Якщо я візьму на себе зобов’язання, перейдіть до іншої гілки, HEAD більше не вказує на останній знімок фіксації. Він вказує на останній знімок фіксації на гілці, на який я щойно перейшов. Якщо я checkout HEAD^, зараз HEAD навіть не вказує на останній знімок фіксації на будь-якій гілці.
LarsH

"Батькот наступного вашої комісії (якщо ви повинні здійснити прямо зараз)" є більш точним, але існує багато інших операцій в git, крім фіксації, на які впливає HEAD. Дійсно, в кінці кінців, голова HEAD, і його природа визначається як вона впливає на такі команди , як commit, merge, rebase, logі т.д. Але концептуально може бути «(покажчик) поточний стан» являє собою резюме добре.
LarsH

3

Схоже, HEADце лише тег останнього комітету, який ви перевірили.

Це може бути вістря певної гілки (наприклад, "майстер") або деяка між ними фіксація гілки ("від'єднана голова")


1

Окрім усіх визначень, річ, яка застрягла в моїй свідомості, - це коли ви берете на себе зобов’язання, GIT створює об’єкт фіксації у сховищі. Об'єкти фіксації повинні мати батьків (або декількох батьків, якщо це об'єднання). Тепер, як git знає батьків поточного комітету? Отже HEAD є вказівником на (посилання на) останнього комітету, який стане батьківським поточним комітетом.


0

Ці два можуть вас збентежити:

голова

Вказуючи на названі посилання, нещодавно представлена ​​філія. Якщо ви не використовуєте посилання на пакет, голови зазвичай зберігаються в $ GIT_DIR / refs / heads /.

ГОЛОВА

Поточна гілка або ваше робоче дерево зазвичай генерується із дерева, на яке вказує HEAD. HEAD повинна вказувати на голову, за винятком випадків, коли ви використовуєте відокремлену HEAD.


0

Погляньте на http://git-scm.com/book/en/Git-Branching-What-a-Branch-Is

Малюнок 3-5. Файл HEAD вказує на гілку, на якій ви знаходитесь.


4
Відповіді, що стосуються лише посилань, як правило, накидаються на Stackoverflow, будь ласка, введіть відповідну інформацію у своїй відповіді.
HaskellElephant

2
Це не зовсім правильно. Те, на що HEADйдеться, залежить від того, чи говориш ти про голу проти не голого репо. У контексті не голого репо, воно фактично посилається на поточну перевірку комісії, яка не вимагає, щоб до неї була прикріплена гілка (тобто, коли вона знаходиться у відірваному HEADстані).

0

Гілка фактично є покажчиком , який тримає зробити ID , такі як 17a5 . HEAD - вказівник на гілку, над якою зараз працює користувач.

HEAD має еталонний фільм, який виглядає приблизно так:

посилання:

Ви можете перевірити ці файли, відкривши доступ .git/HEAD .git/refsдо сховища, в якому ви працюєте.


0

Gitце все про коміти.
І Headвказує на комітет, який ви зараз перевірили.

$ git cat-file -t HEAD
commit

Кожного разу, коли ви перевіряєте філію, HEAD вказує на останню поступку на цій гілці. Зміст HEAD можна перевірити як зазначено нижче (для головного відділення):

$ cat .git/refs/heads/master
  b089141cc8a7d89d606b2f7c15bfdc48640a8e25

-5

Як концепція, голова - це остання редакція у галузі. Якщо у вас є декілька заголовків на названу гілку, ви, ймовірно, створили її під час виконання локальних комісій без об'єднання, фактично створюючи неназвану гілку.

Щоб мати "чистий" сховище, ви повинні мати одну голову на названу гілку і завжди зливатися з названою гілкою після того, як ви працювали на локальному рівні.

Це справедливо і для Mercurial .


4
Це справедливо для Mercurial, але не для Git.
Відновіть Моніку - немайнард
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.