如何使用git filter-repo同时考虑其文件路径和数据来修改Blob?

问题描述

例如在How to use git filter-repo as a library with the Python module interface?,我设法通过以下方式修改较旧提交的blob以进行重构:

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://stackoverflow.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,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()

这次,我确实设法在print(file_change.filename)获取了Blob路径,但没有获取Blob数据。

我有blob_id,但我不知道如何使用它。

我想我可以分两次通过,一次提交回调以创建从Blob ID到路径的映射,第二次使用Blob回调使用该信息,但感觉有点难看。

是否有更好的方法可以访问这两者,例如我错过了commit_callback个参数的某些字段?

问题跟踪器上的Ping:https://github.com/newren/git-filter-repo/issues/158

git filter-repo ac039ecc095d中进行了测试。

解决方法

过滤器回购项目负责人以利亚(Elijah)回答:https://github.com/newren/git-filter-repo/issues/158#issuecomment-702962073并解释说,没有“ hacks”是不可能的。

他向我指出了这个树内示例:https://github.com/newren/git-filter-repo/blob/7b3e714b94a6e5b9f478cb981c7f560ef3f36506/contrib/filter-repo-demos/lint-history#L152,它通过提交过滤器+调用git cat-file来完成。

潜在的问题是,可能已经在git fast-export流上更早地发送了Blob,并且稍后在添加相同Blob的第二次提交中仅由ID引用。而且,将所有内容保留在内存中通常会在大型存储库上浪费内存。