45

私は常にインターフェイス ベースの git クライアント (smartGit) を使用してきたため、git コンソールの経験はあまりありません。

ただし、履歴からすべての .txt ファイルの文字列を置き換える必要に直面しています (したがって、ファイル全体を消去するのではなく、文字列を置き換えるだけです)。次のコマンドを見つけました。

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

これを試してみたところ、残念ながら、パスワードが変更されている間に、すべてのバイナリ ファイルが破損していることに気付きました。画像などがすべて破損します。

バイナリ ファイルを破損させずにこれを行うためのより良い方法はありますか?

ありがとう。

編集:

何かと混同してしまいました。バイナリ ファイルが破損する原因となった実際のコードは次のとおりです。

$ git filter-branch --tree-filter "find . -type f -exec sed -i -e 's/originalpassword/newpassword/g' {} \;"

上部のコードは、奇妙なことに、私のパスワードを含むすべてのファイルを実際に削除しました。

4

6 に答える 6

41

-name "pattern"に渡すことで、不要なファイルに触れるのを避けることができますfind

これは私のために働く:

git filter-branch --tree-filter "find . -name '*.php' -exec sed -i -e \
    's/originalpassword/newpassword/g' {} \;"
于 2010-11-06T17:04:27.913 に答える
6

/usr/local/git/findsed.sh に次の内容のファイルを作成しました。

find . -name 'githubDirToSubmodule.sh' -exec sed -i '' -e 's/What I want to remove//g' {} \;

コマンドを実行しました:

git filter-branch --tree-filter "sh /usr/local/git/findsed.sh"

コマンドの説明

git filter-branch を実行すると、コミットした各リビジョンが 1 つずつ処理されます。--tree-filter は、コミットされた各リビジョンで findsed.sh スクリプトを実行し、それを保存してから、次のリビジョンに進みます。

find コマンドは、特定のファイルまたは一連のファイルを検索し、そのファイルに対して sed エディターを実行 (-exec) します。sed は、s/ の後に正規表現を取り、それを / と /g の間の文字列 (私の例では空白) に置き換えるコマンドです。{} は、find コマンドによって指定されたファイル パスへの参照です。ファイル パスが sed に渡されるため、sed は何を処理するかを認識できます。\; -exec コマンドを終了するだけです。

シェル スクリプトとコマンドを別々の部分に分けると、引用符 '' または "" に関して複雑さが軽減されます。

特徴

これを mac に正常に実装しましたが、どうやら sed は mac の特定の (古い?) バージョンです。動作が異なる場合があるため、これは重要です。必ず sed -i '' を実行してください。そうしないと、ファイルの末尾に「-e」が追加され、バックアップファイルに名前を付けたいと思っていました。-i '' は、バックアップ ファイルを作成しないでください。ファイルをその場で編集するだけで、バックアップ ファイルは必要ありません。

-name 'filename.sh' を指定すると、解決できなかった別の問題を回避できました。.sh を含む別のファイルがあり、そのファイルは改行文字なしで終了しました。何らかの理由で sed 、「s/blah/blah/g」がそのファイル内の何にも一致しないにもかかわらず、最後に改行文字を追加します。そのため、その問題を理解する代わりに、他のすべてのファイルを無視するように検索に指示しました。

動作する追加コマンド

さらに、これらのコマンドが findsed.sh ファイルで機能することがわかりました (複数ではなく、一度に 1 つのコマンドのみなので、# 他のコマンドはコメントアウトしてください)。

find . -name '.publishNewZenPackFromGithub.sh.swp' -exec rm -f {} \;
find . -name '*' -exec grep -H PassToRemove {} \;

楽しみ!

于 2011-11-07T19:43:45.827 に答える
2

シェル拡張の問題である可能性があります。"*.php"コマンドを評価するまでにfilter-branch が引用符を失っている場合は、何も展開されていないため、git ls-files -zすべてのファイルがリストされている可能性があります。

フィルター ブランチのソースを確認したり、別の引用のトリックを試したりすることもできますが、私なら、ツリー フィルターを実行する 1 行のシェル スクリプトを作成し、代わりにそのスクリプトを渡すだけです。

于 2010-11-05T22:56:52.510 に答える