Почему кто-то вызывает «git read-tree» после разреженной проверки

В соответствии с Проверка подкаталогов с помощью git sparse-checkout вызывает git read-tree -mu HEAD после настройки разреженной проверки в случае уже существующего репозитория, т.е.:

# Enable sparse-checkout:
git config core.sparsecheckout true

# Configure sparse-checkout 
echo some/dir/ >> .git/info/sparse-checkout
echo another/sub/tree >> .git/info/sparse-checkout

# Update your working tree:
git read-tree -mu HEAD
  • Не могли бы вы объяснить шаг read-tree подробнее?
  • Как это работает?
  • Что здесь происходит?
  • Почему используется read-tree, а не, скажем, checkout?
  • Почему используется -mu (почему это слияние и что сливается)?

-m

    Perform a merge, not just a read. The command will refuse to run if
    your index file has unmerged entries, indicating that you have not
    finished previous merge you started.

-u

    After a successful merge, update the files in the work tree with the
    result of the merge.

person Micha Wiedenmann    schedule 27.02.2015    source источник


Ответы (1)


В Git 2.25 (1 квартал 2020 г.) управление рабочим деревом с разреженной проверкой получило специальную команду sparse-checkout.
Она вводит режим конуса (о котором я подробно рассказываю в Git sparse checkout с исключением), что sparse-checkout должно ускориться.

Но это также косвенно описывает, почему используется git read-tree -mu HEAD (или, с новым режимом конуса, использовалось).

Подписано: Деррик Столи

unpack-trees: также разрешить get_progress() работать с другим индексом

Встроенная функция sparse-checkout использовала 'git read-tree -mu HEAD' для обновления битов skip-worktree в индексе и для обновления рабочего каталога.
Этот дополнительный процесс слишком сложен и может привести к сбою. Это также требует, чтобы мы записывали наши изменения в файл sparse-checkout, прежде чем пытаться обновить индекс.

Удалите этот дополнительный вызов процесса, создав прямой вызов unpack_trees() так же, как это делает 'git read-tree -mu HEAD'.
Кроме того, предоставьте список шаблонов в памяти, чтобы мы могли избежать чтения из файла sparse-checkout. Это позволяет нам протестировать предложенное изменение в файле перед записью в него.

Более ранняя версия этого патча содержала ошибку, когда команда 'set' не удалась из-за того, что разреженная проверка не оставляет записи об ошибке рабочего каталога. спецификация потерпит неудачу. Тест в t1091 теперь охватывает этот сценарий.

А в Git 2.27 (второй квартал 2020 г.) sparse-checkout умеет повторно применять себя:


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

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

clear_pattern_list(): очистить встроенные хэш-карты

Предоставьте один.

обновленная git sparse-checkout справочная страница теперь включает:

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

Такие команды, как merge или rebase, могут материализовать пути для выполнения своей работы (например, чтобы показать вам конфликт), а другие команды разреженной проверки могут не разрежить отдельный файл (например, из-за неустановленных изменений или конфликтов).

reapply:

В таких случаях имеет смысл запустить git sparse-checkout reapply позже, после очистки затронутых путей (например, разрешения конфликтов, отмены или фиксации изменений и т. д.).

Но с Git 2.27 он больше не будет повторно применяться/обновляться с помощью git read-tree:

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


Ранее единственным способом обновить биты SKIP_WORKTREE для различных путей был вызов git read-tree -mu HEAD или вызова того же кода, что и этот кодовый путь.

Однако это вызывало ряд проблем, если индекс или рабочий каталог не были чистыми.

А) На пути есть непроторенный путь

Сначала рассмотрим случай:

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

Давайте пометим этот случай для дальнейшего обсуждения:

Теперь рассмотрим обратный случай:

Flipping SKIP_WORKTREE -> !SKIP_WORKTREE (materializing files)

Если бы индекс и рабочее дерево были чистыми, это было бы нормально, но если бы были какие-то нечистые пути, мы бы столкнулись с проблемами.

Следует рассмотреть три различных случая:

  • D) Путь имеет поэтапные изменения (отличается от HEAD)

Если бы какой-либо путь попадал в случай B или C, то вся операция прервалась бы с ошибкой.

