10.3. Git References
Это типа конспект, который я веду для себя, чтобы получше разобраться и запомнить. Вероятно, вам лучше сразу читать оригинал: 10.3 Git References.
References
Как мы можем видеть, в файлах веток и тэгов указан objectId
того объекта, на который идёт ссылка.
Так можно создать ветку:
echo 1a410efbd13591db07496601ebc7a059dd55cfe9 > .git/refs/heads/master
Однако есть более феншуйный способ:
git update-ref refs/heads/master 1a410efbd13591db07496601ebc7a059dd55cfe9
git update-ref refs/heads/master 1a410e
Этот способ лучше, потому что тогда изменения веток отражаются в рефлоге,
который можно посмотреть командой git reflog.
Если запихать в ветку коммит, то можно написать:
git log master
Если, к примеру, ветка будет указывать на дерево, то git log ничего не покажет, равно как и с самим айдишником дерева.
HEAD
Обычно HEAD — это указание на текущую ветку, причём на саму ветку, а не на коммит, куда она указывает. Это называется symbolic reference. Когда вы находитесь на коммите вне веток, то HEAD указывает на сам коммит.
Для работы с симрефами есть команда, хотя и cat + echo подойдёт:
$ git symbolic-ref HEAD refs/heads/test
$ cat .git/HEAD
ref: refs/heads/test
$ git symbolic-ref HEAD
refs/heads/test
Ссылку непонятно куда нельзя создать:
$ git symbolic-ref HEAD test
fatal: Refusing to point HEAD outside of refs/
Можно создать симреф с любым именем:
$ git symbolic-ref chiv refs/heads/master
$ git symbolic-ref chiv
refs/heads/master
$ git log chiv
commit ba8770af76b13e53c265c8bfdf4924ad968c911e (HEAD -> master)
Author: Scott Chacon <schacon@gmail.com>
Date: Fri May 22 18:09:34 2009 -0700
First commit
Симрефы создаются в корне.git:
$ ls .git
HEAD
chiv
config
description
hooks
index
info
objects
refs
sourcetreeconfig
$ cat .git/chiv
ref: refs/heads/master
Tags
Как мы рассказывали в Git Basics тэги бывают двух видов: аннотированные и лёгкие.
Лёгкий:
$ git update-ref refs/tags/v1.0 15fa4d36b23f62d4650f03b17d40c61736ce658e
$ cat .git/refs/tags/v1.0
15fa4d36b23f62d4650f03b17d40c61736ce658e
$ git cat-file -p refs/tags/v1.0
tree d8329fc1cc938780ffdd9f94e0d364e0ea74f579
author Scott Chacon <schacon@gmail.com> 1243040974 -0700
First commit
Тот же эффект:
$ git tag v1.0.1 15fa4d36b23f62d4650f03b17d40c61736ce658e
$ cat .git/refs/tags/v1.0.1
15fa4d36b23f62d4650f03b17d40c61736ce658e
Аннотированный:
$ git tag -a v1.1 15fa4d36b23f62d4650f03b17d40c61736ce658e -m 'Test tag'
$ cat .git/refs/tags/v1.1
01be226321c4380a974fee5fce896133cf966c66
$ git cat-file -p refs/tags/v1.1
object 15fa4d36b23f62d4650f03b17d40c61736ce658e
type commit
tag v1.1
tagger Chivorotkiv <git@chiv.info> 1619493174 +0600
Test tag
Аннотированным тэгом можно тэгнуть любой объект:
In the Git source code, for example, the maintainer has added their GPG public key as a blob object and then tagged it. You can view the public key by running this in a clone of the Git repository:
$ git cat-file blob junio-gpg-pubThe Linux kernel repository also has a non-commit-pointing tag object — the first tag created points to the initial tree of the import of the source code.
А можно ли обычным? Вроде можно:
$ git tag tag-a-tree 3c4e9cd789d88d8d89c1073707c3585e41b0e614
$ cat .git/refs/tags/tag-a-tree
3c4e9cd789d88d8d89c1073707c3585e41b0e614
$ git cat-file -t refs/tags/tag-a-tree
tree
$ git tag
tag-a-tree
v1.0
v1.1
Remotes
Это read-only рефы, которые указывают на те же объекты, на которые указывали рефы репозитория на сервером в тот момен, когда ваш репозиторий в прошлый раз контачил с тем сервером.
Если вы сделаете туда git cehckout, то HEAD не станет симрефом на реф из remotes, и вы не сможете сдвинуть эту ветку сделав коммит.