1. 削除対象コミットを確認
まず履歴を確認します。
git log --oneline
例
abc1234 README修正
def5678 パスワード削除
9876543 パスワード追加 ← 消したい
aaa1111 初回コミット
ポイント
- 削除したいコミットIDを控える
- 本当に削除対象か確認する
2. コミット内容を確認
git show 9876543
ポイント
- 本当に削除対象のコミットか確認する
- パスワードや秘密情報などが含まれていないか確認する
3. Interactive Rebaseを開始
対象コミットが直近14コミット以内の場合
git rebase -i HEAD~14
ポイント
-
HEADは最新コミット -
HEAD~14は14個前のコミット - 14コミット分の履歴を編集する
4. 削除対象を drop に変更
例
pick abc1111 通常コミット
drop 9876543 パスワード追加
pick def2222 パスワード削除
pick ghi3333 README修正
ポイント
-
pick:コミットを残す -
drop:コミットを削除する
保存して終了します。
コンフリクトがなければ、これでコミットの削除は完了です。
10. Rebase完了を確認に進みます。
5. コンフリクトが発生した場合
例
CONFLICT (content): Merge conflict in test/test.yml
対象ファイルを開きます。
vi test/test.yml
6. コンフリクトを解消
ファイル内に次のような記号が表示されます。
<<<<<<< HEAD
現在の内容
=======
rebase適用中の内容
>>>>>>> 325675a
以下の記号を削除し、必要な内容だけを残します。
<<<<<<< HEAD
=======
>>>>>>> 325675a
例
var1: test
var2: sample
7. コンフリクト解消を登録
git add test/test.yml
Gitへ「コンフリクトを解消した」ことを伝えます。
8. Rebaseを続行
git rebase --continue
次のコミットの適用へ進みます。
9. コンフリクトが続く場合
以下を繰り返します。
vi <conflict file>
git add <conflict file>
git rebase --continue
10. Rebase完了を確認
完了すると
Successfully rebased and updated refs/heads/feature1
と表示されます。
状態を確認します。
git status
期待される結果
On branch feature1
nothing to commit, working tree clean
11. 削除されたことを確認
履歴を確認します。
git log --oneline
削除対象コミットが表示されないことを確認します。
さらに
git branch --contains 9876543
何も表示されなければ、現在のブランチはそのコミットを参照していません。
補足
他のブランチやタグが参照している場合は、そのコミットはリポジトリ内に残ります。
12. GitLabへ反映
履歴を書き換えたため、通常のPushは失敗します。
git push --force-with-lease origin feature1
ポイント
-
--force-with-lease- 履歴を書き換えてPushする
-
--forceより安全
-
origin- リモート名
-
feature1- Push対象ブランチ
13. GitLabのリポジトリの確認
新しくGitLabからCloneしたリポジトリで
git show 9876543
を実行し、
fatal: bad object 9876543
となれば、そのクローンからはコミットを参照できません。
補足
元のローカルリポジトリでは
git show 9876543
が成功する場合があります。
これはGitが不要になったオブジェクトをすぐには削除しないためです。
確認できます。
git fsck --unreachable
表示されるコミットは
履歴からは外れたものの、ローカルの
.gitディレクトリにはまだ残っているオブジェクト
を意味します。
元のローカルリポジトリからも完全に削除する
1. Reflogを削除
git reflog expire --expire=now --all
内容
- reflogに残っている過去の参照を削除します。
2. Garbage Collectionを実行
git gc --prune=now
内容
- 到達不能オブジェクトを即座に削除します。
- 不要になった commit・tree・blob を回収します。
3. 確認
git show <コミットID>
以下のようになれば削除完了です。
fatal: bad object <コミットID>