Имея трудное понимание 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." появляется предупреждающее сообщение.