Почему не существует A Git Клон Специфический параметр комманды?

В свете недавнего вопроса о SO и аналогичного сценария на работе, мне интересно, почему нет опции в git clone, чтобы указатель HEAD вновь созданного ветки указывал на указанное коммит? В заявляемом вопросе OP пытается предоставить инструкции по конкретному коммиту, который должны использовать его пользователи, в то время как в моем случае на работе мы пытаемся клонировать конкретный коммит, который соответствует интересующему нас подмодулю.

Обратите внимание, что этот вопрос не о Как клонировать в конкретную версию, используя reset; но о том, почему его нет?

Ответ 1

Два ответа до сих пор (в то время, когда я писал это, теперь их больше) правильны в том, что они говорят, но на самом деле не отвечают на вопрос "почему" . Конечно, вопрос "почему" действительно трудно ответить, за исключением авторов различных бит Git (и даже тогда, что, если два частых вкладчика Git дали два разных ответа?).

Тем не менее, учитывая Git "философию", как правило, различные протоколы передачи работают, именовая ссылку. Если они предоставляют SHA-1, это SHA-1 этой ссылки. Для тех, у кого еще нет прямого (например, командной строки) доступа к репозиторию, ни один 1 встроенных команд не позволяет ссылаться на фиксации по идентификатору. Самое близкое, что я могу найти по этой причине, - и это действительно хорошая причина. 2 - этот бит в git upload-archive:

Безопасность

Чтобы защитить конфиденциальность объектов, которые были удалены из история, но может еще не быть обрезанной, git -upload-archive избегает обслуживающие архивы для коммитов и деревьев, которые недоступны из репозиторий refs. Однако, поскольку вычисление достижимости объекта вычислительно дорого, git -upload-archive реализует более строгий, но более простой для проверки набор правил...

Однако он продолжает:

Если параметр конфигурации uploadArchive.allowUnreachable равен true, эти правила игнорируются, а клиенты могут использовать произвольные выражения sha1. Эта полезно, если вы не заботитесь о конфиденциальности недоступных объектов, или если ваша база данных объектов уже общедоступна для доступа через не смарт-клиента.

что особенно интересно, поскольку git clone получает все доступные объекты в первую очередь, после чего ваш локальный клон может тривиально проверить фиксацию с помощью идентификатора SHA-1 (и создать имя локальной ветки, указывающее на этот идентификатор, если это необходимо, или просто оставите свой клон в режиме "отсоединенный HEAD" ).

Учитывая эти два перекрестных тока, я думаю, что настоящий ответ на вопрос "почему" на данный момент "никто не заботится о том, чтобы его добавить".:-) Аргумент конфиденциальности действителен, но нет причин, чтобы git clone не смог проверить фиксацию по идентификатору после клонирования, так же, как может быть сказано, чтобы проверить какую-либо ветвь, отличную от master 3 с git clone -b .... Единственным недостатком разрешения -b sha1 является то, что Git не может проверять фронт (до начала процесса клонирования), будет ли получен sha1. Он может проверять имена ссылок, так как они передаются (вместе с подсказками их ветвей или другими значениями SHA-1) спереди, поэтому git clone -b nonexistentbranch ssh://... быстро заканчивается и не создает копию:

fatal: Remote branch nonexistentbranch not found in upstream origin
fatal: The remote end hung up unexpectedly

Если -b разрешил идентификатор, вы получили бы весь клон, тогда он должен был бы сказать вам: "О, черт возьми, извините, не могу проверить этот идентификатор, я оставлю вас на хозяине" или что-то еще. (Что более или менее то, что происходит сейчас с перегруженным подмодулем.)


1 Пока git upload-archive теперь применяет это правило "конфиденциальности", это не всегда так (оно было введено в версии 1.7.8.1); и многие (большинство?) git -web-серверов, в том числе и распределенные с самим Git, позволяют просматривать по произвольному идентификатору. Вероятно, поэтому allowUnreachable был добавлен в upload-archive через несколько лет после добавления кода "только по имени ref" (но обратите внимание, что релизы Git после 1.7.8 и до 2.0.0 не имеют возможности ослабить правила). Следовательно, хотя идея "безопасности" действительно, существовал период (до 1.7.8.1), когда он не был применен.

2 Существует множество способов "утечки" якобы частных данных из репозитория Git. Новый файл, Documentation/transfer-data-leaks, должен появиться в Git 2.11.1, а Git 2.11.0 добавил некоторые внутренние (см. commit 722ff7f87 среди других), чтобы немедленно удалить объекты, нажатые, но не принятые. Такие объекты в конечном итоге собираются с мусором, но это оставляет их выставленными в течение продолжительности.

3 Фактически, по умолчанию git clone делает локальную проверку ветки, которая, по его мнению, идет с удаленной ссылкой HEAD. Обычно это master в любом случае.

Ответ 2

Клонирование репо - это другая операция, кроме проверки. Вы не "клонируете конкретную фиксацию". Для удобства вы можете клонировать, а затем проверять конкретную ранее существовавшую ветвь одновременно, так как это то, чего хотят большинство людей. Если это не соответствует вашим потребностям (никакой ветки для конкретной SHA, которую вы хотите), просто используйте или псевдоним какой-либо формы

git clone -n <some repo> && cd <some repo> && git checkout SHA

Ответ 3

Как говорят другие ответы, это обычно не большая проблема, но они не говорят, почему вы не можете клонировать конкретную фиксацию. Ответ - безопасность.

Если вы случайно нажимаете конфиденциальную информацию, а затем принудительно нажимаете фиксированную историю, фиксации с конфиденциальной информацией все равно будут храниться на сервере, пока сервер Git сборщик мусора не обнаружит, что он больше не нужен. Если хэш известен (например, он может быть доступен в журналах), злоумышленник может запросить конкретный коммит, который не должен был быть нажат, даже если бы вы смогли убедиться, что когда вы принудительно надавили фиксированную историю, никто все еще принесли эти коммиты.

Убедившись, что вы можете клонировать только от refs, убедитесь, что клиентам будут отправляться только "достижимые" коммиты.

Ответ 4

Если ваша конкретная фиксация ссылается на ветку, вы можете сделать:

git clone -b yourBranch /url/of/the/repo

Клонированное репо будет находиться непосредственно в фиксации, на которую ссылается эта ветка.