Что такое ГОЛОВА в git?

232

Кажется, есть разница между последним коммитом, HEAD и состоянием файла, который я вижу в моем каталоге.

Что такое ГОЛОВА, что я могу с ней сделать и какой ошибки следует избегать?

е-удовлетворяться
источник
1
Начиная с Git версии 1.8.4, все ответы ниже , что используют HEADили headмогут теперь использовать @вместо HEADвместо этого. Посмотрите этот ответ (последний раздел), чтобы узнать, почему вы можете это сделать.
3
Из git-scm : HEAD в Git - это указатель на текущую ссылку на ветвь, которая, в свою очередь, является указателем на последний сделанный вами коммит или последний коммит, который был извлечен в ваш рабочий каталог. Это также означает, что это будет родитель следующего коммита, который вы делаете. Как правило, проще всего думать об этом, поскольку HEAD - это снимок вашего последнего коммита.
Quazi Irfan
3
Возможный дубликат Что такое HEAD в Git?
Бутс

Ответы:

185

HEAD - это ссылка на последний коммит в текущей извлеченной ветке.


Есть небольшое исключение, это отдельная ГОЛОВА. Отдельностоящая ГОЛОВА ситуация вы в конечном итоге в каждый раз , когда вы извлекаете совершить (или тег) вместо филиала. В этом случае вы должны представить это как временную ветку без имени; поэтому вместо ссылки на именованную ветку у нас есть только HEAD. Он по-прежнему позволит вам совершать коммиты (что приведет к обновлению HEAD), поэтому приведенное выше краткое определение остается верным, если вы думаете об отключенном HEAD как о временной ветви без имени.

совать
источник
1
Так почему у тебя две головы?
e-удовлетворительно
1
@ e-sat: иногда вы видите ветви, называемые головами - они хранятся в refs/heads. Строчная голова отличается от HEAD, тем не менее. Мой ответ проясняет это немного.
Каскабель
7
@ E-удовлетворительно: это не регулярное выражение. Это ^просто обозначение git для «commit before» - это коммит перед текущим. (Если текущий является слиянием, он использует первого родителя.)
Cascabel
1
@ e-sat: см. раздел с указанием ревизий справочной страницы для git-rev-list для получения дополнительной информации обо всех способах указания коммитов - это всего лишь одна маленькая деталь. kernel.org/pub/software/scm/git/docs/…
Каскабель
1
Нет, когда rev и HEAD указывают на один и тот же коммит, разницы нет. И вы могли бы даже написать идентификатор фиксации (значение SHA-1) вместо rev или HEAD. И не волнуйтесь, вы не беспокоите нас вопросами :) (я, по крайней мере: P)
тыкайте
87

HEAD является ссылкой (ссылкой) на текущий извлеченный коммит.

В нормальных состояниях это фактически символическая ссылка на ветку, которую вы извлекли - если вы посмотрите на содержимое .git / HEAD, вы увидите что-то вроде «ref: refs /head / master». Сама ветка является ссылкой на коммит в конце ветки. Следовательно, в нормальном состоянии HEADфактически относится к коммиту в конце текущей ветви.

Также возможно иметь «отделенную ГОЛОВУ». Это происходит, когда вы извлекаете что-то помимо (локальной) ветки, например, удаленную ветку, определенный коммит или тег. Чаще всего это можно увидеть во время интерактивного перебазирования, когда вы решаете редактировать коммит. В отключенном состоянии HEAD ваш HEAD является прямой ссылкой на коммит - содержимое .git / HEAD будет хешем SHA1.

Вообще говоря, HEAD - это просто удобное название, означающее «то, что вы проверили», и вам не нужно сильно беспокоиться об этом. Просто будьте в курсе того, что вы извлекли, и помните, что вы, вероятно, не захотите фиксировать, если вы не находитесь в ветке (состояние отсоединенного HEAD), если вы не знаете, что делаете (например, находитесь в интерактивной перебазировке) ,

