Вы можете рассмотреть возможность использования git filter-branch --index-filter
- в отличие от --tree-filter
(по умолчанию).Идея состоит в том, что в --index-filter
нет этапа извлечения (т. Е. Рабочее дерево не заполняется (перезаполняется) на каждой итерации).
Так что вы можете написать фильтр для git filter-branch --index-filter
, который быиспользуйте git ls-files
- примерно так:
Вызовите git ls-files --cached --stage
и выполните итерации по каждой записи.
Рассмотрите только те из них, которые имеют режим файла 100644
, - чтоесть обычные файлы.
Для каждой записи выполните что-то вроде
sha1=`git show ":0:$filename" \
| iconv -f iso8859-1 -t utf-8 \
| git hash-object -t blob -w --stdin`
git update-index --cacheinfo "10644,$sha1,$filename" --info-only
Промыть, повторить.
Альтернативный подход, который я понимаю, состоит в том, чтобы атаковать проблему под другим углом: формат потоков, генерируемых git fast-export
и потребляемых git fast-import
, представляет собой простой текст plain (просто перенаправьте вывод вашего экспортера в less
илидругой пейджер и убедитесь сами).
Вы можете написать фильтр, используя ваш любимый PL, который будет анализировать поток, перекодировать любые фрагменты data
.Поток организован таким образом, что хэши SHA-1 не используются, поэтому вы можете перекодировать по ходу дела.Единственная очевидная проблема, которую я понимаю, состоит в том, что чанки data
не несут информации о том, какой файл они будут представлять в результирующем коммите (если есть), поэтому, если у вас есть нетекстовые файлы в вашей истории, вам, возможно, придется прибегнуть котгадывать на основе содержимого каждого большого двоичного объекта данных или усложнять свой процессор, запоминая двоичные объекты, которые он видел, и решая, какие из них следует перекодировать после того, как он увидел запись commit
, которая присваивает имена файла (некоторым из) этих больших двоичных объектов.
¹ Документировано в git-fast-import(1)
- запуск git help fast-import
.