Как изменить BLOB-объект с учетом пути к файлу и данных с помощью git filter-repo?

Например, в разделе Как использовать git filter-repo в качестве библиотеки с интерфейсом модуля Python? Мне удалось изменить капли старых коммитов для целей рефакторинга примерно такими:

def blob_callback(blob, callback_metadata):
    blob.data = blob.data.replace(b'd1', b'asdf')

git_filter_repo.RepoFilter(
   args,
   blob_callback=blob_callback
).run()

Но мне не удалось найти путь к BLOB-объекту, который был бы полезной информацией, особенно для определения типа файла по расширению файла и соответствующей адаптации изменений данных.

Если это невозможно с blob_callback, Я бы ожидал, что определенно commit_callback должен разрешить это, поэтому я пробовал такие вещи, как:

#!/usr/bin/env python

# https://stackru.com/questions/64160917/how-to-use-git-filter-repo-as-a-library-with-the-python-module-interface/64160918#64160918

import git_filter_repo

def blob_callback(blob, callback_metadata):
    blob.data = blob.data.replace(b'd1', b'asdf')

def commit_callback(commit, callback_metadata):
    for file_change in commit.file_changes:
        print(commit)
        print(file_change)
        print(file_change.filename)
        print(file_change.blob_id)
        print(callback_metadata)
        print()

# Args deduced from:
# print(git_filter_repo.FilteringOptions.parse_args(['--refs', 'HEAD', '--force'], error_on_empty=False))
args = git_filter_repo.FilteringOptions.default_options()
args.force = True
args.partial = True
args.refs = ['HEAD']
args.repack=False
args.replace_refs='update-no-add'

git_filter_repo.RepoFilter(
   args,
   # blob_callback=blob_callback
   commit_callback=commit_callback
).run()

На этот раз мне удалось получить путь к blob в print(file_change.filename), но не данные blob.

У меня есть это blob_id, но я не знаю, как им пользоваться.

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

Есть ли лучший способ получить доступ к обоим, например к некоторым полям commit_callback аргументы, которые я упустил?

Пинг в системе отслеживания проблем: https://github.com/newren/git-filter-repo/issues/158

Проверено в git filter-repo ac039ecc095d.

1 ответ

Элайджа, руководитель проекта репозитория фильтров, ответил: https://github.com/newren/git-filter-repo/issues/158#issuecomment-702962073 и объяснил, что это невозможно без "хаков".

Он указал мне на этот пример в дереве: https://github.com/newren/git-filter-repo/blob/7b3e714b94a6e5b9f478cb981c7f560ef3f36506/contrib/filter-repo-demos/lint-history#L152, который делает это с помощью фильтра фиксации + звонок git cat-file.

Основная проблема заключается в том, что капля могла быть отправлена ​​на git fast-exportstream намного раньше, и на него ссылается только идентификатор позже во второй фиксации, которая добавляет идентичный blob. А хранение всего в памяти в целом приведет к потере памяти при больших репозиториях.

Другие вопросы по тегам