簡體   English   中英

git-filter-branch刪除字符串,但是字符串包含$'\\和其他字符

[英]git-filter-branch to remove strings, but where strings contain $ ' \ and other characters

我正在嘗試使用以下方式重寫歷史記錄:

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'類型字符串。

有人可以解釋我需要什么轉義嗎? 我在任何地方都找不到它,並且已經為此奮斗了數小時。

嘗試使用BFG代替git filter-branch ...

如果你使用,你可以使用一個更加友好的替代格式的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

然后使用以下命令運行BFG

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

您的整個存儲庫歷史記錄將被掃描,並且所有.php文件(大小小於1MB)將執行替換:任何匹配的字符串(不在您的最新提交中)將被替換。

...無需轉義

請注意,在這里使用替換文件解析BFG的惟一步驟是在' ==> '字符串上拆分-可能不在您的密碼中-默認情況下,所有文本均按字面意義進行解釋。

如果您想更加簡潔,可以將' ==> '及其后面的所有內容都刪除(即, 僅包含一個passwords文件 ),BFG將用字符串' ***REMOVED***替換每個密碼。 ***REMOVED*** '默認情況下。

BFG通常比在大型倉庫上運行git-filter-branch 快數百倍,並且圍繞以下兩種常見用例量身定制選項:

  • 刪除瘋狂的大文件
  • 刪除密碼,憑據和其他私人數據

完全公開:我是BFG Repo-Cleaner的作者。

konsolebox提供的出色幫助的基礎上 ,它確實幫助我解決了這一問題,最終我通過外殼實現的解決方案是:

在文件strings.txt定義strings.txt

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

創建一個Perl腳本perl-escape-strings.pl ,該腳本將用於轉義字符串,其中xXxXxXXxXxXx是將全部替換為的字符串

#!/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,以查看其是否更快完成。

使用包裝器腳本:

#!/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

從內而外構建它。 說的密碼是

a$b'c\d

regex模式將是

a\$b'c\\d

perl命令的一種可能性是

perl -i -pe's/a\$b'\''c\\d/.../g'

(請注意,每個'如何被替換為'\\'' 。)

現在,您需要將其包括在單引號中,以便重復此過程。

... '... perl -i -pe'\''s/a\$b'\''\'\'''\''c\\d/.../g'\''' ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM