Каждый репозиторий Git имеет свои собственные копии имен.Каждое имя соответствует точно одному хеш-идентификатору, например, в вашем примере:
c31a55 refs/heads/fix-async-stdout-order
615f5a refs/pull/10/head
вы предложили, что refs/heads/fix-async-stdout-order
сопоставляется с хэш-идентификатором c31a55
и refs/pull/10/head
отображаются на хеш-код 615f5a
. 1
Имена - это то, что Git вызывает refs или ссылка .(Хеш-идентификаторы - это хеши, с которыми вы должны быть хорошо знакомы.)
В большинстве случаев, когда вы даете Git имя, Git сразу же превращает его в базовый хеш-идентификатор.Хеш-идентификаторы - вот что действительно важно: имена в основном предоставляются, чтобы позволить нам, простым людям, иметь дело с настоящими именами, которые являются хеш-идентификаторами.Хеш-идентификаторы никогда не меняются: они всегда однозначно идентифицируют этот конкретный контент - например, один конкретный коммит.Коммит и его хэш-идентификатор вечны, в то время как одно или несколько имен могут быть созданы или уничтожены по желанию или прихоти. 2
Когда имя идентифицирует коммит, мы можем использовать имя напрямуючтобы найти фиксацию: refs/heads/fix-async-stdout-order
, например, идентифицирует фиксацию c31a55
.Но коммиты также позволяют нам находить их непосредственные родительские коммиты: с c31a55
мы можем работать в обратном направлении к тому, кем является его родитель, и из этого родителя мы можем работать в обратном направлении, еще один шаг к другому коммиту, и так далее,вплоть до начала времен в хранилище.Таким образом, имя, подобное этому, служит не только для поиска одного коммита, чей хеш-идентификатор он хранит, но также всех более ранних коммитов в его цепочке .
Когда имя является branch name - как и этот - Git также позволяет нам использовать его специально с git checkout
.Команда git checkout
присоединяет другое специальное имя, HEAD
, к имени ветви.Теперь Git считает нас «включенными» в ветке, поэтому, если мы сделаем новые коммиты, Git автоматически изменит идентификатор хеша, хранящийся под именем этой ветви .
То есть после:
git checkout fix-async-stdout-order
, если мы выполним некоторую работу, а затем сделаем новый коммит, имя fix-async-stdout-order
- которое на самом деле refs/heads/fix-async-stdout-order
, мы простосократил его для целей отображения - перестанет указывать на коммит c31a55
и вместо этого начнет указывать на наш новый коммит.Наш новый коммит будет иметь c31a55
в качестве родительского элемента.
Это свойство, позволяющее получать «на» ветке, разрешено только для branch имён.У Git много имен: имена веток, имена тегов, имена для удаленного отслеживания и так далее.Все они ссылки , но только ссылки, написание которых начинается с refs/heads/
, являются именами ветвей.
Ссылка refs/tags/v1.2
, если она существует, является тегом named v1.2
.
Ссылкой refs/remotes/origin/master
, если она существует, является имя удаленного отслеживания origin/master
.
Каждый из этих префиксов - refs/heads/
, refs/tags/
и refs/remotes/
- представляет пространство имен .Ссылки в пространстве имен refs/heads/
являются именами ветвей .
Помимо того, что они являются специальными с точки зрения разрешения git checkout
использовать их описанным выше способом, другая особенность branch name появляется, когда клиентский Git, такой как ваш собственный Git, подключается к серверу Git.Сервер Git отображает для клиента все его имена, включая имена ветвей, а также хэш-идентификаторы, которые представляют эти имена. клиент Git копирует ответвления имен сервера, но меняет их одновременно, так что сервер вызывает refs/heads/master
клиент вызывает refs/remotes/origin/master
.
Этот процесс позволяет вашему Git иметь имена для удаленного отслеживания.У сервера Git есть свои ветви, и ваш Git приходит вместе - когда вы запускаете git fetch
- и видит, а затем запоминает их ветви как ваши имена для удаленного слежения origin/*
.Они живут в вашем Git, в пространстве имен refs/remotes/
.
Этот процесс происходитurs только для имен ветвей! 3 Поскольку refs/pull/10/head
не начинается с refs/heads/
, это не имя ветви.Процесс не распространяется на refs/pull/10/head
.Вот почему и чем heads
отличается от pull
.
1 Это оба сокращенные хеш-идентификаторы;фактические хеш-идентификаторы в настоящее время всегда имеют длину 40 символов.
2 Предупреждение здесь заключается в том, что без имени можно найти коммит или другой объект Git,этот коммит или другой объект теперь незащищен от процесса сборки мусора в Git.Таким образом, не только имена позволяют нам находить последний коммит в цепочке, они также защищают этот коммит и всех его предшественников от вывоза в качестве мусора.
3 Процесс программируется через то, что Git называет refspecs .Вышеприведенное описание относится только к стандартным refspecs, которые вы получаете при запуске git clone
.Если вы создаете свои собственные refspecs, вы можете изменить то, что происходит здесь.См. документацию git fetch
и обратите внимание, что remote.origin.fetch
является совокупной настройкой ;каждый экземпляр remote.origin.fetch
предоставляет один refspec.
По умолчанию во время клонирования Git создает один параметр remote.origin.fetch
, который либо копирует все их ветвей в ваше дистанционное отслеживаниеимена или копии одной их ветвей на одну имя для удаленного слежения, если вы выбрали --single-branch
во время клонирования.