我最近开始为FTP编写一个小的Python脚本。首先,我有一个在脚本中硬连线的FTP站点的服务器,登录名和密码详细信息,但这并不重要,因为我只是在本地工作。
然后我有了将项目放在github上的天才想法。我很快就意识到了自己的错误,并用一个涉及.netrc
的解决方案取代了硬连线的细节。我现在已经从github中删除了该项目,因为任何人都可以查看历史记录,并以纯文本格式查看登录详细信息。
问题是,有没有办法通过git历史记录并删除整个用户名和密码,但是否则保留历史记录?或者我是否需要开始一个没有历史记录的新回购?
答案 0 :(得分:23)
首先,您应该更改FTP站点上的密码。密码已公开;你不能保证没有人克隆了回购,或者它不是在某个地方的备份中的纯文本,或类似的东西。如果密码完全有价值,我认为它现在已经妥协了。
现在,关于如何编辑历史记录的问题。 git filter-branch
命令用于此目的;它将遍历存储库历史记录中的每个提交,应用命令进行修改,然后创建新提交。
特别需要git filter-branch --tree-filter
。这允许您编辑每个提交的树的内容(实际文件和目录)。它将在包含整个树的目录中运行命令,您的命令可以编辑文件,添加新文件,删除文件,移动它们等等。然后,Git将创建一个新的提交对象,其中包含与前一个相同的所有元数据(提交消息,日期等),但是您的命令修改了树,将新文件视为添加,将文件丢失为删除,等等(所以,你的命令不需要git add
或git rm
,它只需要修改树。)
出于您的目的,以下内容应该可以使用,具有适当的正则表达式和文件名,具体取决于您的具体情况:
git filter-branch --tree-filter "sed -i -e 's/SekrtPassWrd/REDACTED/' myscript.py" -- --all
请记住对存储库的副本执行此操作,因此如果出现问题,您仍然可以使用原始文件并重新开始。 filter-branch
还会保存对原始分支的引用,如original/refs/heads/master
等,因此即使您忘记执行此操作也应该能够恢复;在对我的源代码历史进行全局修改时,我想确保在出现问题时我有多个回退。
更详细地解释其工作原理:
sed -i -e 's/SekrtPassWrd/REDACTED/' myscript.py
这会将SekrtPassWrd
文件中的myscript.py
替换为REDACTED
; -i
的{{1}}选项告诉它编辑文件,没有备份文件(因为该备份将被Git选为新文件)。
如果你需要做一些比单一替换更复杂的事情,你可以编写一个脚本,然后只为你的命令调用它;只需确保使用绝对路径名调用它,因为sed
从临时目录中调用您的命令。
git filter-branch
这告诉git filter-branch --tree-filter <command> -- --all
如上所述,在存储库中的每个分支上运行树过滤器。 git
部分告诉Git将其应用于所有分支;没有它,它只会编辑当前分支的历史记录,保持所有其他分支不变(这可能不是你想要的)。
有关处理已推送到GitHub的信息副本的更多信息,请参阅Removing Sensitive Data上的GitHub文档(作为originally pointed out by MBO)。请注意,他们重申了我更改密码的建议,并提供了一些处理GitHub可能仍然拥有的缓存副本的提示。
答案 1 :(得分:5)
也许更容易在FTP站点上更改密码?除非你对代码感到尴尬......
答案 2 :(得分:3)
我相信您应该能够使用filter-branch
命令更改所有提交。有关详细信息,请参阅the section in the ProGit book。
但是,正如@MBO的链接说明
强制推送不会删除远程仓库上的提交,它只是引入新的并将分支指针移动到指向它们
因此,您需要从GitHub中完全删除存储库以删除这些提交(即使它们不在您的提交历史记录中,它们仍然在存储库中浮动)
答案 3 :(得分:1)
要通过添加到chosen answer,我的用例中的代码存在问题。我只是在早期的提交中错过了有问题的文件。我确信我不是这种情况下唯一的人,所以我做了一个简单的修复/黑客
let transition = CATransition()
transition.duration = 1.0
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromLeft
view.window!.layer.add(transition, forKey: kCATransition)
self.dismiss(animated: false, completion: nil)
我所做的只是添加git filter-branch --tree-filter "sed -i -e 's/SekrtPassWrd/REDACTED/' myscript.py || echo 'fail'" -- --all
以确保即使在提交中找不到文件,代码也会继续运行。我希望其他人发现这个有用,或者可以使用更好的方法来处理丢失的文件。我没有足够的代表所以我不得不做出新的答案。