46

git リポジトリを開始したとき、最初のコミットとしていくつかのファイルをコミットしました。さて、後で多くのコミットを行った後、これらのファイルに公開したくない情報を含む行が含まれていることに気付きました (残りのコードとは異なります)。したがって、この1行を削除/変更して、残りのコードを保持したいと思います。

周りを検索すると、この解決策が見つかりました: 最初のコミットとして空のコミットを挿入し (ここで説明: Git のルート コミットの前にコミットを挿入しますか? )、それをリベースしてから、古い最初のコミットを amend で編集します。残念ながら、リベース中に多くの残酷なマージ競合が発生します (ここで説明されているように: git: Solving conflicts due to rebase )。

私の問題を解決する別の方法はありますか、またはすべての競合を手動でリベースして編集する必要がありますか?

前もって感謝します :)

4

4 に答える 4

53

すべてのブランチのファイルの履歴から問題のある行を削除するコマンドを次に示します。

git filter-branch --tree-filter 'sed -i "/sensitive information/ d" filename' -- --all

これにより、すべてのリビジョンがチェックアウトされ、sedコマンドが実行され、そのリビジョンがコミットされます。

この場合のsedコマンドは、sensitive information指定されたファイル内のパターンを含むすべての行に一致し、filenameそれらの行を削除します。

注: バックアップを取っておくとよいでしょう。sed最初にスクリプトを単独で実行して、目的の動作をしていることを確認してください。これは、長い履歴で実行するにはかなりの時間がかかる可能性があるためです。

于 2011-08-25T22:39:45.283 に答える
8

ファイルが存在しない場合にエラーにならない次のコマンドを作成しました。

 filename=./path/to/your/filename
 filter=your_regex_here

 git filter-branch --tree-filter 'test -f $filename && sed -i.bak "/$filter/d" $filename  || echo “skipping file“' -- --all
于 2016-06-30T21:37:41.657 に答える
4

私の答えは、すべての最高のものを組み合わせたものです。行全体ではなく、指定されたフィルター文字列だけを置き換え、コミットでファイルが見つからない場合は適切にスキップします。エスケープされた引用符がたくさんありますが、他の回答には本当に奇妙な引用符があり、うまくいきませんでした。

 git filter-branch --tree-filter "test -f \"$filename\" && sed -i \"s/$filter//g\" \"$filename\" || echo \"skipping $filename\"" -- --all
于 2018-05-03T15:23:31.457 に答える
1

ご覧いただけますgit filter-branch

リンクの例を参考にしてください: http://git-scm.com/docs/git-filter-branch

于 2011-08-25T18:14:03.957 に答える