Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从Git历史记录中删除敏感文件及其提交_Git_Git Commit_Git Filter Branch_Git Rewrite History - Fatal编程技术网

从Git历史记录中删除敏感文件及其提交

从Git历史记录中删除敏感文件及其提交,git,git-commit,git-filter-branch,git-rewrite-history,Git,Git Commit,Git Filter Branch,Git Rewrite History,我想在GitHub上放置一个Git项目,但它包含某些带有敏感数据的文件(用户名和密码,如capistrano的/config/deploy.rb) 我知道我可以将这些文件名添加到.gitignore,但这不会删除它们在Git中的历史记录 我也不想通过删除/.git目录重新开始 有没有办法删除Git历史记录中某个特定文件的所有痕迹?出于所有实际目的,您首先应该担心的是更改密码您的问题不清楚您的git存储库是否完全是本地的,或者您在其他地方是否有远程存储库;如果它是远程的,并且不受其他人的保护,那么

我想在GitHub上放置一个Git项目,但它包含某些带有敏感数据的文件(用户名和密码,如capistrano的/config/deploy.rb)

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

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


有没有办法删除Git历史记录中某个特定文件的所有痕迹?

出于所有实际目的,您首先应该担心的是更改密码您的问题不清楚您的git存储库是否完全是本地的,或者您在其他地方是否有远程存储库;如果它是远程的,并且不受其他人的保护,那么您就有问题了。如果有人在您修复此问题之前克隆了该存储库,他们将在其本地计算机上拥有您的密码副本,并且您无法强制他们更新到您的“固定”版本,因为它已从历史记录中消失。你能做的唯一安全的事情就是在你使用过的任何地方将密码更改为其他密码


有了这个问题,下面是解决方法:

Windows用户注意事项:在此命令中使用双引号(“)而不是单引号

请记住,一旦您将此代码推送到GitHub这样的远程存储库,并且其他人克隆了该远程存储库,您现在就处于重写历史记录的状态。当其他人在此之后尝试下拉您的最新更改时,他们会收到一条消息,指示无法应用更改,因为这不是一个快进过程

要解决此问题,他们必须删除现有存储库并重新克隆它,或者按照中“从上游重新基恢复”下的说明进行操作

提示:执行
git-rebase——交互式


将来,如果您无意中提交了一些带有敏感信息的更改,但在推送到远程存储库之前注意到,则有一些更简单的修复方法。如果您上次提交是为了添加敏感信息,则只需删除敏感信息,然后运行:

git commit -a --amend
这将使用您所做的任何新更改(包括使用
git rm
完成的整个文件删除)来修改以前的提交。如果更改在历史上进一步追溯,但仍然没有推送到远程存储库,您可以执行交互式重设基础:

git rebase -i origin/master
这将打开一个编辑器,其中包含您自上次与远程存储库共享祖先以来所做的提交。在表示提交的任何行上,将“pick”更改为“edit”,并使用敏感信息保存和退出。Git将遍历这些更改,并将您留在一个可以执行以下操作的位置:

$EDITOR file-to-fix
git commit -a --amend
git rebase --continue
对于每一个带有敏感信息的更改。最终,您将返回到您的分支,并且您可以安全地推动新的更改。

我推荐David Underhill,他对我很有吸引力

除了natacado的过滤器分支之外,它还添加了以下命令,以清理留下的混乱:

rm-rf.git/refs/original/
git reflog过期--全部
git gc——攻击性——修剪
完整脚本(全部归功于David Underhill)

!/bin/bash
set-o errexit
#作者:大卫·安德希尔
#用于从git存储库中永久删除文件/文件夹的脚本
#它将cd复制到存储库的根目录,然后使用路径列表运行脚本
#您要删除,例如git delete history path1 path2
如果[$#-eq 0];则
出口0
fi
#确保我们是git回购的根源
如果[!-d.git];那么
echo“错误:必须从git存储库的根目录运行此脚本”
出口1
fi
#从回购历史记录中删除作为参数传递的所有路径
档案=$@
git筛选器分支--索引筛选器\
“git rm-rf——缓存——忽略不匹配的$files”标题
#删除临时历史git筛选器分支
#否则会留下很长时间
rm-rf.吉特/参考文献/原件\
git reflog过期--all&&\
git gc——攻击性——修剪
如果将最后两个命令更改为以下命令,可能会更好地工作:

git reflog expire --expire=now --all && \
git gc --aggressive --prune=now

更改密码是一个好主意,但对于从回购历史记录中删除密码的过程,我建议使用,这是一种比
git filter branch
更快速、更简单的替代方法,它是专为从git回购中删除私有数据而设计的

创建一个
private.txt
文件,列出要删除的密码等(每行一项),然后运行以下命令:

$ java -jar bfg.jar  --replace-text private.txt  my-repo.git
将扫描回购历史记录中阈值大小(默认为1MB)以下的所有文件,并将任何匹配字符串(不在最新提交中)替换为字符串“***已删除***”。然后,您可以使用
git gc
清除死数据:

$ git gc --prune=now --aggressive
BFG通常比运行
git filter branch
快10-50倍,选项被简化并围绕以下两种常见用例进行定制:

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

完全披露:我是BFG回购清洁剂的作者。

所以,它看起来像这样:

git rm --cached /config/deploy.rb
echo /config/deploy.rb >> .gitignore
从git中删除跟踪文件的缓存,并将该文件添加到
.gitignore
列表中


需要明确的是:被接受的答案是正确的。请先尝试一下。但是,对于某些用例来说,它可能会变得不必要的复杂,特别是当您遇到令人讨厌的错误时,例如“致命的:错误的修订--删减为空”,或者确实不关心回购的历史记录

另一种选择是:

  • cd发送至项目的基础分支机构
  • 删除敏感代码/文件
  • rm-rf.git/#从中删除所有git信息 你的代码
  • 转到github并删除您的存储库
  • 按照本指南将您的代码推送到一个新的存储库,就像您通常所做的那样-
  • 这当然会删除所有提交历史记录
    $ git gc --prune=now --aggressive
    
    git rm --cached /config/deploy.rb
    echo /config/deploy.rb >> .gitignore
    
    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
    
    pip install git-filter-repo
    git filter-repo --path path/to/remove1 --path path/to/remove2 --invert-paths
    
    git filter-repo --replace-text <(echo 'my_password==>xxxxxxxx')
    
    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
    
    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