Как использовать git sparse-checkout в версии 2.27+
Я пытался воспроизвести несколько шагов из руководства:
https://github.blog/2020-01-17-bring-your-monorepo-down-to-size-with-sparse-checkout
Это было сделано для git 2.25, но теперь в 2.27 ничего не происходит при запуске:
$ git sparse-checkout set client/android
Я не могу найти способ заставить его работать.
Вот MWE:
$ git clone --no-checkout https://github.com/derrickstolee/sparse-checkout-example
Cloning into 'sparse-checkout-example'...
$ cd sparse-checkout-example/
$ git sparse-checkout init --cone
Используя git 2.25, я получаю непустой каталог:
$ ls -a
. .. bootstrap.sh LICENSE.md README.md .git
Используя git 2.27, я получаю пустой каталог:
$ ls -a
. .. .git
4 ответа
Думаю, я нашел для этого причину. Зафиксировать f56f31af0301
в Git изменили реализацию sparse-checkout
так что, когда у вас есть неинициализированное рабочее дерево (как и сразу после запуска git clone --no-checkout
), Бег git sparse-checkout init
не будет извлекать файлы из вашего рабочего дерева. В предыдущих версиях команда фактически извлекала файлы, что могло иметь неожиданные последствия, учитывая, что в этот момент у вас не было активной ветки.
Соответствующий коммит, f56f31af0301
был включен в Git 2.27, но не в 2.25. Это объясняет, почему поведение, которое вы видите, не соответствует поведению, показанному на веб-странице, за которой вы пытаетесь следовать. По сути, поведение на веб-странице было ошибкой, которую в то время никто не осознавал, но в Git 2.27 она была исправлена.
Я думаю, это очень хорошо объясняется в сообщении для фиксации b5bfc08a972d
:
Итак... это подводит нас к особому случаю: клон git, выполняемый с
--no-checkout
. Согласно значению флага,--no-checkout
не проверяет какую-либо ветку, подразумевая, что вы не в одной из них и вам нужно переключиться на одну после клона. В практическом планеHEAD
все еще установлен (так что в некотором смысле вы частично находитесь на ветке), но
- индекс "нерожденный" (не существует)
- в рабочем дереве нет файлов (кроме
.git/
)- в следующий раз
git switch
(илиgit checkout
) запускается unpack_trees сinitial_checkout
флаг установлен в значение true.Это не так, пока вы не запустите, например
git switch <somebranch>
что индекс будет записан, а файлы в рабочем дереве заполнены.С этим особенным
--no-checkout
случай, традиционныйread-tree -mu HEAD
поведение было бы эквивалентно действию какcheckout
- перейти в ветку по умолчанию (HEAD
), выпишите индекс, соответствующийHEAD
, и обновите рабочее дерево, чтобы оно соответствовало. Этот особый случай ускользнул от проверки на избежание внесения изменений в оригинале.sparse-checkout
команда и таким образом продолжил там.После
update_sparsity()
был введен и использован (см. коммитf56f31a
("sparse-checkout: use new update_sparsity() function
", 2020-03-27)) поведение для--no-checkout
case изменен: из-за автоматического оживления пустого индекса в памяти git (см.do_read_index()
и обратите внимание, чтоmust_exist
ложно), и из-заsparse-checkout
сupdate_working_directory()
код, чтобы всегда записывать индекс после того, как это было сделано, мы получили новую ошибку. Это сделало так, чтоsparse-checkout
переключит репозиторий с клона с "нерожденным" индексом (т.е. все еще нуждается вinitial_checkout
) на тот, у которого был записанный указатель без записей. Таким образом, вместо того, чтобы все файлы были удалены вgit status
Поскольку git известен как особый артефакт того, что он еще не находится в ветке, наша запись пустого индекса заставила его внезапно выглядеть как git, как если бы он определенно находился в ветке со ВСЕМИ файлами, подготовленными для удаления! Последующая проверка или переключение должны были бороться с тем фактом, что он не былinitial_checkout
но было несколько поэтапных удалений.
Вот решение, которое будет заполнять только файлы в корневой папке:
$ git clone --filter=blob:none --sparse https://github.com/derrickstolee/sparse-checkout-example
Тогда последующие звонки с редкими проверками работают как шарм.
До сих пор не понимаю, почему учебник не работает.
Я уже упоминал ранее в разделе « Почему исключенные файлы продолжают появляться в моем git sparse checkout? », Что любой файл skip-worktree не должен больше изменяться или даже просматриваться во время разреженной проверки с Git 2.27+.
Но с новым
sparceIndex
вариант с Git 2.32 (2 квартал 2021 г.), который снова меняется:
В Git 2.32 (второй квартал 2021 г.) он строится поверх инфраструктуры разреженного индекса, чтобы отмечать операции, которые не готовы пометить разреженным индексом, заставляя их возвращаться к полностью заполненному индексу, с которым они всегда работали.
См совершают 4589bca , совершают 71f82d0 , совершают 5f11669 (12 апреля 2021), совершают f5fed74 , совершают dc26b23 , совершают 0c18c05 , совершают 465a04a , совершают f7ef64b , совершают 3450a30 , совершают d425f65 , совершают 2508df0 , совершают a029120 , совершают e43e2a1 , совершают 299e2c4 , совершают 42f44e8 , фиксация 46eb6e3 , фиксация 2227ea1 , фиксация 48b3c7d , фиксация cb8388d , фиксация 0f6d3ba, Совершают 1b850d3 , совершают 54beed2 , совершают 118a2e8 , совершают 95e0321 , совершают 847a9e5 , совершают 839a663 (01 апр 2021), а также совершать c9e40ae , совершают 9ad2d5e , совершают 2de37c5 , совершают dcc5fd5 , , совершают 58300f4 , совершают 0938e6f , совершают 13e1331 , совершают f442313 , фиксация 6e77352 , фиксация cd42415 , фиксация 836e25c , фиксация 6863df3 , фиксация 2782db3, фиксация e2df6c3 , фиксация ecfc47c , фиксация 4300f84 , фиксация 3964fc2 , фиксация 4b3f765 , фиксация 0b5fcb0 , (30 марта 2021 г.) Деррик Столи (
derrickstolee
) .
(Слияние Junio C Hamano -
gitster
- в коммите 8e97852 , 30 апр 2021 г.)
фиксация 0ad6090
sparse-index
: дизайн документа и обновление форматаПодписано: Деррик Столи
С этого начинается долгая работа по обновлению формата индекса, чтобы разрешить разреженные записи каталога.
Это должно привести к значительному улучшению команд Git, когда HEAD содержит миллионы файлов, но пользователь выбрал гораздо меньше файлов для сохранения в их определении.В настоящее время формат индекса обновляется только при наличии, а не при увеличении номера версии формата файла.
Это временно, и индекс v5 является частью плана будущей работы в этой области.В проектной документации подробно описаны многие причины для начала этой работы, а также план ее безопасного завершения.
technical/index-format
теперь включает в свою справочную страницу :
Запись индекса обычно представляет собой файл. Однако, если разреженная проверка включена в режиме конуса (включена) и
extensions.sparseIndex
расширение включено, то индекс может содержать записи для каталогов вне определения sparse-checkout. Эти записи имеют режим040000
, включите бит, и путь заканчивается разделителем каталогов.
technical/sparse-index
теперь включает в свою справочную страницу :
Проектный документ Git Sparse-Index
Функция разреженной проверки позволяет пользователям сосредоточить рабочий каталог на подмножестве файлов в HEAD. Шаблоны режима конуса, включенные
core.sparseCheckoutCone
, позволяют очень быстро сопоставить с образцом, чтобы определить, какие файлы в HEAD принадлежат конусу разреженной проверки.Три важных измерения масштаба для рабочего каталога Git:
: Сколько файлов присутствует?
Заполнено: сколько файлов находится в конусе разреженной проверки.
Изменено: сколько файлов пользователь изменил в рабочем каталоге?
Мы будем использовать нотацию большого O -
O(X)
- чтобы обозначить, насколько дороги определенные операции с точки зрения этих размеров.Эти размеры упорядочены по их величине: пользователи (обычно) изменяют меньше файлов, чем заполнено, и мы можем заполнить файлы только в.
Проблемы возникают, если наблюдается крайний дисбаланс в этих размерах. Например, если содержит миллионы путей, но заполненный набор содержит только десятки тысяч, тогда команды, такие как и могут преобладать над операциями, которые требуют операций O() вместо O(заполнено). В первую очередь затраты заключаются в синтаксическом анализе и перезаписи индекса, который в основном заполняется файлами, помеченными битом.
Sparse-index намеревается принимать эти команды, которые читают и изменяют индекс с O() на O(заполнено) .
Для этого нам нужно существенно изменить формат индекса: добавить "
sparse directory
"записи.С помощью шаблонов режима конуса можно определить, когда весь каталог будет иметь свое содержимое за пределами определения разреженной проверки. Вместо того, чтобы перечислять все файлы, которые он содержит, как отдельные записи, разреженный индекс содержит запись с именем каталога, ссылающуюся на идентификатор объекта дерева в
HEAD
и отмеченSKIP_WORKTREE
немного. Если нам нужно узнать подробности о путях в этом каталоге, мы можем проанализировать деревья, чтобы найти этот список.
Итак, у вас есть новая возможность:
совершают 122ba1f
sparse-checkout
: переключить разреженный индекс со встроенногоПодписано: Деррик Столи
Расширение разреженного индекса используется для обозначения того, что запись индекса должна выполняться в разреженном режиме.
Это было обновлено только с использованиемGIT_TEST_SPARSE_INDEX=1
.Добавьте параметр '- [no-] sparse-index' в ' '( man ), который указывает, следует ли использовать разреженный индекс.
Он также обновляет индекс, чтобы в любом случае использовать правильный формат.
Добавьте в документацию предупреждение о том, что использование расширения репозитория может снизить совместимость со сторонними инструментами.
'git sparse-checkout init
уже устанавливаетextension.worktreeConfig
, что выводит пользователей с редкими заказами вне сферы действия большинства сторонних инструментов.
git sparse-checkout
теперь включает в свою справочную страницу :
Использовать
--[no-]sparse-index
опция для переключения использования формата разреженного индекса.Это уменьшает размер индекса, чтобы он лучше соответствовал вашему определению разреженной проверки.
Это может иметь значительные преимущества в производительности для таких команд, как
git status
или жеgit add
. Эта функция все еще экспериментальная. Некоторые команды могут работать медленнее с разреженным индексом, пока они не будут должным образом интегрированы с функцией.ПРЕДУПРЕЖДЕНИЕ. Использование разреженного индекса требует изменения индекса таким образом, чтобы его не полностью понимали внешние инструменты. Если у вас проблемы с совместимостью, запустите
git sparse-checkout init --no-sparse-index
чтобы переписать индекс, чтобы он не был разреженным.Более старые версии Git не распознают расширение индекса разреженных записей каталога и могут не взаимодействовать с вашим репозиторием, пока оно не будет отключено.
В Git 2.35 (1 квартал 2022 г.) подкоманды "" и "" в "git sparse-checkout
" ( man ) были унифицированы для лучшего взаимодействия с пользователем и производительности.
См. коммит dfac9b6 (23 декабря 2021 г.) и коммит d359541 , коммит d30e2bb , коммит ba2f3f5 , коммит 4e25673 , , коммит be61fd1 , коммит f85751a , коммит 45c5e47 , коммит 0b624e0 , коммит 1530ff3 (214) от Elihren 2jaren (
214 Dec 2jaren)newren
) .
(Объединено Junio C Hamano --
gitster
-- в коммите 2dc94da , 3 января 2022 г.)
коммит f2e3a21
sparse-checkout
: включить для инициализации режима разреженной проверкиРецензировал: Деррик Столи
Рецензировал: Виктория Дай
Подписал: Элайджа Ньюрен
Предложенный ранее рабочий процесс: git sparse-checkout init...git sparse-checkout set...
Столкнулся с тремя проблемами:
- Он удалит почти все файлы на первом этапе, а затем восстановит их на втором.
Это была плохая производительность и вынужденные ненужные перестроения.- Двухэтапный процесс привел к появлению двух индикаторов выполнения, что было неоптимально с точки зрения пользовательского интерфейса для оболочек, которые вызывали обе эти команды, но предоставляли своим конечным пользователям только одну команду.
- В конусном режиме первым шагом будет удаление почти всех игнорируемых файлов повсюду, потому что все считалось находящимся за пределами указанных путей разреженности.
(Пользователю не разрешалось указывать какие-либо пути разреженности на этом шаге.)Избегайте этих проблем, обучая
set
понять дополнительные параметры, которыеinit
принимает и выполняет любую необходимую инициализацию, если она еще не находится в разреженной проверке.