git - 在 macOS 上使用树过滤器和 sed 从 Git 提交中删除敏感数据
问题描述
我尝试阅读多篇关于sed
以及如何从已提交的文件中删除密钥的帖子。我正在尝试这个
git filter-branch --tree-filter \
"sed -i '' 's/my_sensitive_data/<your-api-key>/' ./app/src/main/java/com/demo/Test.kt"
我不断得到sed ./app/src/main/java/com/demo/Test.kt: No such file or directory
。但如果我接受同样的命令
sed -i '' 's/my_sensitive_data/<your-api-key>/' ./app/src/main/java/com/demo/Test.kt
从我运行git filter-branch
命令的目录中,该sed
命令会适当地替换它。
我正在运行 macOS catalina 并使用 ZSH。我在这里可能做错了什么?
解决方案
使用git filter-branch
,Git 在每次提交时运行过滤器。1 即树过滤器:
- 检查提交(在临时目录中);
- 运行指定的命令(在那个临时目录中);和
- 从该命令留下的任何内容构建替换提交。
filter-branch 命令对要复制的每个提交重复此操作。(这就是 filter-branch 所做的:它复制提交。原件继续存在。)
你的一些提交有文件;该sed
命令将对这些提交起作用。您的某些提交缺少该文件,并且sed
在这种情况下该命令失败。失败(git filter-branch
被视为过滤命令的非零退出状态)会导致git filter-branch
自身停止并且不执行您想要的过滤。
解决方案是避免sed
在文件不存在时完全运行此命令。有两种方法可以做到这一点(见脚注 1),但最简单的是修改你的命令以首先检查。代替:
sed -i '' 's/my_sensitive_data/<your-api-key>/' ./app/src/main/java/com/demo/Test.kt
你会使用:
if [ -f app/src/main/java/com/demo/Test.kt ]; then
sed -i '' 's/my_sensitive_data/<your-api-key>/' app/src/main/java/com/demo/Test.kt
fi
注意:如果你把它压缩成一行,它至少需要一个分号。我把它去掉了(也把它去掉了./
,因为它是多余的)以使这些线条更适合发布目的。
1从技术上讲,它仅在您告诉它的提交上运行过滤器,这可能比每次提交都要少。将访问的提交是那些通过正引用显式或隐式命名的提交,不包括那些通过负引用显式或隐式命名的提交。这句话中有相当多的行话,值得将其拆解一下:
肯定引用是前面没有否定的引用,也没有用于否定引用的各种特殊句法方法中的任何一种。这方面的简单示例包括
feature
(分支名称)、v2.1
(标记名称)和a1234567
(缩写的提交哈希)。否定引用是前面有否定的引用,或者用于否定的语法:
^feature
,^v2.1
,^a1234567
。对于否定语法的简单示例,请考虑master..feature
:这完全等同于写作feature ^master
。该短语显式或隐式地指的是 Git 正在遍历提交图这一事实。有关这意味着什么的正确教程,请参阅Think Like (a) Git。
命令行中提到的所有正面引用都会导致 Git 遍历提交图,标记要复制的提交。所有负面引用都会导致 Git 遍历图表,取消标记提交。如果您将过程视为“先标记,然后取消标记”,您会得到正确的结果:只有标记的提交会被复制和过滤。如果您将其视为“首先取消标记”,那么“标记之后”阶段必须尊重所有早期的“取消标记”。(Git 实际上以一种复杂的交错方式执行此操作,因此它总能得到正确的结果,但比简单的两遍算法更快。)
那些作为分支名称的正面引用会导致名称被记住。然后,Git 将所有标记的提交按适当的顺序排列——根据复制过程的需要进行拓扑排序——并开始复制。当它复制时,它会构建一个从旧哈希 ID 到新哈希 ID 的映射。在复制过程结束时,对于每个保存的分支名称,Git 强制名称指向新的哈希 ID 而不是旧的,过滤现在完成。
因此,如果有一个简单(或复杂!)的范围表达式让 Git仅枚举您需要复制和过滤的提交,您可以使用它,而不是在过滤器中进行测试。例如,假设敏感数据是专门在 commit 中引入的badf00d
,其父级是cafedad
:因此所有好的提交都可以到达cafedad
,所有坏的提交都在以 开头badf00d
并一直持续到master
.
之前 的一些提交cafedad
,可能还有cafedad
自己的提交,缺少文件Test.kt
,因此sed
它们会失败。在这种情况下:
git filter-branch <filter-specifiers> -- cafedad..master
可以解决问题,因为这将复制和过滤限制为仅(a)具有文件和(b)需要编辑的那些提交。
推荐阅读
- fb-hydra - 使用 SLURM 和 Horovod 运行 hydra 配置的项目
- amazon-web-services - AWS Dynamodb TTL Stream 是否会触发单独的过期事件和已删除事件?
- reactjs - 将应用程序与 FCM 集成时出现 MIME 类型错误
- eclipse - 如何确定在 Eclipse 中使用哪种颜色突出显示
- python - 如何解析在事件中心的存储帐户中捕获的 AVRO blob?
- reactjs - 从下拉列表中选择标签时的反应选择显示标签+值
- c++ - 我应该在堆栈上使用 Qprocess
- c# - C# 中实体组件系统的多态性
- php - PHP:无法将上传的文件从 tmp 移动到远程服务器上的指定文件夹?
- c# - C# 多个异步任务以及当它们相互使用完成时在哪里正确等待它们?