2

我正在尝试改写历史,使用:

git filter-branch --tree-filter 'git ls-files -z "*.php" |xargs -0 perl -p -i -e "s#(PASSWORD1|PASSWORD2|PASSWORD3)#xXxXxXxXxXx#g"' -- --all

本教程中所述。

但是,我的密码字符串包含各种非 AZ 字符,例如 $ ' 和 \,而不是上面示例中简单的 'PASSWORD1' 类型的字符串。

有人可以解释我需要什么转义吗?我无法在任何地方找到它,而且我已经为此奋斗了好几个小时。

4

4 回答 4

3

尝试 BFG 而不是 git filter-branch ...

如果您使用BFG不是. 创建一个文件,每行一个密码,如下所示:git-filter-branchpasswords.txt

PASSWORD1==>xXxXx      # Replace literal string 'PASSWORD1' with 'xXxXx'
ezxcdf\fr$sdd%==>xXxXx # ...all text is matched as a *literal* string by default

然后使用以下命令运行 BFG :

$ java -jar bfg.jar -fi '*.php' --replace-text passwords.txt  my-repo.git

将扫描您的整个存储库历史记录,并且所有.php文件(大小小于 1MB)都将执行替换:任何匹配的字符串(不在您最近的提交中)都将被替换。

...无需转义

请注意,在此处使用替换文件解析 BFG 的唯一一点是拆分 ' ==>' 字符串 - 这可能不在您的密码中 - 并且默认情况下所有文本都按字面意思解释。

如果你想更简洁,你可以==>在每一行删除 ' ' 和它后面的所有内容(即,只有一个密码文件***REMOVED***) ,默认情况下,BFG 将用字符串 ' ' 替换每个密码。

BFG 通常比在大型 repo 上运行快数百倍,git-filter-branch并且这些选项是围绕以下两个常见用例量身定制的:

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

全面披露:我是 BFG Repo-Cleaner 的作者。

于 2013-09-06T06:11:52.843 回答
1

在konsolebox提供的出色帮助的基础上,它确实帮助我解决了这个问题,我最终通过 shell 使用的解决方案是:

在文件中定义字符串,strings.txt

string1
another$string
yet! @nother string
some more stuff to re\move

创建一个perl-escape-strings.pl用于转义字符串的 Perl 脚本,其中 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,看看它是否完成得更快。

于 2013-09-07T10:12:16.473 回答
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
于 2013-09-05T23:27:28.173 回答
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'\''' ...
于 2013-09-06T04:50:56.153 回答