元々追加したコミットから削除された複数行を削除するGitコマンド

元々追加したコミットから削除された複数行を削除するGitコマンド

Gitバージョンコントロールファイルからいくつかの行を削除するときにその行を削除する新しいコミットを作成するのではなく、最初に導入したコミットからその行を削除するgitコマンドはありますか?たとえば、次のファイルが提供されます。

$ echo "Line 1" >> foo
$ echo "Line 2" >> foo
$ git commit -a -m "Add 1, 2"
[master 1005cbb] Add 1, 2
 1 file changed, 2 insertions(+)

$ echo "Line 3" >> foo
$ git commit -a -m "Add 3"
[master 5036981] Add 3
 1 file changed, 1 insertion(+)

$ echo "Line 4" >> foo
$ echo "Line 5" >> foo
$ git commit -a -m "Add 5, 6"
[master 41ca6ab] Add 5, 6
 1 file changed, 2 insertions(+)

$ git blame -s foo
1005cbbb 1) Line 1
1005cbbb 2) Line 2
50369811 3) Line 3
41ca6ab6 4) Line 4
41ca6ab6 5) Line 5

2-4行を削除するとします。

$ sed -i '/Line [234]/d' foo
$ git diff
diff --git a/foo b/foo
index 572d5d9..e486b1b 100644
--- a/foo
+++ b/foo
@@ -1,5 +1,2 @@
 Line 1
-Line 2
-Line 3
-Line 4
 Line 5

1005cbbこれで、変更をコミットするのではなく、履歴からこれらの行を完全に削除するタスクを実行して(または新しいハッシュが何であれ)、「line 1」のみを追加し、空または消える新しいツリーを5036981作成したいと思います。41ca6ab「ライン5」が追加されます。

可能ですか?私が考えることができる最も近いのは、rebaseの前に各行を個別に削除することですが、git commit --fixup hash-of-the-commit-that-added-that-lineこの方法で自動化する前により良い組み込み方法があるかどうか疑問に思います。

答え1

これは何ですか?git filter-branchこれにより、履歴のすべてのリビジョンに対してコマンドが実行され、変更に関係なく結果が再送信されます。最初の修正バージョン以降、すべてのコミットのすべてのハッシュが変更され、新しいブランチがすべてのレプリカと互換性がなくなります。

sed -i '/Line [234]/d' foo必要な修正を実行するコマンドの場合は、それをツリーフィルタとして適用できます。

git filter-branch --tree-filter "sed -i '/Line [234]/d' foo" HEAD

一般的に、複雑な内容を自分のスクリプトに配置する方が簡単です。フィルタコマンドは別のディレクトリで実行されるため、フルパスを指定してください。

多くのフィルタリングモードがあります。ツリーフィルタはファイル自体を変更し、他のフィルタと組み合わせてコミットメッセージ、詳細、親、タグなどを変更できます。ツリーフィルタは、新しいリポジトリで実行しているかのように動作しますgit add -f *。既存のすべてのファイルには現在コンテンツが追加されています。ローカルまたはグローバルを無視する、存在しなくなったファイルはすべて削除されます。

関連情報