HEAD і ORIG_HEAD в Git


253

До чого відносяться ці символи та що вони означають?

(Я не можу знайти жодного пояснення в офіційній документації)


4
Примітка: HEADзараз (майбутній git1.8.4) ' @'! Дивіться мою відредаговану відповідь нижче
VonC

Примітка-біс: ' @' (для HEAD) все ще надходить, але не для редагування та доповнень відповіді 1.8.4 .
VonC

1
Примітка ter: ' @' for HEADє назад для git 1.8.5 / 1.9. відповідь знову відредаговано .
VonC

21
HEADі ORIG_HEADв Git, як $PWDі $OLDPWDв Bash. :)
musiphil

Відповіді:


324

HEADє (прямим або непрямим, тобто символічним) посиланням на поточний комітет. Це фіксація, яку ви зареєстрували в робочому каталозі (якщо ви не внесли якісь зміни або еквівалент), і це коміт, поверх якого "git commit" зробив би нове. Зазвичай HEADсимволічне посилання на якусь іншу названу галузь; ця гілка наразі перевірена філія, або поточна гілка.HEADможе також вказувати безпосередньо на зобов’язання; цей стан називається "відокремленою ГОЛОВОЮ", і його можна розуміти як такий, що знаходиться на неназваній, анонімній гілці.

І @лише це ярлик для HEAD, оскільки Git 1.8.5

ORIG_HEADце попередній стан HEAD, встановлений командами, які можуть мати небезпечну поведінку, щоб їх легко було відновити. Зараз менш корисно, коли Git має рефлог: HEAD@{1}приблизно еквівалентний ORIG_HEAD( HEAD@{1}завжди останнє значення HEAD,ORIG_HEAD це останнє значення HEADдо небезпечної операції).

Для отримання додаткової інформації прочитайте сторінку git (1) , посібник користувача Git, книгу спільноти Git та словник Git


2
Привіт Якуб. +1 для пояснення. Чи можете ви детально описати "приблизно еквівалентну" частину HEAD @ {1}? Я посилаюсь у своїй відповіді на тему теми.gmane.org/gmane.comp.version-control.git/38379 (ви були в ній, ще в лютому 2007 року), і я не точно зрозумів дискусію, яку ви, хлопці, вели навколо синтаксис @ {...}.
VonC

19
ORIG_HEAD встановлюється (я думаю) лише "небезпечними" командами, які переміщують HEAD більше, ніж один коміт. Отже ORIG_HEAD не завжди встановлюється, тоді як HEAD @ {1} завжди встановлюється. @ {1} є $ (git символічно-ref HEAD) @ {1}, тобто він використовує reflog для поточної гілки, а не HEAD reflog.
Якуб Нарубський

Ріай ... я розумію зараз :) Дякую за роз'яснення. Що того варте, я також підтримав ваш коментар!
VonC

1
"і HEAD - це зобов'язання, на вершині якого" git commit "зробить новий." - добре пам’ятати, дякую! Крім того, від @VonC: "Це команда" git commit "будується на вершині, а" git diff - cached "та" git status "порівнюються з."
Пан Minqi

1
редагування довідки git відкриває git-scm.com/docs/gitreitions , де описані всі способи посилання на коміти (включаючи HEADта ORIG_HEAD).
dahlbyk

104

Від скидання git

"тягнути" або "злити" завжди залишає початковий наконечник поточної гілки в ORIG_HEAD.

git reset --hard ORIG_HEAD

Якщо скинути його важко, ви повернете ваш індексний файл та робоче дерево назад до цього стану та скидає кінчик гілки до цього фіксу.

git reset --merge ORIG_HEAD

Перевіривши результат злиття, ви можете виявити, що зміна в іншій гілці незадовільна. Запуск " git reset --hard ORIG_HEAD" дозволить вам повернутися туди, де ви були, але він відкине ваші локальні зміни, яких ви не хочете. « git reset --merge» Зберігає свої локальні зміни.


Перш ніж застосовувати будь-які виправлення, ORIG_HEAD встановлюється на кінчик поточної гілки.
Це корисно, якщо у вас виникли проблеми з декількома комісіями, як-от запуск "git am " на неправильній гілці або помилка в комітетах, яку легше виправити зміною поштової скриньки (наприклад, + помилки в рядках "Від:").

Крім того, злиття завжди встановлює ' .git/ORIG_HEAD' у вихідний стан HEAD, тому проблемне злиття можна усунути за допомогою ' git reset ORIG_HEAD'.


