我试着阅读了多篇关于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命令对要复制的每个提交重复此操作。(过滤分支就是这样做的:它复制提交。原始文件仍然存在。)
您的一些提交具有该文件;CCD_ 7命令将对这些提交起作用。您的一些提交缺少文件,在这种情况下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而不是旧的哈希ID,过滤现在就完成了。
因此,如果有一个简单(或复杂!)的范围表达式,让Git只枚举需要复制和筛选的提交,你可以使用它,而不是在过滤器中进行测试。例如,假设敏感数据是专门在提交 坏的一些在badf00d
中引入的,其父级是cafedad
:因此,所有好的提交都可以从cafedad
访问,而所有cafedad
之前提交,可能还有cafedad
本身,缺少Test.kt
文件,因此sed
将在这些文件上失败。在这种情况下:
git filter-branch <filter-specifiers> -- cafedad..master
这将起到关键作用,因为这将复制和筛选限制为只有(a)具有文件和(b)需要编辑的提交。