開発を進めていく中で特定のcommitの特定に含まれる、特定ファイルの変更差分だけ除外(なかったことに)したい場合があるかと思います。
例えば、自分が編集したファイルの変更差分がcommit済みの状態で、
git pull --rebaseで他リポジトリのcommitを取り込んだ際にコンフリクトが発生し、
merge commitとして残したくない場合などが該当します。
このような過去のcommitの特定のファイルの変更差分だけを除外する方法について解説します。
1. 戻したいファイルのcommitを特定する
まずは除外したいファイルの変更差分が含まれるcommitを以下コマンドで一覧表示します。
git log --graph --pretty="%h %s" --stat
表示されたcommit一覧が以下。
コミットBのTestB_2.phpを除外したいとします。
この場合、さらに古いコミットCのハッシュ値をメモしておきます。
* 72201c9a コミットA
|
| TestA_1.php | 146 --------------------------------------------------------
|
* 919a044b コミットB
|
| TestB_1.php | 1 +
| TestB_2.php | 26 +++++++++++++-
| TestB_3.php | 29 +++++++++++++++-
|
* 9c54069d コミットC
|
| TestC_1.php | 75 +++++++++++++++++--
| TestC_2.php | 4 -
| TestC_3.php | 156 ++++++++++++++++++--------------------
2. rebaseを実行する
続いて、コミットハッシュ値を元にrebaseします。
つまり、過去のcommitの編集作業を行います。
rebaseコマンドは以下です。
コミットBを編集したいので、先ほ1.でメモした1つ前のコミットCのハッシュ値を指定してコマンドを実行します。
git rebase -i [コミットハッシュ]
# コミットBのファイルを編集する場合、コミットCのハッシュ値を指定
# git rebase -i 9c54069d
すると、テキストエディタが以下のような画面で立ち上がりますので、
編集したいコミットB行の先頭の pick を edit に変更します。
pick 919a044b コミットB
pick 72201c9a コミットA
変更後、保存します(:wq)
edit 919a044b コミットB
pick 72201c9a コミットA
3. 対象のファイルをcheckout & commit
すると、2.でeditにしたcommitの編集モードに切り替わるので、
対象のファイルに対して変更差分を1つ前の状態にcheckoutします。
その後、commitを実行します。
git checkout HEAD^ -- path/to/file
# 対象のTestB_2.phpに対してcheckout実行
# git checkout HEAD^ -- TestB_2.php
git commit --amend
4. rebase完了
commitしたら以下コマンドでrebase作業を完了します。
git rebase --continue
ここまでの操作でコミットBのTestB_2.phpの変更差分が除外されていることが確認できるかと思います。
この操作はまだmergeしていない自分のブランチ内のcommitに対して実行することを想定しています。
他の方と共有しているリポジトリに対して行う場合は、気をつけて実施する必要があるかと思います。
[参考]