はじめに
gitのコミットを整理することは大事です。特にチーム開発をしている時は、コミット履歴の綺麗さがレビュアーの生産性に直結します。
なので、自分はPRを出す前にコミット履歴をまとめて整理することがよくあります。
ですが、大きなPRを作る時など、整理したつもりが間違えてコミットを作ってしまうことがあります。
例えば次のような感じです。
- init project
- create package1
- package1/file1.txt 追加
- create package2
- package2/file1.txt 追加
- add files to package1
- package1/file2.txt 追加
- package1/file3.txt 追加
- package1/file4.txt 追加
- package2/file2.txt 間違えて追加
- add files to package2
- package2/file3.txt 追加
- package2/file4.txt 追加
- modify ...
- modify ...
- modify ...- modify ...
....
三つ目のコミット「add files to package1」に間違えてpackage2/file2.txt
の作成を混ぜてしまっています。本来はこのファイルの作成は次のコミットに含めるべきものです。
直近のコミットならgit reset HEAD~
なりで修正すれば良いですが、その後にいくつものコミットがある場合は、それらのコミットも全てリセットすることになってしまいます。色々整理し終わっていざpushする直前にこのような間違いに気づくととても大変ですね。
このような状態の時に、簡単に過去のコミットのファイルを移動させる方法です。
やり方
まず、間違えてファイルを追加してしまったコミットのコミットIDを取得します。
$ git log --oneline
872653a (HEAD -> master) modify package1/file1.txt
71135ef add files to package2
ffb5ca4 add files to package1 # 今回はこれのコミットID
b876371 create package2
903598c create package1
続いて、移動させたいファイルをどのような名前でも良いのでリネームします。すると、gitにはこのような差分として表示されます。
$ mv package2/file2.txt package2/file2.txt_
$ git status
On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
deleted: package2/file2.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
package2/file2.txt_
このdeleted
として表示された差分だけをfixup
でコミットします。
$ git add package2/file2.txt
$ git commit --fixup ffb5ca4 # 先ほどのコミットIDを指定
[master 4d0136f] fixup! add files to package1
1 file changed, 1 deletion(-)
delete mode 100644 package2/file2.txt
今度は、ファイルを本来追加すべきコミットのコミットIDを取得します。
$ git log --oneline
872653a (HEAD -> master) modify package1/file1.txt
71135ef add files to package2 # 今度はこれのコミットID
ffb5ca4 add files to package1
b876371 create package2
903598c create package1
そして、リネームしたファイル名を元に戻して、fixup
でコミットします。
$ mv package2/file2.txt_ package2/file2.txt
$ git add .
$ git commit --fixup 71135ef # コミットIDを指定
[master bbe31b9] fixup! add files to package2
1 file changed, 1 insertion(+)
create mode 100644 package2/file2.txt
最後にrebase
をかけてfixup
を適用させます。
git rebase -i --autosquash ffb5ca4~ # 間違えてファイルを追加してしまったコミットのコミットIDを指定
これでコミット履歴が素敵になります。
どういうことか
詳しくは解説しませんがgit fixup
は複数のコミットをまとめるコマンドです。
今回は「間違えてファイルを追加したコミット」と「ファイルを削除」というコミットを1つにまとめ、さらに「ファイルを追加し忘れたコミット」と「ファイルを追加する」というコミットをまとめました。
こうすることにより、擬似的にコミット間でファイルを移動させたというわけです。
参考文献