Имея трудное понимание git -fetch
Мне сложно понять нюансы git -fetch. Я понимаю, что выполнение fetch
, выбор удаленных ссылок в локальной ветке отслеживания.
У меня есть несколько вопросов:
-
Возможно ли, что локальная ветвь отслеживания не существует? Если это так, будет ли оно автоматически создано?
-
Что произойдет, если я сделаю fetch
и укажите ветку не отслеживания в качестве адресата?
-
Страница руководства для git -fetch указывает:
git-fetch <options> <repository> <refspec>
Как использовать refspec для извлечения содержимого из моего удаленного мастера в удаленную ветку отслеживания? Я считаю, что это возможно, если мой текущий HEAD находится на master, и я запускаю
git fetch origin master
Однако могу ли я использовать refspec <+?src:dest>
для достижения того же? Я думаю, что это поможет мне лучше понять концепции.
И еще один вопрос:
В моем файле .git/config имеется следующая строка для выбора (показывая только соответствующие строки):
fetch = +refs/heads/*:refs/remotes/origin/*
Может кто-нибудь объяснить, что именно эта строка означает?
Ответы
Ответ 1
Во-первых, нет такой концепции локальных ветвей отслеживания, только удаленные ветки отслеживания. Таким образом origin/master - это ветвь удаленного отслеживания для master в реестре origin.
Обычно вы выполняете git fetch $remote, который обновляет все ваши ветки удаленного отслеживания и при необходимости создает новые.
Тем не менее, вы также можете указать refspec, но это не коснется ваших ветвей удаленного отслеживания, вместо этого оно выберет указанную ветку и сохранит ее на FETCH_HEAD, если вы не укажете адресата. В общем, вы не хотите связываться с этим.
Наконец,
fetch = +refs/heads/*:refs/remotes/origin/*
Это означает, что если вы делаете
git fetch origin
На самом деле это будет делать:
git fetch origin +refs/heads/*:refs/remotes/origin/*
Это означает, что удаленные head/foobar будут локальными удаленными/исходными/foobar, а знак плюса означает, что они будут обновлены, даже если они не будут быстрыми, вперед.
Возможно, то, что вы считаете веткой отслеживания, связано с git pull и конфигурацией слияния.
Ответ 2
felipec ответил на большинство вопросов, о которых идет речь в его ответе.
Несколько оставшихся (большинство взятых из git fetch manpage, который немного устарел в некоторых местах, к сожалению):
-
Если ветвь удаленного отслеживания (ветвь, которая отслеживает какую-либо ветвь в каком-то удаленном репозитории) не существует, она будет создана.
-
Входящая ветвь (<dst>
in [+]<src>:<dst>
) не должна находиться в пространстве имен remotes/<remote>/
. Например, для зеркалирования репозиториев (git clone --mirror
) refspec - от 1 до 1. В старые времена перед раздельным расположением пультов (до remotes/<remote>/
пространства имен для удаленных следящих ссылок) главная ветвь была выбрана в ветки с именем origin. Даже теги текущего времени выбираются непосредственно в пространство имен tags/
при зеркальном отображении.
-
Если вы выберете ветвь (правая часть refspec <src>:<dst>
существует, Git будет проверять, приведет ли загрузка к быстрой перемотке вперед, т.е. если текущее состояние в <dst>
является предком состояние в <src>
в данном удаленном репозитории. Если это не так, и вы не используете опцию -f
/--force
для git -fetch или префикс refspec с '+' (используйте +<src>:<dst>
refspec ) fetch отказался бы обновить эту ветвь.
-
git fetch origin master
эквивалентен git fetch origin master:
, а не git fetch origin master:master
; он сохраняет полученное значение ведущей ветки (удаленного происхождения) в FETCH_HEAD, а не в ветки ведущей ветки или дистанционной отслеживания remotes/origin/master
. За ним может следовать git merge FETCH_HEAD
. Обычно не используется напрямую, а как часть однократного нажатия без настройки ветки удаленной отслеживания: git pull <URL> <branch>
.
-
+refs/heads/*:refs/remotes/origin/*
как значение для конфигурации конфигурации remote.origin.fetch означает, что каждая ветвь (ref in refs/heads/
namespace) в удаленном начале выбирается в соответственно названную ветку удаленного отслеживания в пространстве имен refs/remotes/origin/
, например. ведущая ветвь в источнике (т.е. refs/heads/master
ref) будет загружена в ветвь удаленного отслеживания происхождения/мастер (т.е. refs/remotes/origin/master
ref). Префикс "+" означает, что выборка будет успешной даже в случае без быстрой перемотки вперед, что означает, что ветвь на удаленном сервере переустановлена или перематывается (reset в какое-то состояние в прошлом) или иным образом изменена.
Sidenote: Возможно, вы захотите использовать более высокий уровень git remote для управления удаленными репозиториями и получения обновлений.
Ответ 3
Обратите внимание, что главный поддерживающий для Git теперь (Git 2.1, август 2014 года) добавил это объяснение git fetch
:
(совершить fcb14b0 Junio C Hamano (gitster
):
КОНФИГУРИРОВАННЫЕ ФИЛИАЛЫ REMOTE-TRACKING
Вы часто взаимодействуете с одним и тем же удаленным репозиторием регулярно и многократно извлекаете из него. Чтобы отслеживать прогресс такого удаленного репозитория, git fetch
позволяет настраивать переменные конфигурации remote.<repository>.fetch
.
Обычно такая переменная может выглядеть так:
[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
Эта конфигурация используется двумя способами:
-
Когда git fetch
запускается без указания того, какие ветки и/или теги будут извлекаться в командной строке, например. Значения git fetch origin
или git fetch
, remote.<repository>.fetch
используются как refspecs --- они определяют, какие refs для fetch и какие локальные ссылки обновлять.
В приведенном выше примере будут отобраны все ветки, которые существуют в origin
(то есть любой ref, который соответствует левой стороне значения, refs/heads/*
) и обновляют соответствующие ветки удаленного отслеживания в иерархии refs/remotes/origin/*
.
-
Когда git fetch
запускается с явными ветвями и/или тегами для извлечения в командной строке, например. git fetch origin master
, <refspec>
, указанные в командной строке, определяют, что нужно извлечь (например, master
в примере, который является короткой для master:
, что, в свою очередь, означает "выборка" master
', но я не говорю о том, что ветвь удаленного отслеживания обновляется с ней из командной строки "), и команда example будет извлекать только ветку' master
.
Значения remote.<repository>.fetch
определяют, какая ветка удаленного отслеживания, если она есть, обновляется.
При использовании таким образом значения remote.<repository>.fetch
не влияют на выбор того, что получает (то есть значения не используются как refspecs, когда в командной строке перечислены refspecs); они используются только для определения того, где refs, которые извлекаются, сохраняются, действуя как отображение.
Ответ 4
Обратите внимание также, что при Git 2.5+ (Q2 2015) git merge FETCH_HEAD
может объединить несколько git fetch.
См. совершить d45366e Junio C Hamano (gitster
), 26 марта 2015 года.
(объединено Junio C Hamano - gitster
- в commit bcd1ecd, 19 мая 2015 г.)
"git merge FETCH_HEAD
" узнал, что предыдущим "git fetch
" может быть создание слияния Octopus, т.е. запись нескольких ветвей, которые не помечены как "не для слияния"; это позволяет нам потерять вызов старого стиля "git merge <msg> HEAD $commits...
" в реализации "git pull
" script; синтаксис старого стиля теперь может быть устаревшим.
git merge
doc теперь упоминают:
Если указано FETCH_HEAD
(и никакая другая фиксация), ветки, записанные в файле .git/FETCH_HEAD
предыдущим вызовом git fetch
для объединения, объединяются в текущую ветвь.
Git 2.13 (Q2 2017) официально удаляет старый синтаксис git merge
.
См. commit b439165 (26 марта 2015 г.) Junio C Hamano (gitster
).
(слияние Юнио С Хамано - gitster
- в commit 1fdbfc4, 30 марта 2017 г.
merge
: drop 'git merge <message> HEAD <commit>
' синтаксис
Остановить поддержку "git merge <message> HEAD <commit>
" синтаксиса, который имеет был устаревшим с октября 2007 года и выдает предупреждение об отказе от версии с версии 2.5.0.
Это означает, что в старом стиле "'git merge <msg> HEAD <commit>' is deprecated.
" появляется предупреждающее сообщение.