Flipping !SKIP_WORKTREE -> SKIP_WORKTREE (removing files)

С sparse-checkout вся операция была бы прервана и для случая D, но для его предшественника с прямым использованием git read-tree -mu HEAD все пути, попадающие в случай D, будут удалены из рабочей копии, а запись индекса для этого пути будет сброшена, чтобы соответствовать HEAD — что выглядит и ощущается пользователями как потеря данных (лишь немногие даже осознают, что могут спросить, можно ли их восстановить, и даже в этом случае требуется пройтись по разбросанным объектам, пытаясь сопоставить нужные).

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

  • A) Оставьте файл в рабочей копии в покое, очистите бит SKIP_WORKTREE и напечатайте предупреждение (таким образом, оставив путь в состоянии, при котором статус будет сообщать о файле как об изменении, что кажется логичным).
  • Б) НЕ отмечайте этот путь как SKIP_WORKTREE и оставьте его не объединенным.
  • C) НЕ отмечайте этот путь как SKIP_WORKTREE и выводите предупреждение о грязном пути.

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

Эта логика мешает им это сделать.

Иногда в ответ пользователь создает файлы и повторяет попытку, но безрезультатно с sparse-checkout или, к ужасу потери своих изменений, если он использует его предшественника git read-tree -mu HEAD.

Добавьте новую функцию update_sparsity(), которая не будет выдавать ошибку ни в одном из этих случаев, но будет вести себя следующим образом в особых случаях:

Я попробовал другое поведение для A (оставил бит SKIP_WORKTREE установленным), но нашел это очень удивительным и нелогичным (например, пользователь видит, что он присутствует вместе со всеми другими файлами в этом каталоге, пытается создать его, но git add игнорирует его, поскольку установлен бит SKIP_WORKTREE).

A & C кажутся мне оптимальным поведением.

B тоже может быть, хотя мне интересно, будет ли печатать предупреждение улучшением.

Кого-то может поначалу немного удивить D, но, учитывая, что он правильно работает с git commit и даже с git commit -a (git add игнорирует записи, помеченные SKIP_WORKTREE, и поэтому не удаляет их, а commit -a аналогично), мне это кажется логичным .

И все еще с Git 2.27 (второй квартал 2020 г.):

См. commit 6c34239 (14 мая 2020 г.) от Элайджа Ньюрен (newren).
(объединено Хунио C Хамано -- gitster -- в commit fde4622, 20 мая 2020 г.)

Принято: Джефф Хостетлер
Подписано: Элайджа Ньюрен

commit b0a5a12a60 (unpack-trees: разрешить check_updates() работать с другим индексом, 2020-03- 27, Git v2.27.0-rc0 -- слияние, указанное в пакет № 5) позволял check_updates() работать с другим индексом, но вызывал get_progress(), который был жестко закодирован для работы. o->result очень похоже на check_updates().

Обновите его, чтобы он также принимал параметр индекса, и пусть check_updates() передает этот параметр, чтобы оба работали с одним и тем же индексом.

B) Путь не объединен

Код стал более надежным с Git 2.29 (4 квартал 2020 г.):

См. коммит 55fe225, зафиксировать 1c89001, noreferralflowd2a77b6d> 9a53219 (17 августа 2020 г.) и commit f1de981, коммит c514c62, совершают 9101c8e, совершают 8dc3156 (14 августа 2020 г.) от Джефф Кинг (peff).
(Объединено Юнио С Хамано - - gitster -- в commit 0d9a8e3, 27 августа 2020 г.)

Подписано: Джефф Кинг
Подтверждено: Деррик Столи


Коммит 96cc8ab531 (sparse-checkout: используйте хэш-карты для шаблонов конусов, 21 ноября 2019 г., Git v2.25.0-rc0 -- merge) добавлено несколько вспомогательных хэш-карт в структуру pattern_list, но они просачиваются, когда вызывается clear_pattern_list().

sparse-checkout: обновить рабочий каталог в процессе

C) Путь имеет неустановленные изменения

sparse-checkout: укажите новую подкоманду повторного применения

unpack-trees: добавьте новую функцию update_sparsity()

person VonC    schedule 28.12.2019