Почему git update-ref принимает ссылки, отличные от /refs?
в то время как команды, такие как "git log", с радостью примут разные выражения для одного и того же ref, например
refs/heads/master
heads/master
master
это неверно для "Git update-ref". Например
git update-ref master HEAD^
- это не то же самое как
git update-ref refs/heads/master HEAD^
первая команда создает новую ссылку .git / master (и, в свою очередь, вводит двусмысленность в отношении refs/heads/master). Только вторая команда действительно обновляет голову мастера. (.git / refs / heads / master)
Почему git update-ref принимает ссылки без префикса " refs/"? Разве не должно быть хотя бы предупреждения или опции командной строки для принудительного создания таких ссылок?
мне потребовалось довольно много времени, чтобы понять, почему
git update-ref master HEAD^
не работает, как ожидалось.
2 ответов
tl; dr
главная причина, почему git log
и git update-ref
вести себя по-другому, потому что git-log
это высокого уровня command-и поэтому разработан, чтобы быть удобным для пользователя-в то время как git-update-ref
- это низкий уровень команда предназначена для использования в скриптах.
керамогранит и сантехника
на языке Git команды высокого уровня называются фарфор в то время как низшие звенья называются сантехники.
фарфоровые команды предназначены для использования интерактивно людьми и поэтому подвергают знакомые концепции высокого уровня, такие как символические ссылки. С другой стороны, команды сантехники предназначены для использования программно - обычно в скриптах - и позволяют напрямую управлять внутренней файловой системой Git структуры.
git-update-ref
пока git-log
способен разрешить ссылки, git-update-ref
– это команда, сантехника – интерпретирует первый аргумент как ссылка или обычный имя файла в зависимости от того, как он указан.
С документация:
следует реальные символические ссылки, только если они начинаются с " refs/": в противном случае это просто попробуйте прочитать их и обновить их как обычный файл.
так вот почему если вы говорите git update-ref master <value>
он будет лечить master
как имя файла и создайте его в .git.
Git 2.18 (Q2 2018) улучшает надежность обновления git-ref, потому что"git update-ref A B
" должен гарантировать, что ref A
еще не существует, когда B
является нулевым OID, но эта проверка не была выполнена правильно для псевдо-ссылок вне refs / иерархии, например MERGE_HEAD
.
посмотреть совершить db0210d, совершить 65eb8fc, совершить c0bdd65 (10 мая 2018) by Мартин Огрен (`).
Помог: Рафаэль Ascensão .
(слитый Junio C Hamano -- gitster
-- на совершить 26597cb, 30 мая 2018)
refs: обрабатывать нулевой oid для псевдореф
согласно документации, возможно "указать 40' 0 ' или пустые строки
<oldvalue>
чтобы убедиться, что ref вы создаете не существует."
Но в коде для pseudorefs мы этого не реализуем, как показали добавленные неудачные тесты в предыдущий.
Если мы не читаем старого рефери, мы немедленно умираем. Но провал чтение на самом деле было бы хорошо, если бы нам дали нулевой oid.С нулевым oid, позвольте -- и даже требуйте -- ref-чтение потерпеть неудачу. Это реализует "
make sure that the ref ... does not exist
" часть документация и исправления обоих неудачных тестов из предыдущей фиксации.у нас есть
strbuf err
для сбора ошибок, давайте использовать его и сигнализируйте об ошибке звонящему вместо того, чтобы умирать.