假设我有一个名为 "Hammerstein" 的尚未发布的软件产品的巨大存储库。 ,由德国著名软件公司“Apfel”编写,我是该公司的员工。
有一天,“Apfel”分拆出 Hammerstein 部门并将其出售给更著名的公司“Oráculo”,该公司将“Hammerstein”重命名为 "Reineta"出于民族自豪感,决定将其开源。
协议(protocol)要求将存储库中所有对“Hammerstein”和“Apfel”的引用替换为“Oráculo”和“Reineta”。
所有文件名、所有提交消息、一切都必须替换。
所以,例如:
src/core/ApfelCore/main.cpp
必须成为src/core/OraculoCore/main.cpp
。“Add support for Apfel Groupware Server”
的提交消息必须变为“Add support for Oraculo Groupware Server”
字符串
ApfelServerInstance* local_apfel
、#define REINETA
和Url("http://apfel.de")
必须成为OraculoServerInstance* local_oraculo
、#define HAMMERSTEIN
等
这也适用于不再位于 HEAD
中的文件。
用最少的手动干预实现它的最简单和最轻松的方法是什么(以便它可以批量应用于潜在的大量存储库/ Assets )?
- BFG可以替换字符串,但它似乎只有一个
--delete-file
选项,而不是一个--rename-file
,即使那样它也不会将模式作为一个论点 - This approach似乎只适用于
HEAD
而不是整个历史;我没有运气将它与--tree-filter
一起使用
最佳答案
完全披露:我是 BFG Repo-Cleaner 的作者
正如您在问题中所说,BFG 支持使用 --replace-text
标志替换文件内容 - 但此标志不会扩展到文件 names 并提交消息。那么,要使 BFG 的 --replace-text
操作也扩展到这些代码库,需要对代码库进行哪些更改?
这归结为 Hook 一些新的 Cleaner[V]
实现,其中 V
是您要清理的东西的类型(提交消息、目录列表),而 Cleaner
只是负责生成一个新的、干净的V
来自旧的、脏的 V
。要执行实际的文本更改,您可以重复使用相同的 text-replacing function用于文件内容更改。
文件名
使用 Cleaner[Seq[Tree.Entry]]
- “树”是 Git 对文件夹的称呼(“文件树”) - 所以你只需更新 FileName
在每个 Tree.Entry
上。
提交消息
使用 Cleaner[CommitNode]
- 同样,您只是替换 message
字段中的文本 - 请参阅 CommitMessageObjectIdsUpdater一个非常接近的例子,说明你正在尝试做什么。当你在那里时,如果你愿意,你可以对作者和提交者的电子邮件地址做一些事情(例如清除 ...@apfel.com
,我猜)。
速度
正如@VonC 在他的回答中提到的,filter-branch
可以 进行这两种替换(文件名和提交消息),但是 --msg -filter
标志应该相当快地完成提交消息更新,我相信 filter-branch
对于在像您这样的大型代码库中重命名文件会相当非常慢 . BFG 正是针对此类操作进行了优化,将快 数百 倍。
BFG 在 https://www.bountysource.com/teams/bfg-repo-cleaner 接受捐赠 - 因此,如果您愿意支持此功能的开发,或者如果您只是发现 BFG 对解决您的问题很有用,那么您就可以有所作为。
关于git - 如何通过一个简单的步骤将存储库中 *Foo* 的 *所有* 实例(内容、文件名和提交消息)批量替换为 *Bar*?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32677970/