Трудно понять git-fetch
Мне трудно понять нюансы git-fetch. Я понимаю что делаю fetch
, извлекает удаленные ссылки в локальную ветку отслеживания.
У меня есть несколько вопросов, хотя:
Возможно ли, что локальная ветвь отслеживания не существует? Если да, то будет ли он создан автоматически?
Что будет, если я сделаю
fetch
и указать не отслеживающую ветвь как пункт назначения?Страница man для git-fetch указывает:
git-fetch <options> <repository> <refspec>
Как бы я использовал refspec для извлечения содержимого из моего удаленного мастера в его ветку удаленного отслеживания? Я полагаю, что это может быть возможно, если мой текущий заголовок находится на мастере, и я бегу
git fetch origin master
Тем не менее, я могу использовать <+?src:dest>
refspec добиться того же? Я думаю, что это поможет мне лучше понять концепции.
И еще один вопрос:
Мой файл.git/config имеет следующую строку для извлечения (показывая только соответствующие строки):
fetch = +refs/heads/*:refs/remotes/origin/*
Может кто-нибудь объяснить, что именно означает эта строка?
4 ответа
Во-первых, нет такой концепции локальных ветвей отслеживания, только удаленные ветви отслеживания. Поэтому 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/*
Это означает, что удаленные заголовки /foobar будут локальными remotes / origin /foobar, а знак плюс означает, что они будут обновлены, даже если они не перемотаны вперед.
Возможно, то, что вы считаете ветвью отслеживания, связано с git pull и конфигурацией слияния.
FelipeC ответил на большинство вопросов в своем ответе.
Несколько оставшихся (большая часть взята с man-страницы git fetch; в некоторых местах, к сожалению, немного устаревшей):
Если ветка удаленного отслеживания (ветвь, которая отслеживает какую-то ветку в некотором удаленном хранилище) не существует, она будет создана.
Ветвь, в которую вы входите (
<dst>
в[+]<src>:<dst>
) не нужно проживать вremotes/<remote>/
Пространство имен. Например для зеркалирования репозиториев (git clone --mirror
) refspec от 1 до 1. В старые времена перед разметкой отдельных пультов (доremotes/<remote>/
пространство имен для удаленного отслеживания ссылок) главная ветка была выбрана в ветку, называемую источником. Даже в настоящее время теги извлекаются непосредственно в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 означает, что каждая ветвь (ссылка наrefs/heads/
пространство имен) в удаленном источнике извлекается в соответственно именованную ветку удаленного отслеживания вrefs/remotes/origin/
пространство имен, например, основная ветка в источнике (т.е.refs/heads/master
ссылка ref) будет выбрана в ветку удаленного отслеживания origin / master (т.е.refs/remotes/origin/master
исх). Префикс "+" означает, что выборка будет успешной даже в случае отсутствия быстрой пересылки, что означает, что ветвь на удаленном удалении перебазируется, или перематывается (сбрасывается в какое-то состояние в прошлом) или иным образом изменяется.
Sidenote: Возможно, вы захотите использовать команду git remote более высокого уровня для управления удаленными репозиториями и получения обновлений.
Обратите внимание, что основной сопровождающий для Git (Git 2.1, август 2014 г.) добавил это объяснение для git fetch
:
(См. Коммит fcb14b0 от Junio C Hamano ( gitster
):
КОНФИГУРИРОВАННЫЕ УДАЛЕННО-ГУСЕНИЧНЫЕ ФИЛИАЛЫ
Вы часто взаимодействуете с одним и тем же удаленным хранилищем, регулярно и многократно извлекая из него данные. Чтобы следить за ходом работы такого удаленного хранилища,
git fetch
позволяет настроитьremote.<repository>.fetch
переменные конфигурации.Обычно такая переменная может выглядеть так:
[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
Эта конфигурация используется двумя способами:
когда
git fetch
запускается без указания того, какие ветви и / или теги извлекать в командной строке, напримерgit fetch origin
или жеgit fetch
,remote.<repository>.fetch
значения используются в качестве refspecs- они указывают, какие ссылки нужно выбрать, а какие локальные ссылки обновить.
Приведенный выше пример извлечет все ветви, которые существуют вorigin
(т. е. любая ссылка, которая соответствует левой части значения,refs/heads/*
) и обновить соответствующие ветви удаленного отслеживания вrefs/remotes/origin/*
иерархия.когда
git fetch
запускается с явными ветвями и / или тегами для извлечения в командной строке, напримерgit fetch origin master
,<refspec>
данные в командной строке определяют, что нужно выбрать (например,master
в примере, который является сокращением дляmaster:
что в свою очередь означает "получить"master
'ветвь, но я не говорю явно, какую ветвь удаленного отслеживания обновлять с помощью командной строки'), а пример команды извлекает только 'master
' ветка.
remote.<repository>.fetch
значения определяют, какая ветвь удаленного отслеживания, если таковая имеется, обновляется.
При использовании таким образом,remote.<repository>.fetch
значения не влияют на решение о том, что нужно получить (т. е. значения не используются в качестве refspecs, когда в командной строке перечисляются refspecs); они используются только для определения того, где хранятся ссылки, действующие как отображение.
Также обратите внимание, что с Git 2.5+ (2 квартал 2015 года) git merge FETCH_HEAD
может объединить несколько Git Fetch.
Смотрите коммит d45366e от Junio C Hamano ( gitster
), 26 марта 2015 г.
(Объединено Юнио С Хамано - gitster
- в коммите bcd1ecd, 19 мая 2015 г.)
"
git merge FETCH_HEAD
"узнал, что предыдущий"git fetch
msgstr "возможно создать слияние с осьминогом, т.е. записать несколько веток, которые не помечены как" не для слияния ";
это позволяет нам потерять вызов старого стиляgit merge <msg> HEAD $commits...
"В реализации"git pull
"script; синтаксис старого стиля теперь может быть устаревшим.
git merge
док теперь упомянуть:
когда
FETCH_HEAD
(и никаких других коммитов), ветки записываются в.git/FETCH_HEAD
файл предыдущим вызовомgit fetch
для слияния сливаются с текущей веткой.
Git 2.13 (Q2 2017) официально удаляет старый синтаксис для git merge
,
См. Коммит b439165 (26 марта 2015 г.) от Junio C Hamano ( gitster
)
(Объединено Юнио С Хамано - gitster
- в коммите 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.
" больше не.