2020-05-12
На практике оказалось очень важным понимать суть git pull
и отличие от git fetch
и git remote update
.
Для понимания работы git remote update
важно иметь представление о ссылках в Git. Ссылка - это некоторый текстовый указатель на коммит с определенным хэшем. По сути ссылка подменяет сложный в прочтении хэш. Более того, все имена веток на самом деле представляют собой ссылки на последний коммит в этой ветке. Ссылка реализована в виде файла, который содержит хэш коммита, на который она указывает. Сами файлы лежат в подкаталоге .git/refs/:
$ ls .git/refs/
heads remotes tags
$ ls .git/refs/heads/ # локальные ветки репозитория
somebranch master
$ cat .git/refs/heads/master
2c3d6d2317874f7e3a433751f5487cbf81f83030 # хэш последнего коммита в ветке master
Ссылки можно создавать вручную. Особая ссылка - HEAD. Она всегда указывает на последний коммит в текущей рабочей ветке:
$ cat .git/HEAD
ref: refs/heads/somebranch # если мы в ветке somebranch
Для удобства работы с удаленными репозиториями в Git существуют т.н. ссылки на отслеживаемые ветки. Ссылка на отслеживаемую ветку - это ссылка на локальный коммит, скачанный когда-то с удаленного репозитория и соответствующий удаленной ветке на момент скачивания. Ссылка на отслеживаемую ветку имеет вид origin/master
, где вместо origin
будет псевдоним удаленного репозитория, а вместо master
- название скачанной ветки. Хорошо на примере объяснено здесь: https://vk.cc/aiXzKs
Здесь в русскоязычной документации есть путаница, где схожие понятия переводятся одинаково. Локальная ветка, скачанная с удаленного репозитория, автоматически настраивается на отслеживание оригинальной ветки (tracking branch -> upstream branch). Это означает, что такие команды, как git fetch
и git pull
, вызванные в этой ветке, будут автоматически обработаны для нужной upstream branch. Локальную ветку по удаленной можно создать командой git checkout --track origin/somebranch
.
git fetch
стягивает коммиты удаленной ветки и обновляет локальную ветку начиная с предыдущей ссылки на отслеживаемую ветку:
git remote update
сделает это действие со всеми локальными ветками в репозитории. Если не выставлены специфичные настройки, то команда равнозначна git fetch --all
.
git pull
не только стянет новые коммиты с удаленного репозитория, но и произведет их слияние в указанную ветку. git pull remote HEAD
выполнит слияние ветки origin/HEAD с текущей локальной веткой.
Материалы для прочтения: