Как сделать разреженную проверку подмодуля с помощью Git?

Есть много статей и ТАКих вопросов о sparse-checkout. К сожалению, конкретных примеров я не нашел. Я хотел бы получить следующий пример работы:

Создать подмодуль

cd ~
mkdir sub && cd $_
git init 
mkdir foo && touch $_/foo
mkdir bar && touch $_/bar
git add .
git commit -am "Initial commit"

Создать проект

cd ~
mkdir project && cd $_
git init
git submodule add ../sub sub
git config -f .gitmodules submodule.sub.shallow true
git config -f .gitmodules submodule.sub.sparsecheckout true
echo foo/* > .git/modules/sub/info/sparse-checkout
git commit -am "Initial commit"
git submodule update
cd sub
git checkout .

На данный момент я ожидаю, что папка sub будет содержать только foo/foo, а не bar. К сожалению, это не работает:

$ ls
bar/ foo/

Как я могу заставить его работать?


person nowox    schedule 15.08.2017    source источник


Ответы (2)


git submodule add сам проверяет подмодуль.

Что мне удалось:

git init
# I did not find a way to add submodule in 1 step without checking out
git clone --depth=1 --no-checkout ../sub sub
git submodule add ../sub sub
git submodule absorbgitdirs
# note there is no "submodule.sub.sparsecheckout" key
git -C sub config core.sparseCheckout true
# note quoted wildcards to avoid their expansion by shell
echo 'foo/*' >>.git/modules/sub/info/sparse-checkout
git submodule update --force --checkout sub
person max630    schedule 15.08.2017
comment
Вы обновили echo bar >>.git/modules/sub/info/sparse-checkout своим шаблоном? - person max630; 15.08.2017
comment
Спасибо, сработало отлично! Хотя я думаю, что в этом случае absorbgitdirs ничего не делает, потому что submodule add уже помещает каталог git подмодулей внутри в корень .git. хотя позвонить не помешает - person Dorian Roy; 07.11.2018

Начиная с Git 2.25 (1 квартал 2020 г.) вы должны использовать новую команду git sparse-checkout

А в Git 2.28 (3 квартал 2020 г.) задокументировано влияние настроек sparse checkout на подмодули.

См. commit e7d7c73 (10 июня 2020 г.) от Элайджа Ньюрен (newren).
(объединено Хунио С. Хамано -- gitster -- в commit 81be89e, 22 июня 2020 г.)

git-sparse-checkout: уточнение взаимодействия с подмодулями

Подписал: Элайджа Ньюрен
Проверил: Деррик Столи

На мгновение игнорируя функцию разреженной проверки, если у вас есть подмодуль и создаются локальные ветки внутри него с неотправленными изменениями и, возможно, добавляются некоторые неотслеживаемые файлы, тогда мы хотели бы избежать случайного удаления такого подмодуля.

Так, например, с git.git, если вы запустите

git checkout v2.13.0

тогда субмодуль sha1collisiondetection/ НЕ удаляется, даже если он не существовал как субмодуль до v2.14.0.

Точно так же, если вы предварительно проверили только версию 2.13.0 и запустили

git checkout v2.14.0

субмодуль sha1collisiondetection/ НЕ будет автоматически инициализирован, несмотря на то, что он является частью версии 2.14.0.

В обоих случаях git требует, чтобы подмодули инициализировались или деинициализировались отдельно.

Кроме того, у нас также есть специальная обработка подмодулей в других командах, таких как clean, которая требует двух флагов --force для удаления неотслеживаемых подмодулей, а некоторые команды имеют флаг --recurse-submodules.

sparse-checkout очень похож на checkout, о чем свидетельствует похожее имя — он добавляет и удаляет файлы из рабочей копии.

Однако по тем же причинам предотвращения потери данных мы не хотим удалять подмодуль из рабочей копии с помощью checkout, мы не хотим делать это и с sparse-checkout.

Таким образом, подмодули должны быть отдельно инициализированы или деинициализированы; изменение правил разреженной проверки не должно автоматически вызывать удаление или оживление подмодулей.

Я считаю, что предыдущая формулировка в git sparse-checkout о подмодулях касалась только этой конкретной проблемы.

К сожалению, предыдущую формулировку можно интерпретировать как подразумевающую, что подмодули следует считать активными независимо от шаблонов разреженности.

Обновите формулировку, чтобы избежать подобных последствий.

Может оказаться полезным рассмотреть два примера ситуаций, когда различия в формулировках становятся важными:

В будущем мы хотим, чтобы пользователи могли запускать такие команды, как

git clone --sparse=moduleA --recurse-submodules $REPO_URL

а также автоматическая настройка путей разреженности и автоматическая инициализация подмодулей внутри путей разреженности.

Мы не хотим, чтобы все подмодули в любом пути автоматически инициализировались этой командой.

Точно так же мы хотим иметь возможность делать такие вещи, как

git -c sparse.restrictCmds grep --recurse-submodules $REV $PATTERN

и найдите $REV для $PATTERN в записанных шаблонах разреженности.

Мы хотим, чтобы он выполнял рекурсию по подмодулям внутри этих шаблонов разреженности, но не хотим рекурсивно обращаться к каталогам, которые не соответствуют шаблонам разреженности, в поисках возможного подмодуля.

Итак, документация включает:

Если ваш репозиторий содержит один или несколько подмодулей, то подмодули заполняются на основе взаимодействия с командой git submodule.
В частности, git submodule init -- <path> гарантирует присутствие подмодуля в <path>, а git submodule deinit [-f] -- <path> удаляет файлы для подмодуля в <path> (включая любые неотслеживаемые файлы, незафиксированные изменения и неотправленную историю).
Подобно тому, как sparse-checkout удаляет файлы из рабочего дерева, но оставляет записи в индексе, деинициализированные подмодули удаляются из рабочего каталога, но по-прежнему имеют запись в индекс.

Поскольку в подмодулях могут быть неотправленные изменения или неотслеживаемые файлы, их удаление может привести к потере данных.
Таким образом, изменение разреженных правил включения/исключения не приведет к удалению уже проверенного подмодуля из рабочей копии.
Другими словами, точно так же, как checkout не приведет к автоматическому удалению или инициализации подмодулей даже при переключении между ветвями, которые удаляют или добавляют подмодули, использование sparse-checkout для уменьшения или расширения области интересующих файлов не приведет к автоматической деинициализации или инициализации подмодулей. .

Кроме того, приведенные выше факты означают, что существует несколько причин, по которым отслеживаемые файлы могут отсутствовать в рабочей копии: применение шаблона разреженности из sparse-checkout и состояние инициализации подмодуля.
Таким образом, такие команды, как git grep, работают с отслеживаемыми файлами. в рабочей копии может возвращать результаты, ограниченные одним или обоими из этих ограничений.


С Git 2.31 (1 квартал 2021 г.) git grep< sup>(man) был изменен, чтобы ограничиться редкими кассовые пути.

Поскольку вам может понадобиться git grep в подмодулях с разреженной проверкой, это важно.

См. commit 42d906b (09 февраля 2021 г.) от Матеус Таварес (matheustavares).
(объединено Хунио C Хамано -- gitster -- в commit 628c13c, 25 февраля 2021 г.)

grep: учитывать sparse-checkout при поиске в рабочем дереве.

Предложено: Элайджа Ньюрен
Подписано: Матеус Таварес
Проверено: Элайджа Ньюрен

В разреженном проверенном репозитории git grep(man) (без --cached) завершает поиск в кеше, когда запись соответствует спецификации пути поиска и имеет установленный бит SKIP_WORKTREE.

Это сбивает с толку как потому, что разреженные пути не должны находиться в рабочем поиске дерева (поскольку они не извлекаются), так и потому, что выходные данные смешивают результаты рабочего дерева и кэша, не различая их.
(Обратите внимание, что grep также прибегает к кешу при поиске в рабочем дереве, включающем --assume-unchanged путей.
Но весь смысл в этом случае состоит в том, чтобы предположить, что содержимое записи индекса и файла совпадают.
Это не относится к случай разреженных путей, когда файл даже не ожидается.)

Исправьте это, научив grep учитывать правила разреженной проверки для рабочего поиска по дереву.
Если пользователь хочет найти пути вне текущего определения разреженной проверки, он может либо обновить правила разреженности, чтобы материализовать файлы, либо использовать --cached для поиска всех больших двоичных объектов, зарегистрированных в индексе.

person VonC    schedule 28.06.2020