自分は作業中は超適当にcommitを積み重ねることもしばしばあり、ブランチの内容が完成形になった後、本流にmergeする直前に歴史改変をしておく派。現時点でやっている方法をメモしておく。もちろん、今後もっとこうしようという考えが変わることはありうる。
次のようなfeatureブランチが生えているものとする。
$ git log --oneline --all 8b73f05 (HEAD -> feature) 歴史3 44a692b 歴史2 3f12709 歴史1 def9ac2 (main) first commit
バックアップをとる
チキンハートの持ち主なので、何かmergeが事故ったときのことを常に想像している。 切り戻せるようにバックアップのブランチを作っておく。
$ git branch feature_backup $ git log --oneline 8b73f05 (HEAD -> feature, feature_backup) 歴史3 44a692b 歴史2 3f12709 歴史1 def9ac2 (main) first commit
コミットを全部溶かす
git reset --mixed
で適当な歴史を全部溶かす。バックアップもあるのでえいやでやる。
適当な歴史はHEADから3件存在するので次のようにする。
※ --mixedは省略可能らしいが、手が慣れてしまって毎回うっかり書いてしまう。
$ git reset --mixed HEAD~3 $ git log --oneline --all 8b73f05 (feature_backup) 歴史3 44a692b 歴史2 3f12709 歴史1 def9ac2 (HEAD -> feature, main) first commit $ git status On branch feature Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: hello.txt Untracked files: (use "git add <file>..." to include in what will be committed) test1.txt test2.txt test3.txt no changes added to commit (use "git add" and/or "git commit -a")
$ git status
すると歴史が溶けて変更内容だらけになっていることがわかる。カオス。
正史を積みなおす
丁寧にする場合、積みたい歴史単位で $ git add ファイル名
しては commit 、を繰り返す。
(※面倒になったら1つのPullRequestで1機能、と判断して1commitで済ませることもまああるが...。)
$ git add test*.txt $ git status On branch feature Changes to be committed: (use "git restore --staged <file>..." to unstage) new file: test1.txt new file: test2.txt new file: test3.txt Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: hello.txt $ git commit -m 'test#{N}.txtを生成した'
また、この時「同じファイルの中に複数行の変更があって、それぞれ別のcommitに積みたい」という場合は $ git add -p ファイル名
することで、commitする行を選ぶことができる。
方法はこちら: git-scm.com 7.2 Git のさまざまなツール - 対話的なステージング
終わったら --force-with-lease で強制push
すでにリモートリポジトリにブランチがある場合、念の為 --force-with-lease
を使ってpush する。
万が一、他の人がcommitを追加していた時は気づくことができる。
完全に終わったら不要なブランチは消す
そういえば feature_backup
というブランチを作っていた。
完全にもう大丈夫と思えたら潔く消す。
$ git branch -D feature_backup
自分はGitを積み木みたいなイメージで毎度使っている。 便利。