Я клонировал проект от GitHub с клоном мерзавца - зеркало. Это оставило меня с репозиторием с файлом упакованных судей, .pack и .idx файлом. В целях разработки я хочу посмотреть на свободные объекты, таким образом, я распаковал объекты с распаковывать-объектами мерзавца <<файл пакета>, который хорошо работал (я распаковал файл пакета в новый repo, если Вы задаетесь вопросом). Только вещь состоит в том, что refs/heads/все еще пуст, все судьи находятся все еще только в упакованных судьях, но мне нужны они в refs/heads/. Я не смог найти команду, которая извлечет или распакует те ссылки, и я не могу так или иначе полагать, что должен был бы сделать это вручную (или через каналы).
Таким образом, на самом деле у меня есть два вопроса:
Спасибо за любые подсказки и идеи.
Короткий ответ "нет" - нет "простого способа" распаковать рефссылки так, как вы просите.
Немного более длинный ответ: каждый рефссылка - это просто 41-байтовый текстовый файл (40-байтовый SHA1 в hex + новая строка) в определенном пути, поэтому "трудная" версия просто требует что-то вроде этого в вашем ~/.gitconfig
:
[alias]
unpack-refs = "!bash -c 'IFS=$''\\n''; for f in $(git show-ref --heads); do /bin/echo ''Writing '' $(echo $f | cut -c42-); echo $(echo $f | cut -c1-40) > \"${GIT_DIR:-.git}/$(echo $f | cut -c42-)\"; done'"
Потребовалось немного хитрости, чтобы понять, как заставить его работать правильно, но вот оно! Теперь у вас есть 'git unpack-refs', и он делает то, что вы ожидаете, и в качестве бонуса он даже работает с $GIT_DIR, если он установлен (иначе он предполагает, что вы находитесь в корне дерева git). Если вы еще не читали о псевдонимах git, https://git.wiki.kernel.org/index.php/Aliases является отличной ссылкой и даже включает пример расширения 'git alias', который вы можете использовать для расширения своих собственных псевдонимов.
Причина существования упакованных рефссылки - ускорение доступа в репозитории с миллионами рефссылки - проще просмотреть один файл с большим количеством строк, чем один раз обращаться к файловой системе для каждой рефссылки. Всё в git, что должно знать о рефссылках, проходит через код, который может читать как каталог refs, так и упакованный файл refs. Распаковка его привела бы к потере цели. Если вы хотите получить доступ к рефссылкам, используйте команды plumbing (например, show-ref, for-each-ref, update-ref...). Я не могу придумать ни одного вида доступа, который был бы быстрее и проще с помощью структуры каталогов, чем с помощью команд plumbing (особенно при наличии for-each-ref).
И да, упакованные объекты (как и упакованные refs) создаются для повышения производительности, но есть огромная разница. Упакованный файл refs - это просто куча независимых строк. Вы можете, по сути бесплатно, добавлять или удалять из него. Нет необходимости распаковывать его, чтобы изменить. Упакованные объекты, с другой стороны, дельта-сжаты, поэтому объекты внутри них зависят друг от друга. Они значительно снижают использование диска, и объекты могут быть прочитаны из них по разумной цене, но попытка изменить набор объектов в пакете обходится гораздо дороже, чем изменение свободных объектов, поэтому это периодически делается только git repack
(вызывается git gc
), хотя я не верю, что git repack
действительно распаковывает объекты - он просто считывает их из packfile, упаковывает с свободными и создаёт новый пакет.
Однако, когда пакет передается с удаленной стороны, он распаковывается на локальной стороне. Я вижу вызов метода распаковки в источнике git receive-pack
, а в руководстве pack-objects
говорится:
Команда git unpack-objects может прочитать упакованный архив и развернуть объекты, содержащиеся в пакете, в формат "один файл - один объект"; обычно это делается командами smart-pull, когда пакет создается на лету для эффективной передачи по сети их коллегами.