Git - Что такое "Refspec"
Я следовал этому руководству по настройке непрерывной интеграции GitLab с Jenkins.
В рамках этого процесса необходимо установить следующие параметры:
+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/*
который состоит из трех частей:
+
означает применять правило без сбоев, даже если при этом целевой объект будет перемещен без ускоренной перемотки вперед. Я вернусь к этому.
Часть перед :
(но после +
если он есть) - это шаблон "источника". Это refs/heads/*
Это означает, что это правило применяется к любой удаленной ссылке в refs/heads
(смысл, ветки).
Часть после :
это шаблон "назначения". Это 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
и мерзавец должен решить, разрешить ли движение origin/master
от B
в C
, По умолчанию это не допускается, потому что это не ускоренная перемотка вперед (она скажет вам, что она отклонила извлечение для этой ссылки), а потому что правило начинается с +
это примет это.
A --- B <--(master)
\
C <--(origin/master)
(Пул в этом случае приведет к фиксации слияния.)
Второй шаблон похож, но для merge-requests
refs (который, я полагаю, связан с реализацией PR вашего сервера; я не знаком с этим).
Подробнее о refspecs: https://git-scm.com/book/en/v2/Git-Internals-The-Refspec
Refspec сообщает git, как отображать ссылки с удаленного на локальное репо.
В Git 2.29 (Q4 2020) refspec также может указать Git, какую ссылку исключить.
"git fetch
" и "git push
"поддерживать отрицательные ссылки.
Так что не только ты можешь
fetch
выборочно:
# Do not fetch any remote branch starting with 'm'
git fetch origin refs/heads/*:refs/remotes/origin/* ^refs/heads/m*
Но ты можешь даже
push
или же
push --prune
выборочно:
# If I delete local branches, included b,
# those same branches will be deleted in the remote 'origin' repo.
# ... except for the remote branch b!
git push --prune origin refs/heads/* ^refs/heads/b
См. Commit c0192df (30 сентября 2020 г.) Джейкоб Келлер (jacob-keller
).
(Слияние Junio C Hamano -
gitster
- в коммите 8e3ec76, 5 октября 2020 г.)
refspec
: добавить поддержку отрицательных refspecsПодписано: Джейкоб Келлер
И то и другое
fetch
иpush
поддержка шаблонов refspecs, которые позволяют получать или выдвигать ссылки, соответствующие определенному шаблону.
Поскольку эти паттерны представляют собой шары, они имеют несколько ограниченную способность выражать более сложные ситуации.Например, предположим, что вы хотите получить все ветки с пульта дистанционного управления, кроме одной. Чтобы разрешить это, вы должны настроить набор refspecs, который соответствует только нужным вам ветвям.
Поскольку refspecs являются либо явными совпадениями имен, либо простыми глобами, многие шаблоны не могут быть выражены.Добавьте поддержку нового типа refspec, называемого "отрицательными" refspec.
Они имеют префикс '
^
'и означает "exclude any ref matching this refspec
".
У них может быть только одна" сторона ", которая всегда относится к источнику.
- Во время выборки это относится к имени ссылки на пульте дистанционного управления.
- Во время пуша это относится к имени рефери на локальной стороне.
С помощью отрицательных ссылок пользователи могут выражать более сложные шаблоны. Например:
git fetch origin refs/heads/*:refs/remotes/origin/* ^refs/heads/dontwant
получит все ветки на
origin
вremotes/origin
, но исключит получение ветки с именемdontwant
.Refspecs сегодня являются коммутативными, что означает, что порядок явно не имеет значения.
Вместо того, чтобы устанавливать подразумеваемый порядок, отрицательные refspecs всегда будут применяться последними.
То есть, чтобы соответствовать, ссылка должна соответствовать по крайней мере одной положительной refspec и не соответствовать ни одной из отрицательных refspec.
Это похоже на то, как работают отрицательные пути.
Документация теперь включает:
А
<refspec>
может содержать*
в его<src>
для обозначения простого совпадения с образцом.
Такой refspec функционирует как glob, который соответствует любому ref с тем же префиксом. Шаблон<refspec>
должен иметь*
в обоих<src>
и<dst>
. Он сопоставит ссылки с местом назначения, заменив*
с содержанием, совпадающим с источником.Если refspec имеет префикс
^
, он будет интерпретирован как отрицательный refspec.
Вместо того, чтобы указывать, какие ссылки извлекать или какие локальные ссылки обновлять, такая спецификация ссылок будет указывать исключаемые ссылки.
Ссылка будет считаться совпадающей, если она соответствует хотя бы одной положительной ссылке и не соответствует ни одной отрицательной ссылке.Отрицательные refspec могут быть полезны для ограничения области refspec шаблона, чтобы он не включал определенные refs.
Отрицательные refspecs сами по себе могут быть refspecs образца. Однако они могут содержать только<src>
и не указывать<dst>
.
Полностью прописанные шестнадцатеричные имена объектов также не поддерживаются.
Видеть t5582-fetch-negative-refspec.sh
для большего количества примеров