Cascabel
источник
6
Это то, что я не понимаю. Если вы извлекаете удаленную ветку, почему вы получаете «отделенную головку». Почему бы вам автоматически не перейти в ветку локального репо, соответствующую вашему пульту?
e-удовлетворительно
3
@ e-sat: Если вы хотите местное отделение, проверьте местное отделение. Помните, что они не обязательно одинаковы - вы должны указать локальному объединить удаленный (или потянуть). Отслеживание просто так, что он знает, какой из них автоматически тянуть, когда вы спрашиваете. Причина, по которой он отсоединен, заключается в том, что удаленная ветвь предназначена для того, чтобы указывать на последнее увиденное местоположение ветки в удаленном репо. Если вы попытаетесь зафиксировать его, удаленное хранилище не изменится, поэтому удаленная ветвь тоже не должна.
Каскабель
1
Хорошо, это то, что я не получил: локальная ветвь, названная таким образом, не означает, что она такая же, как и удаленная. Действительно трудно понять в начале, потому что я родом из SVN :-) Спасибо, мужик. Кстати, как вы перемещаете головку без головы в местный филиал, чтобы зафиксировать это здесь?
e-удовлетворительно
3
@ E-удовлетворительно: общий ответ git rebase <branch> HEAD. Это найдет последнего общего предка <branch>и HEAD, а затем возьмет все коммиты оттуда HEADи применит их (перебазирует их) <branch>. По сути, он делает это, применяя их как патчи, поэтому, если две ветви действительно разные, могут возникнуть конфликты. Но если <branch>это предок HEAD(то есть вы были в нужном месте, просто забыли, что отсоединились HEAD), то ребаз - это просто слияние в ускоренном режиме.
Каскабель
3
Это одно из самых ясных и точных описаний git HEAD, которое я видел после некоторого поиска.
LarsH
21

Я всегда думал, HEAD~5значит GO до 5 коммитов раньше. Но это не несет GO часть команды. Он содержит только ссылку / «где» часть команды.

С точки зрения непрофессионала, он используется для ответа на вопрос: КУДА мне идти? К чему совершать?

  • HEAD означает (ссылка на) текущий коммит
  • HEAD~1 означает (ссылка на) 1 коммит до
  • HEAD~ ТАКЖЕ означает (ссылка на) 1 коммит до
  • HEAD~87 значит (ссылка на) 87 совершает раньше

Использование:

  • git checkout HEAD~1 будет на самом деле GO / Checkout до 1 коммит / ссылка до
  • git reset HEAD~3 будет отменять ваши последние 3 коммита - без удаления изменений, то есть вы можете увидеть все изменения, сделанные за последние 3 коммита вместе, удалить все, что вам не нравится или добавить в него, а затем зафиксировать их снова.
  • git reset --hard HEAD~3отменяет ваш последний коммит и удаляет их изменения . Это полностью удалит эти изменения. Подробнее смотрите здесь .
  • git diff HEAD~3 для проверки изменений в последних 3 коммитах
Мед
источник
3
возвращаясь к моему собственному ответу :)
Honey
15

Указатель HEAD в Git

Git поддерживает ссылочную переменную под названием HEAD. И мы называем эту переменную указателем, потому что ее целью является указание или указание на конкретную фиксацию в хранилище. Когда мы делаем новые коммиты, указатель изменится или переместится, чтобы указать на новый коммит. HEAD всегда указывает на верхушку текущей ветки в нашем репозитории. Теперь это касается нашего репозитория, а не нашего промежуточного индекса или нашего рабочего каталога.

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

Я думаю, что хорошей метафорой для размышления является воспроизведение и запись на кассетный магнитофон. Когда мы начинаем записывать звук, лента проходит мимо головы и записывается на нее. когда мы нажимаем «Стоп», то место, где останавливается головка записи, - это место, где она начинает запись снова, когда мы нажимаем «Запись» второй раз. Теперь мы можем перемещаться, мы можем перемещать головку в разные места, но везде, где расположена головка когда мы снова нажмем на «Запись», именно там начнется запись.

Указатель HEAD в Git очень похож, он указывает на то место, где мы собираемся начать запись дальше. Это место, где мы остановились в нашем хранилище для того, что мы совершили.

Сухай гупта
источник
0

Проще говоря, HEAD - это ссылка на последний коммит в текущей ветви извлечения.

Думайте о ГОЛОВЕ как о "текущей ветви". Когда вы переключаете ветки с помощью git checkout, ревизия HEAD изменяется, чтобы указывать на вершину новой ветки.

Вы можете увидеть, на что указывает HEAD:

cat .git/HEAD

HEAD может ссылаться на конкретную ревизию, которая не связана с именем ветви. Эта ситуация называется отдельной головой.

Testilla
источник