LoginSignup
0
0

More than 1 year has passed since last update.

数回前の要らないコミットを消す方法

Posted at

はじめに

作業中、過去のコミットで行った変更を元に戻す場面があった。
そのまま作業を続けてしまったが、コミット履歴がわかりにくくなっていたので、不必要になったコミットだけ削除した。

git rebase とは

今回はgit rebaseコマンドを使ってコミット履歴を修正した。

base は名詞では土台、動詞では基礎付けるという意味で、これに再起的なニュアンスを表す接頭語 re が付いている。
イメージとしては、ある枝を切り離してから別の場所に接木し直す、といった感じ。

        C' - D' - E'  feature
       /                            →        - A - B - C - C' - D' - E'  master
- A - B - C  master             rebase を実行  

上の例では-C'-D'-E'のブランチを master の先端にくっ付けている。

今回の状態

私が rebase 機能を使ったとき、作業していた feature ブランチは以下のような状態。

- A - B - C - D - E - F  feature
              ↑
     このコミットだけ消したい

E と F のコミットは残したまま、不必要な D のコミットだけ削除したかった。

そこで、-E-Fの部分を -A-B-C の先端に移すことにした。

実行した手順

まずはgit logで、上図の C のコミットID を取得。

git log
commit 69ec236a8acf4659bd0962a47ca843fb9623bchf (HEAD -> feature)
Author: ユーザ名 <メールアドレス>
Date:   Fri Jul 2 10:13:21 2021 +0900

    F のコミット(残したい)

commit ag28517f035f1b143d356335271de88c5c7136ef
Author: ユーザ名 <メールアドレス>
Date:   Fri Jun 25 17:04:23 2021 +0900

    E のコミット(残したい)

commit 52b81060a47202777d94aebd84cad9ae3eda20b8
Author: ユーザ名 <メールアドレス>
Date:   Fri Jun 25 16:53:33 2021 +0900

    D のコミット(不必要)

commit 59e85460e245827455d94oafe84cad9ae3xvm33l ←この文字列をコピー
Author: ユーザ名 <メールアドレス>
Date:   Fri Jun 25 16:53:33 2021 +0900

    C のコミット(ここに付け足したい)

ブランチ付け替え先のコミットID が分かったら、以下のコマンドを実行。

git rebase -i 取得したコミットID

-iオプションを付けて実行すると、個々のコミットに対して編集や削除などを行うことができる。
このオプションがない場合、移動元のコミット全てが自動的に移植される。

今回は D のコミットを消した上で rebase したいので、-iオプションを使用。
すると下のように出力される。

pick 52b8106 D のコミット(不必要)
pick ag28517 E のコミット(残したい)
pick 69ec236 F のコミット(残したい)

# Rebase 59e8546..69ec236 onto 59e8546 (3 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified). Use -c <commit> to reword the commit message.

D のコミットのみ削除したいので、最初の 3行を次のように書き換えた。

drop 52b8106 D のコミット(不必要)
pick ag28517 E のコミット(残したい)
pick 69ec236 F のコミット(残したい)

コンフリクトが無ければこれで完了。

今回はVSCode を開くとコンフリクトが発生していたので解消した。
コンフリクトを全て解消したら、git addコマンドで変更内容をステージングエリアへ。

これで D のコミットの削除は完了したので、git rebase --continueコマンドで次の E のコミットへ移動。
以下のように、残る 2つのコミットのみが表示される。

pick ag28517 E のコミット(残したい)
pick 69ec236 F のコミット(残したい)

EF のコミットは残したかったため、pickのまま続行した。
もし EF も修正したい場合は、D のときと同様pickを書き換えれば良い。

コミットを削除ではなく編集する際は、git addではなくgit commit --amendを使うことに注意。

git rebase --continueを続け、全てのコミットの処理が正常に終わると以下のように出力された。

Successfully rebased and updated refs/heads/feature.

git logで履歴を確認すると、期待通り D のコミットのみが無くなっていた。

git log
commit 69ec236a8acf4659bd0962a47ca843fb9623bchf (HEAD -> feature)
Author: ユーザ名 <メールアドレス>
Date:   Fri Jul 2 10:13:21 2021 +0900

    F のコミット(残したい)

commit ag28517f035f1b143d356335271de88c5c7136ef
Author: ユーザ名 <メールアドレス>
Date:   Fri Jun 25 17:04:23 2021 +0900

    E のコミット(残したい)

commit 59e85460e245827455d94oafe84cad9ae3xvm33l ←この文字列をコピー
Author: ユーザ名 <メールアドレス>
Date:   Fri Jun 25 16:53:33 2021 +0900

    C のコミット(ここに付け足したい)

おわりに

rebase 機能は知識として知っていたつもりだったけれど、実際に使うとなると全く分かってなかった。
あと rebase を同一ブランチ上で実行できることも初めて知った。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0