我想把一个Git项目放在GitHub上,但它包含某些具有敏感数据的文件(用户名和密码,如/config/deploy。卡皮斯特拉诺的Rb)。

我知道我可以将这些文件名添加到.gitignore中,但这不会删除它们在Git中的历史记录。

我也不想通过删除/来重新开始。git目录。

是否有一种方法可以删除Git历史记录中特定文件的所有痕迹?


当前回答

在我的android项目中,我有admob_keys.xml作为分开的xml文件在app/src/main/res/values/文件夹。要删除这个敏感的文件,我使用下面的脚本和工作完美。

git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch  app/src/main/res/values/admob_keys.xml' \
--prune-empty --tag-name-filter cat -- --all

其他回答

明确一点:公认的答案是正确的。先试试。然而,对于某些用例来说,这可能是不必要的复杂,特别是当你遇到诸如'fatal: bad revision -prune-empty'之类的讨厌错误时,或者真的不关心你的回购历史。

另一种选择是:

CD到项目的基本分支 删除敏感代码/文件 rm -rf .git/ #删除所有git信息 你的代码 去github并删除你的存储库 按照本指南将您的代码推送到一个新的存储库,就像您通常会做的那样 https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/

当然,这将删除所有提交历史分支,以及来自你的github回购和本地git回购的问题。如果这是不可接受的,你将不得不使用另一种方法。

我们可以称之为“核选项”。

更改密码是一个好主意,但对于从回购历史记录中删除密码的过程,我推荐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倍,并且选项是围绕以下两个常见用例进行简化和定制的:

删除疯狂的大文件 删除密码,凭证和其他私人数据

完全披露:我是好心眼巨人回收清理器的作者。

我推荐大卫·安德希尔的这个剧本,对我来说很有魅力。

它在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的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的贡献者,是他们让我把这些放在一起

使用filter-branch:

git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch *file_path_relative_to_git_repo*' --prune-empty --tag-name-filter cat -- --all

git push origin *branch_name* -f