Git - Что такое "Refspec"

Я слежу за этим руководством по настройке непрерывной интеграции GitLab с Jenkins.

Как часть процесса, необходимо установить respec следующим образом

+refs/heads/*:refs/remotes/origin/* +refs/merge-requests/*/head:refs/remotes/origin/merge-requests/ *

Почему это необходимо, не объясняется в сообщении, поэтому я начал искать в Интернете объяснения и смотрел официальную документацию, а также некоторые связанные с этим вопросы, подобные этой.

Несмотря на это, я все еще смущен -

Что такое refspec?

И почему нужен вышеуказанный refspec - что он делает?

Ответ 1

Refspec сообщает git, как сопоставить ссылки с удаленного репозитория на локальный.

Значение, которое вы перечислили, было +refs/heads/*:refs/remotes/origin/* +refs/merge-requests/*/head:refs/remotes/origin/merge-requests/*; так что давай сломать это.

У вас есть два образца с пробелом между ними; это просто означает, что вы даете несколько правил. (В книге "Pro git" это упоминается как два refspecs; это, вероятно, технически более правильно. Однако у вас всегда есть возможность перечислить несколько refspecs, если вам нужно, поэтому в повседневной жизни это, вероятно, не имеет большого значения).

Первый шаблон - это +refs/heads/*:refs/remotes/origin/*, который состоит из трех частей:

  1. + означает применять правило без сбоев, даже если это приведет к перемещению целевого ссылки без ускоренной перемотки вперед. Я вернусь к этому.
  2. Часть до : (но после +, если она есть) является паттерном "источник". Это refs/heads/*, означающее, что это правило применяется к любой удаленной ссылке в refs/heads (имеется в виду, ветки).
  3. Часть после : является шаблоном "назначения". Это refs/remotes/origin/*.

Таким образом, если у источника есть ветвь master, представленная как refs/heads/master, это создаст ссылку на удаленную ветвь origin/master, представленную как refs/remotes/origin/master. И так далее для любого имени ветки (*).

Итак, вернемся к этому +... предположим, что источник имеет

A --- B <--(master)

Вы получаете и, применяя этот refspec, вы получаете

A --- B <--(origin/master)

(Если вы применили типичные правила отслеживания и выполнили pull, у вас также будет master указатель на B.)

A --- B <--(origin/master)(master)

Теперь некоторые вещи происходят на пульте. Кто-то, возможно, сделал reset, который стер B, затем совершил C, а затем вызвал толчок. Так что пульт говорит

A --- C <--(master)

Когда вы получаете, вы получаете

A --- B
 \
  C

и git должен решить, разрешить ли перемещение origin/master из B в C. По умолчанию это не будет разрешено, потому что это не ускоренная перемотка вперед (она скажет вам, что отклонил извлечение для этой ссылки), но поскольку правило начинается с +, оно примет его.

A --- B <--(master)
 \
  C <--(origin/master)

(Пул в этом случае приведет к фиксации слияния.)

Второй шаблон аналогичен, но для ссылок merge-requests (я полагаю, это связано с реализацией PR вашего сервера; я не знаком с этим).

Подробнее о refspecs: https://git-scm.com/book/en/v2/Git-Internals-The-Refspec