Git fetch vs. git fetch Основной хозяин имеет разные эффекты на ветки отслеживания
В основном это характер любопытства, поскольку я пытаюсь познакомиться с Git. Я просмотрел документацию для "git fetch", но я не вижу очевидного объяснения ниже. Заранее благодарим и извиняюсь, если это вопиюще очевидно.
1) Из центрального репозитория, скажем GitHub, я клонировал репозиторий с именем website
на каждой из двух машин, HostA
и HostB
.
2) на HostA
, я вношу изменения в файл, скажем README.txt
, и фиксирую его.
В этот момент на HostA
коммиты для ветвей master
и
origin/master
, как и ожидалось, отличаются, так как я еще не нажал
git show master
git show origin/master
сообщать о разных хэшах (так как master
имеет изменение, а origin/master
- нет)
3) Как только я нажимаю, они после этого то же самое.
4) Теперь, на HostB
, если я делаю следующее:
git fetch
git merge FETCH_HEAD
впоследствии, на HostB master
и origin/master
сообщать о том же хэше, когда запрашивается с помощью git show
НО
Если бы я сделал это, на HostB
:
git fetch origin master
git merge FETCH_HEAD
в этот момент хеши все еще отличаются.
git show origin
git show origin/master
сообщить о разных хэшах
Отслеживание origin/master
не обновляется до тех пор, пока я не сделаю простой git fetch
Почему это?
Ответы
Ответ 1
Если у вашей ветки есть связанная ветка удаленного отслеживания, это означает, что ее конфигурация выглядит следующим образом:
git config branch.[branch-name].remote [remote-name]
git config branch.[branch-name].merge [remote-master]
Ключевая часть git fetch
, объясняющая разницу между этими двумя командами:
<refspec>
Формат параметра <refspec>
является необязательным плюсом +
, за которым следует ссылка на источник <src>
, за которой следует двоеточие :
, а затем ссылка на назначение <dst>
.
Удаленная ссылка, соответствующая <src>
, извлекается, и , если <dst>
не является пустой строкой, локальная ссылка, которая соответствует ей, быстро пересылается с использованием <src>
.
Позвольте мне повторить это:
если <dst>
не является пустой строкой, локальная ссылка, которая соответствует ему, быстро пересылается с помощью <src>
.
Зная это:
git fetch
эквивалентно git fetch origin master:master
(из значения по умолчанию вашей конфигурации ветки), поэтому он обновит ветку удаленного отслеживания: для вас указан пункт назначения refspec.
git fetch origin master
эквивалентно "git fetch origin master:
", а не "git fetch origin master:master
"; он сохраняет извлеченное значение ветки 'master
(удаленного' origin
') в FETCH_HEAD
, а не в ветки' master
'или ветки remotes/origin/master
удаленного слежения (из Jakub Narębskiответить)
Другими словами, вы не указали пункт назначения вашего refspec
Ответ 2
Ответ заключается в сообщениях, которые вы возвращаете из git fetch
. В первом случае, когда вы выбираете без предоставления refspec, вы увидите, что ветки удаленного отслеживания обновляются:
remote: Counting objects: 5, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /depot
c67d1c8..1941673 master -> origin/master
Обратите внимание на то, как в сообщении говорится, что источник/мастер обновляется мастером из источника.
Теперь во втором случае, когда вы указываете refspec, вы получаете что-то совсем другое:
remote: Counting objects: 5, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /depot
* branch master -> FETCH_HEAD
Поэтому, когда вы указываете refspec, ветвь удаленного отслеживания (источник/мастер) НЕ обновляется, только FETCH_HEAD.
Конечным результатом является то, что вы, кажется, опережаете начало/мастер, когда вы на самом деле не похожи. Я не могу себе представить, почему это поведение было бы желательно, но это определенно интересная небольшая причуда команды fetch.
Ответ 3
Если вы хотите ускорить слияние, или используйте git pull. Вы, похоже, не понимаете, что целью git fetch является НЕ обновлять рабочее дерево. Fetch предназначен для обновления ветвей отслеживания.