我正在尝试使用以下内容重写历史记录:
git filter-branch --tree-filter 'git ls-files -z "*.php" |xargs -0 perl -p -i -e "s#(PASSWORD1|PASSWORD2|PASSWORD3)#xXxXxXxXxXx#g"' -- --all
如this tutorial中所述。
但是,我的密码字符串包含所有类型的非A-Z字符,例如$'和\,而不是上面例子中简单的'PASSWORD1'类型字符串。
有人可以解释一下我需要逃避什么吗?我无法在任何地方找到这个,而且我已经和它斗争了好几个小时。
答案 0 :(得分:2)
如果您使用The BFG而不是git-filter-branch
,则可以使用多更友好的替换格式。创建一个passwords.txt
文件,每行一个密码,如下所示:
PASSWORD1==>xXxXx # Replace literal string 'PASSWORD1' with 'xXxXx'
ezxcdf\fr$sdd%==>xXxXx # ...all text is matched as a *literal* string by default
然后使用此命令run the BFG:
$ java -jar bfg.jar -fi '*.php' --replace-text passwords.txt my-repo.git
将扫描整个存储库历史记录,并且所有.php
个文件(大小不超过1MB)将执行替换:任何匹配的字符串(不在最新提交中) )将被替换。
请注意,解析BFG的唯一一点就是替换文件在这里拆分为“==>
”字符串 - 在密码中可能不是 - 并且默认情况下,所有文本都按字面解释。
如果您想要更简洁,可以删除“==>
”以及每行后面的所有内容(例如,只有一个密码文件)和默认情况下,BFG将使用字符串“***REMOVED***
”替换每个密码。
BFG通常是hundreds of times faster,而不是在大型仓库上运行git-filter-branch
,并且选项是围绕这两个常见用例量身定制的:
完全披露:我是BFG Repo-Cleaner的作者。
答案 1 :(得分:1)
在konsolebox提供的精彩帮助的基础上,这真的帮助我解决了这个问题,我最终通过shell进行的解决方案是:
在文件中定义字符串strings.txt
string1
another$string
yet! @nother string
some more stuff to re\move
创建一个Perl脚本perl-escape-strings.pl
,用于转义字符串,其中xXxXxXxXxXx是字符串,它们将全部替换为
#!/usr/bin/perl
use strict;
use warnings;
while (<>)
{
chomp;
my $passwd = quotemeta($_);
print qq|s/$passwd/xXxXxXxXxXx/g;\n|;
}
exit 0;
Bash脚本:
# Pre-process the strings
./perl-escape-strings.pl strings.txt > strings-perl-escaped.txt
# Change directory to the repo
cd repo/
# Define the filter command
FILTER="git ls-files -z '*.html' '*.php' | xargs -0 perl -p -i ../strings-perl-escaped.txt"
# Run the filter
git filter-branch --tree-filter "$FILTER" -- --all
但是,由于字符串的数量很大,而且我的存储库很大并且提交了数千次,因此filter-branch方法需要很长时间。所以我将尝试同时在另一个答案中提到的BFG,看它是否更快完成。
答案 2 :(得分:0)
使用包装器脚本:
#!/bin/bash
readarray -t PASSWORDS < list_file
REPLACEMENT='xXxXxXxXxXx'
SEP=$'\xFF'
EXPR=${PASSWORDS[0]}
for (( I = 1; I < ${#PASSWORDS[@]}; ++I )); do
EXPR+="|${PASSWORDS[I]}"
done
EXPR="s${SEP}(${EXPR})${SEP}$REPLACEMENT${SEP}g"
EXPR=${EXPR//'\'/'\\\\'}; EXPR=${EXPR//'$'/'\\\$'}
EXPR=${EXPR//'"'/'\"'}; EXPR=${EXPR//'`','\`'}
EXPR=${EXPR//'^','\\^'}; EXPR=${EXPR//'[','\\['}
EXPR=${EXPR//']','\\]'}; EXPR=${EXPR//'+','\\+'}
EXPR=${EXPR//'?','\\?'}; EXPR=${EXPR//'.','\\.'}
EXPR=${EXPR//'*','\\*'}; EXPR=${EXPR//'{','\\{'}
EXPR=${EXPR//'}','\\}'}; EXPR=${EXPR//'(','\\('}
EXPR=${EXPR//')','\\)'}
FILTER="git ls-files -z '*.php' | xargs -0 perl -p -i -e \"$EXPR\""
echo "Number of passwords: ${#PASSWORDS[@]}"
echo "Passwords:" "${PASSWORDS[@]}"
echo "EXPR: $EXPR"
echo "FILTER: $FILTER"
git filter-branch --tree-filter "$FILTER" -- --all
答案 3 :(得分:0)
从内到外构建它。说密码是
a$b'c\d
正则表达式模式将是
a\$b'c\\d
perl
命令的一种可能性是
perl -i -pe's/a\$b'\''c\\d/.../g'
(请注意每个'
如何替换为'\''
。)
现在您需要将其包含在单引号中,以便重复此过程。
... '... perl -i -pe'\''s/a\$b'\''\'\'''\''c\\d/.../g'\''' ...