1. ホーム
  2. git

[解決済み] 特定のコミットを削除する

2022-03-14 21:41:52

質問

あるプロジェクトで友人と一緒に作業していたのですが、彼は編集されてはいけないファイルを大量に編集してしまいました。どういうわけか、私は彼の仕事を私の仕事にマージしてしまいました。私は長い間、これらのファイルへの編集を含むコミットを削除する方法を探して遊んでいました。それはrevertとrebaseの間の投げ合いのようで、簡単な例はありませんし、ドキュメントでは私が私以上に知っていると仮定しています。

というわけで、以下は質問の簡略版です。

次のようなシナリオの場合、コミット2を削除するにはどうすればよいですか?

$ mkdir git_revert_test && cd git_revert_test

$ git init
Initialized empty Git repository in /Users/josh/deleteme/git_revert_test/.git/

$ echo "line 1" > myfile

$ git add -A

$ git commit -m "commit 1"
[master (root-commit) 8230fa3] commit 1
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 myfile

$ echo "line 2" >> myfile

$ git commit -am "commit 2"
[master 342f9bb] commit 2
 1 files changed, 1 insertions(+), 0 deletions(-)

$ echo "line 3" >> myfile

$ git commit -am "commit 3"
[master 1bcb872] commit 3
 1 files changed, 1 insertions(+), 0 deletions(-)

期待される結果は

$ cat myfile
line 1
line 3

以下は、私がリバートしようとしている例です。

$ git revert 342f9bb
Automatic revert failed.  After resolving the conflicts,
mark the corrected paths with 'git add <paths>' or 'git rm <paths>'
and commit the result.

解決方法は?

Git が元に戻すべき差分を計算する際に使用するアルゴリズムでは、以下のことが要求されます。

  1. 元に戻される行は、それ以降のコミットで変更されていません。
  2. 歴史上、他の "隣接" コミットが存在しないこと。

隣接する("adjacent") の定義は、コンテキスト差分のデフォルトの行数である 3 に基づいています。

$ cat >myfile <<EOF
line 1
junk
junk
junk
junk
line 2
junk
junk
junk
junk
line 3
EOF
$ git add myfile
$ git commit -m "initial check-in"
 1 files changed, 11 insertions(+), 0 deletions(-)
 create mode 100644 myfile

$ perl -p -i -e 's/line 2/this is the second line/;' myfile
$ git commit -am "changed line 2 to second line"
[master d6cbb19] changed line 2
 1 files changed, 1 insertions(+), 1 deletions(-)

$ perl -p -i -e 's/line 3/this is the third line/;' myfile
$ git commit -am "changed line 3 to third line"
[master dd054fe] changed line 3
 1 files changed, 1 insertions(+), 1 deletions(-)

$ git revert d6cbb19
Finished one revert.
[master 2db5c47] Revert "changed line 2"
 1 files changed, 1 insertions(+), 1 deletions(-)

すると、すべて期待通りに動作するようになります。

2つ目の回答はとても興味深いものでした。 まだ正式にリリースされていない機能ですが、(Git v1.7.2-rc2では利用可能ですが)Revert Strategyというものがあります。 このようにgitを呼び出すことができます。

git revert --戦略的解決 <commit>

を使えば、より良い仕事ができるはずです。 私は利用可能なストラテジーのリストが何であるか知りませんし、どのストラテジーの定義も知りません。