我想把一个Git项目放在GitHub上,但它包含某些具有敏感数据的文件(用户名和密码,如/config/deploy。卡皮斯特拉诺的Rb)。
我知道我可以将这些文件名添加到.gitignore中,但这不会删除它们在Git中的历史记录。
我也不想通过删除/来重新开始。git目录。
是否有一种方法可以删除Git历史记录中特定文件的所有痕迹?
我想把一个Git项目放在GitHub上,但它包含某些具有敏感数据的文件(用户名和密码,如/config/deploy。卡皮斯特拉诺的Rb)。
我知道我可以将这些文件名添加到.gitignore中,但这不会删除它们在Git中的历史记录。
我也不想通过删除/来重新开始。git目录。
是否有一种方法可以删除Git历史记录中特定文件的所有痕迹?
当前回答
我推荐大卫·安德希尔的这个剧本,对我来说很有魅力。
它在natacado的filter分支中添加了这些命令来清理它留下的混乱:
rm -rf .git/refs/original/
git reflog expire --all
git gc --aggressive --prune
完整剧本(全部由大卫·安德希尔提供)
#!/bin/bash
set -o errexit
# Author: David Underhill
# Script to permanently delete files/folders from your git repository. To use
# it, cd to your repository's root and then run the script with a list of paths
# you want to delete, e.g., git-delete-history path1 path2
if [ $# -eq 0 ]; then
exit 0
fi
# make sure we're at the root of git repo
if [ ! -d .git ]; then
echo "Error: must run this script from the root of a git repository"
exit 1
fi
# remove all paths passed as arguments from the history of the repo
files=$@
git filter-branch --index-filter \
"git rm -rf --cached --ignore-unmatch $files" HEAD
# remove the temporary history git-filter-branch
# otherwise leaves behind for a long time
rm -rf .git/refs/original/ && \
git reflog expire --all && \
git gc --aggressive --prune
最后两个命令如果改为下面的命令可能会更好:
git reflog expire --expire=now --all && \
git gc --aggressive --prune=now
其他回答
它看起来是这样的:
git rm --cached /config/deploy.rb
echo /config/deploy.rb >> .gitignore
从git中删除跟踪文件的缓存,并将该文件添加到.gitignore列表中
Git filter-repo现在正式推荐超过Git filter-branch
在git 2.5本身的git filter-branch的手册中提到了这一点。
从git/GitHub的历史记录中删除文件夹及其内容
pip install git-filter-repo
git filter-repo --path path/to/remove1 --path path/to/remove2 --invert-paths
这将自动删除空提交。
或者你可以替换某些字符串:如何替换整个Git历史中的字符串?
git filter-repo --replace-text <(echo 'my_password==>xxxxxxxx')
如果您推送到GitHub,强制推送不够,请删除存储库或联系技术支持
即使你在一秒钟后强行推,这也不够,如下所述。
唯一有效的做法是:
泄露的是像密码一样可更改的凭证吗? 是:立即修改您的密码,并考虑使用更多的OAuth和API密钥! 不(裸照): 您是否关心存储库中的所有问题都被nuked? No:删除存储库 是的: 联络支持 如果泄漏对你来说非常重要,以至于你愿意让一些存储库停机以降低泄漏的可能性,那么在你等待GitHub支持回复你的时候,将其设置为私有
一秒钟后的推力是不够的,因为:
GitHub keeps dangling commits for a long time. GitHub staff does have the power to delete such dangling commits if you contact them however. I experienced this first hand when I uploaded all GitHub commit emails to a repo they asked me to take it down, so I did, and they did a gc. Pull requests that contain the data have to be deleted however: that repo data remained accessible up to one year after initial takedown due to this. Dangling commits can be seen either through: the commit web UI: https://github.com/cirosantilli/test-dangling/commit/53df36c09f092bbb59f2faa34eba15cd89ef8e83 (Wayback machine) the API: https://api.github.com/repos/cirosantilli/test-dangling/commits/53df36c09f092bbb59f2faa34eba15cd89ef8e83 (Wayback machine) One convenient way to get the source at that commit then is to use the download zip method, which can accept any reference, e.g.: https://github.com/cirosantilli/myrepo/archive/SHA.zip It is possible to fetch the missing SHAs either by: listing API events with type": "PushEvent". E.g. mine: https://api.github.com/users/cirosantilli/events/public (Wayback machine) more conveniently sometimes, by looking at the SHAs of pull requests that attempted to remove the content There are scrappers like http://ghtorrent.org/ and https://www.githubarchive.org/ that regularly pool GitHub data and store it elsewhere. I could not find if they scrape the actual commit diff, and that is unlikely because there would be too much data, but it is technically possible, and the NSA and friends likely have filters to archive only stuff linked to people or commits of interest.
如果你删除了存储库,而不是强制推送,提交甚至会立即从API中消失,并给出404,例如https://api.github.com/repos/cirosantilli/test-dangling-delete/commits/8c08448b5fbf0f891696819f3b2b2d653f7a3824,即使你重新创建了另一个具有相同名称的存储库,这也是有效的。
为了测试这一点,我创建了一个repo: https://github.com/cirosantilli/test-dangling,并做了:
git init
git remote add origin git@github.com:cirosantilli/test-dangling.git
touch a
git add .
git commit -m 0
git push
touch b
git add .
git commit -m 1
git push
touch c
git rm b
git add .
git commit --amend --no-edit
git push -f
参见:如何从GitHub删除悬空提交?
更改密码是一个好主意,但对于从回购历史记录中删除密码的过程,我推荐BFG回购- cleaner,这是一个更快、更简单的替代Git -filter-branch,专门用于从Git回购中删除私人数据。
创建一个private.txt文件,列出你想要删除的密码等(每行一个条目),然后运行以下命令:
$ java -jar bfg.jar --replace-text private.txt my-repo.git
你的回购历史记录中所有小于阈值大小(默认为1MB)的文件将被扫描,任何匹配的字符串(不是你最近提交的)将被替换为字符串“***REMOVED***”。然后你可以使用git gc清除死数据:
$ git gc --prune=now --aggressive
BFG通常比运行git-filter-branch快10-50倍,并且选项是围绕以下两个常见用例进行简化和定制的:
删除疯狂的大文件 删除密码,凭证和其他私人数据
完全披露:我是好心眼巨人回收清理器的作者。
你可以使用git的forget-blob。
它的用法很简单,git forget-blob file-to-forget。你可以在这里获得更多信息
https://ownyourbits.com/2017/01/18/completely-remove-a-file-from-a-git-repository-with-git-forget-blob/
它将从历史记录、reflog、标签等所有提交中消失
我时不时地会遇到同样的问题,每次我都要回到这个帖子和其他帖子,这就是为什么我把这个过程自动化了。
感谢Stack Overflow的贡献者,是他们让我把这些放在一起
到目前为止,我已经做过几次了。注意,这一次只对一个文件有效。
获取修改文件的所有提交的列表。底部的将是第一个提交: git log——pretty=oneline——branches——pathToFile 要从历史记录中删除文件,请使用第一个提交sha1和之前命令中的文件路径,并将它们填充到这个命令中: Git filter-branch——index-filter ' Git rm——cached——ignore-unmatch <path-to-file>'——<sha1-where-the-file-was-first-added>..