Как использовать git sparse-checkout в 2.27+ - PullRequest
7 голосов
/ 17 июня 2020

Я пытался воспроизвести несколько шагов руководства из:

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

Ответы [ 2 ]

4 голосов
/ 20 июня 2020

Кажется, я нашел для этого причину. Фиксация 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 изменилось: из-за автоматического оживления git пустого индекса в памяти (см. do_read_index() и обратите внимание, что must_exist является ложным), и из-за кода sparse-checkout update_working_directory() всегда записывать индекс после того, как это было сделано, мы получили новую ошибку. Это сделало так, что sparse-checkout переключит репозиторий с клона с «нерожденным» индексом (т.е. все еще нуждающимся в initial_checkout) на тот, у которого есть записанный индекс без записей. Таким образом, вместо того, чтобы все файлы, появляющиеся в git status, были известны git как особый артефакт того, что они еще не находятся в ветке, наша запись пустого индекса заставила его внезапно обратиться к git, как если бы он определенно был на ветке со ВСЕМИ файлами, поставленными на удаление! Последующая проверка или переключение должны были иметь дело с тем фактом, что он не был на initial_checkout, но имел кучу поэтапных удалений.

2 голосов
/ 20 июня 2020

Вот решение, которое будет заполнять только файлы в папке root:

$ git clone --filter=blob:none --sparse https://github.com/derrickstolee/sparse-checkout-example

Тогда последующие вызовы разреженной проверки работают как чудо.

Все еще не понимаю, почему учебник не работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...