Примітка: звідси

HEAD - це рухомий вказівник. Іноді це означає поточну гілку, іноді - ні.

Тож HEAD НЕ є синонімом "поточної гілки" скрізь.

HEAD означає "струм" скрізь у git, але це не обов'язково означає "поточна гілка" (тобто окрема HEAD).

Але це майже завжди означає "поточне зобов'язання".
Це команда, яка " git commit" будується на вершині, а " git diff --cached" і " git status" порівнювати проти.
Це означає, що поточна гілка є лише у дуже обмежених контекстах (саме тоді, коли ми хочемо, щоб ім’я гілки працювало на --- скидання та нарощування кінчика гілки через комісію / перезавантаження / тощо).

Reflog - це засіб, який повертається у часі та часі, машини мають цікаву взаємодію з поняттям "струм".

HEAD@{5.minutes.ago}може означати "повалення HEAD symref, щоб дізнатись, на якій гілці ми знаходимось ПРАВО ЗАРАЗ, а потім дізнаємось, де верхівка цієї гілки була 5 хвилин тому".
Крім того, це може означати "що є зобов'язанням, яке я б назвав HEAD 5 хвилин тому, наприклад, якби я" git show HEAD "тоді".


git1.8.4 (липень 2013) вводить запровадили нове позначення!
(насправді це буде для 1.8.5 або 1.9, Q4 2013: знову введено в команду 9ba89f4 )

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

Див. Комісію cdfd948

Введення тексту " HEAD" стомлює, особливо коли ми можемо використовувати " @" замість цього.

Причина вибору " @" полягає в тому, що це природно випливає із ref@opсинтаксису (наприклад HEAD@{u}), за винятком того, що у нас немає жодної поправки та жодної операції HEAD.

Тож тепер ми можемо користуватися ' git show @~1', і все це доброю доброю.

Досі ' @' було дійсною назвою, але воно суперечить цій ідеї, тому давайте зробимо її недійсною. Напевно, дуже мало людей, якщо такі є, використовували це ім'я.


Повідомлення в блозі протягом періоду 1.8.4-rc3 (14 серпня 2013 року) оголосило, що ця функція була скасована і відкладена (Дякую Cupcake за голову ).
Знову ж таки, він знову вводиться з комітом 9ba89f4 (вересень 2013).

Див. Команду 2c2b664 :

Скасувати "Додати нову @ярлик для HEAD"

Це повертає до виконання cdfd948 , оскільки це не просто стосується " @" (і форм з модифікаторами, як @{u}застосовано до нього), але також впливає, наприклад, на " refs/heads/@/foo", що не повинно.

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


Після запуску git скиньте ORIG_HEAD і виконайте команду. ORIG_HEAD все ще є під Посиланнями поруч із HEAD. Чому його не видалили з виду?
порошок366

@ powder366, але засіб git resetбуде генерувати a ORIG_HEAD. Тож вам потрібно rmце вручну. Наприклад, див. Stackoverflow.com/a/12418078/6309
VonC

1
@VonC @псевдонім HEADв даний час повернуті (тимчасово?) Для Git 1.8.4 релізу ! Це було щойно оголошено сьогодні!

Сподобався коментар "хед-ап"!
Робіно

2

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

Наприклад, git-rebase та git-am записують оригінальну підказку гілки перед тим, як застосувати будь-які зміни.


4
HEAD не завжди вказує на поточну гілку (її можна від'єднати)
VonC

1
Отже, що таке "поточна гілка", коли HEAD "відривається"?
cjs

@ CurtJ.Sampson Це "немає гілки". ось чому, коли ви в відстороненій голові, ви робите git branch foo -bдля того, щоб "створити" гілку для цих сиріт.
Рой Намір

1

Від man 7 gitrevisions:

HEAD називає комісію, на якій ви базували зміни в робочому дереві. FETCH_HEAD записує гілку, яку ви отримали з віддаленого сховища, за допомогою останнього виклику git fetch. ORIG_HEAD створюється командами, які різко переміщують вашу ГОЛОВУ, записуючи положення ГОЛОВКИ перед їх роботою, щоб ви могли легко змінити кінчик гілки назад у стан, перш ніж ви запускаєте їх. MERGE_HEAD записує фіксацію (и), яку ви об'єднуєте у свою філію під час запуску git merge. CHERRY_PICK_HEAD записує фіксацію, яку ви збираєте вишнею, коли запускаєте git cherry pick.

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