Действительно ли ветки равны их последним коммитам в git? - PullRequest
0 голосов
/ 16 декабря 2018

Я читал о "оторванной голове" в git, и это происходит, когда кто-то проверяет "коммит" вместо "ветки".

Часть любопытства для меня (которую я не смог проверить с помощьюman pages или Google) является ли ветка действительно внутренне ссылкой на ее последний коммит?(В противном случае, я думаю, что, возможно, команда checkout может запретить возникновение отсоединенной головы ..., но это не так.)

Если приведенное выше предположение верно, можем ли мы сказать, что все ветви являются ссылками накоммиты на кончике их?

(По сути, это сомнение возросло во мне, когда я прочитал эти два отдельных комментария от двух людей:

  1. HEAD - ссылка (ссылка) на * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1018* * * * * * * * *1018* * * * * * * * * * * * * * * * * *1018* * * * * * * * * * * *1018* * * * * * * *1018* * * * * * * * *1018* * * * * * * *1018* * * * * * * * *1018*предлагает использовать ветки для проверки, так как это гарантирует перемещение HEAD в "tip commit").

Ответы [ 2 ]

0 голосов
/ 16 декабря 2018

Принцип работы HEAD - это содержимое файла .git / HEAD.Извлечение ветви приводит к .git / HEAD, содержащему имя ветви (полный ref).Имя ветви затем оценивается как путь в каталоге .git, который содержит хэш.Поэтому, когда вы делаете новый коммит в этой ветке, меняется только ссылка на хэш последнего коммита..git / HEAD менять не нужно.

Когда вы извлекаете хеш коммита напрямую, .git / HEAD просто содержит хеш коммита.Например, если вы извлекаете хеш коммита, представляющий последний коммит в master , он более или менее совпадает с извлечением master .

Единственное отличиев том, что фиксация master или получение обновлений из общедоступного репозитория не изменит то, к чему вы были извлечены, а фиксация из этого состояния не изменит ветку master .

Пример сеанса, демонстрирующий некоторые из этих моментов:

util$ cat .git/HEAD
ref: refs/heads/master
util$ cat .git/refs/heads/master
3e213b3d373a9d157426db2ae40e0b5b8ba9c3b2
util$ git checkout 3e21
Note: checking out '3e21'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at 3e21 edit_with_editor() takes a line kwarg
util$ cat .git/HEAD
3e213b3d373a9d157426db2ae40e0b5b8ba9c3b2

Таким образом, 'master' оценивает хеш коммита, только косвенно:

util$ git rev-parse master
3e213b3d373a9d157426db2ae40e0b5b8ba9c3b2

Если я сделаюпри фиксации в этом состоянии, он меняет HEAD, но не master:

util$ echo Example change >> README
util$ git commit -a -m "example commit in detached head state"
[detached HEAD 45d4] example commit in detached head state
 1 file changed, 4 insertions(+)
 create mode 100644 README
util$ cat .git/HEAD
45d4b4f7816dc7626be6f7166f7cf972dc18a9d7
util$ git rev-parse master
3e213b3d373a9d157426db2ae40e0b5b8ba9c3b2
0 голосов
/ 16 декабря 2018

Да, ветвь - это просто ссылка на коммит, который обновляется, как только вы делаете новый коммит в его извлечении.Вы даже можете создавать ветки вручную.

(просто готовите репо с двумя коммитами)

$ git init
Initialized empty Git repository in /home/che/foo/.git/
$ touch bar
$ git add bar
$ git commit -minitial
[master (root-commit) 5d512c6] initial
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 bar
$ touch second
$ git add second 
$ git commit -msecond_commit
[master 5aebe72] second_commit
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 second
$ git log --format='%H %s'
5aebe72d3f6cd72c3236021319d8ea43eae899fe second_commit
5d512c6fcec86f02d69a7b4f5f177ec1a6ecb32e initial

(теперь создайте новый файл в .git/refs/heads, который является одним из мест, где gitсохраняет ветки)

$ echo 5d512c6fcec86f02d69a7b4f5f177ec1a6ecb32e > .git/refs/heads/old
$ git branch
* master
old

(или вы можете посмотреть в файлах, есть хэши коммитов, больше ничего)

$ fgrep '' .git/refs/heads/*
.git/refs/heads/master:5aebe72d3f6cd72c3236021319d8ea43eae899fe
.git/refs/heads/old:5d512c6fcec86f02d69a7b4f5f177ec1a6ecb32e

Существуют другие виды ссылок (удаленные ветки и теги), и они также могут храниться в сжатых файлах, поэтому эти файловые операции не всегда будут работать, но вы можете проверить и связываться с ссылками, используя git show-ref и git update-ref.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...