git のコミットを dangling commit にしてgcで削除する例

プログラムなどのバージョン管理を行える、無料ソースコード管理 (SCM: software configuration management) ソフト Git で、他のコミットから到達不能になったコミット(dangling commit)を gc (garbage collect) の機能ですぐに削除する手順の例を紹介します。
※定期的に行われる gc auto で一定期間(reflog から破棄されるデフォルトの期間は 90 日)の後に dangling commit は自動的に削除されます。

git-scm 公式サイトの一部 20250408

Git-2.49.0 (64 bit) を使用します。

前回の記事

前回は、どのコミットからも到達不能になり削除される対象になった dangling commit を、削除される前に復旧する手順の例を紹介しました。

今回は、 dangling commit を git gc を用いてすぐに削除する手順を紹介します。
※定期的に行われる gc auto で一定期間(reflog から破棄されるデフォルトの期間は 90 日)の後に dangling commit は自動的に削除されます。

Git gc は自動的に dangling commit を削除します

自身以外のコミットから到達不能なコミット (dangling commit) は、自動的に行われる auto gc によって削除されます。

Gitは時々 “auto gc” と呼ばれるコマンドを自動的に実行します。 

“gc” はガベージコレクト(garbage collect)を意味します。このコマンドは幾つものことを行います。

さらにどのコミットからも到達が不可能かつ数ヶ月間更新がないオブジェクトを削除します。

Git – メンテナンスとデータリカバリ

dangling commit になる条件の1つは、 reflog の記録からそのコミットが消去されることです。
他のコミットから到達不能になったあと、デフォルトでは 90 日間で reflog からそのコミットは消去されます。

そのあとの auto gc のタイミングで dangling commit は削除されます。

–expire=<time>

Prune entries older than the specified time. If this option is not specified, the expiration time is taken from the configuration setting gc.reflogExpire, which in turn defaults to 90 days. --expire=all prunes entries regardless of their age; --expire=never turns off pruning of reachable entries (but see --expire-unreachable).

指定された時間より古いエントリをプルーニングします。このオプションが指定されていない場合、有効期限は構成設定 gc.reflogExpire から取得され、デフォルトでは 90 日になります。 --expire=all は、経過時間に関係なくエントリを削除します。 --expire= は、到達可能なエントリのプルーニングをオフにすることはありません (ただし、--expire-unreachable を参照してください)。
Git – git-reflog Documentation と Google 翻訳

サンプルリポジトリのログの確認

前回の結果を git log –oneline コマンドで確認します。

前回作成した new-branch ブランチ3回目のコミットが、 HEAD の参照先(=現在のコミット位置)に設定されています。

ログでは、現在のコミット以前の3つのコミットが表示されています。

G:\Dev\StudyTortoiseGit\Repo1ResetHard>git log --oneline
fa795f0 (HEAD -> new-branch) file.txt に 2 行目を追加
1f1f4dd file.txt に hello, world を追記。
e2829b8 file.txt をバージョン管理に追加します。

コミットを削除するため再び dangling commit にする

今回は、HEAD の参照先に設定されている new-branch ブランチの3回目のコミットdangling commit にして、 gc を使ってすぐにそのコミットオブジェクトを削除します。

最新のコミットを dangling commit にする手順は、前回の記事でも紹介しています。

 https://compota-soft.work/wp1/wp-admin/post.php?post=53860&action=edit

サンプルリポジトリのフォルダをエクスプローラで開いて、右クリックして表示されるメニュー「TortoiseGit」→「ログを表示」を選択します。

TortoiseGit と git でコミットの削除と削除直前の dangling commit を復元2

表示された「リビジョンログ(ログメッセージ)」ダイアログの上側に表示されている3つのコミットの行のうち、最新より1つ前2行目のコミットを右クリックして表示されるメニュー「”new-branch” をここへリセット」を選択します。
※コミットは上側の行の方が最新です。
※ new-branch は現在のコミットが割り当てられているブランチ名です。

TortoiseGit と git でコミットの削除と削除直前の dangling commit を復元20

「リセット」ダイアログが表示されます。

「現在のブランチのリセット」枠は、「コミット」ラジオボタンが選択されていて、2回目のコミットを指すハッシュ値 (SHA-1) が入力されています。
※ハッシュ値が指すコミットについては、右側の … ボタンから確認できます。

「リセットの種類」枠で Hard ラジオボタンを選択すると、作業ツリーの全ての要素(HEAD, インデックス, 作業ディレクトリ)が指定されたコミットの状態にリセットされます。

設定が完了したら、 OK ボタンでリセット (Hard) を行います。

TortoiseGit と git でコミットの削除と削除直前の dangling commit を復元21
git reset --hard コミット位置のハッシュ値

のコマンドが実行されました。「閉じる」ボタンで閉じます。
※ –end-of-options は前回紹介したように、それ以降の — をオプション表記とみなさないオプションです。

TortoiseGit と git でコミットの削除と削除直前の dangling commit を復元22

「リビジョンログ(ログメッセージ)」ダイアログを再び表示して確認すると、2回目のコミット位置リセットしたため、それより後にコミットされた3回目のコミットの行は表示されなくなりました。

TortoiseGit と git でコミットの削除と削除直前の dangling commit を復元23

git による log と dangling commit の確認

最新の3回目のコミット位置から、リセット (Hard) で2回目のコミットの状態にしたあとのサンプルリポジトリで

git log --oneline

でログを確認すると、 HEAD 以前のコミットだけが表示され、3回目のコミットは表示されなくなりました。

G:\Dev\StudyTortoiseGit\Repo1ResetHard>git log --oneline
1f1f4dd (HEAD -> new-branch) file.txt に hello, world を追記。
e2829b8 file.txt をバージョン管理に追加します。

しかし、 reflog には new-branch ブランチ上に、3回目のコミットの参照履歴が記録されています。

G:\Dev\StudyTortoiseGit\Repo1ResetHard>git log --reflog --oneline
f960404 (master) 最新のコミットの1つ前のコミットから、新たに別のコミットを行います。
fa795f0 file.txt に 2 行目を追加
1f1f4dd (HEAD -> new-branch) file.txt に hello, world を追記。
e2829b8 file.txt をバージョン管理に追加します。

そのため、

git fsck --full

で、到達不能なコミット(dangling commit)を調べても、検出されませんでした。
3回目のコミットはまだ dangling commit になっていません。

G:\Dev\StudyTortoiseGit\Repo1ResetHard>git fsck --full
Checking object directories: 100% (256/256), done.

そこで、reflog からも、3回目のコミットの情報を消します。

git reflog expire --expire-unreachable=now --all

を使って、到達不能なコミットを reflog の記録から削除します。

git log --reflog --oneline

で確認すると reflog にさっきはあった「fa795f0 file.txt に 2 行目を追加」という3回目のコミットの行がなくなっています。

G:\Dev\StudyTortoiseGit\Repo1ResetHard>git reflog expire --expire-unreachable=now --all

G:\Dev\StudyTortoiseGit\Repo1ResetHard>git log --reflog --oneline
f960404 (master) 最新のコミットの1つ前のコミットから、新たに別のコミットを行います。
1f1f4dd (HEAD -> new-branch) file.txt に hello, world を追記。
e2829b8 file.txt をバージョン管理に追加します。
TortoiseGit と git でコミットの削除と削除直前の dangling commit を復元24

reflog から到達不能なコミット記録を削除したあとの確認

reflog から到達不能なコミットの記録を削除した後に再び

git fsck --full

で dangling commit を調べると、「dangling commit 3回目のコミットのハッシュ値」が表示されました。
削除したい3回目のコミットdangling commit になりました。

G:\Dev\StudyTortoiseGit\Repo1ResetHard>git fsck --full
Checking object directories: 100% (256/256), done.
dangling commit fa795f083559ba016c00be644bd24601ac587f41

gc で dangling commit を削除

あとは、何もしなくても gc (garbage collect) の機能で自動的に削除されるのですが、いつ行われるかはわかりません。

今回は、こちらからコマンドを実行して、即時 dangling commit を削除します。
※gc によって削除されたコミットはおそらく復元できません

git gc --prune=now

を実行すると、すぐに dangling commit は削除されます。

G:\Dev\StudyTortoiseGit\Repo1ResetHard>git gc --prune=now
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 12 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (7/7), done.
Total 7 (delta 1), reused 0 (delta 0), pack-reused 0 (from 0)

dangling commit を削除した後に、再び

git fsck --full

で dangling commit を調べると、削除されたため、検出されませんでした。
#Verifying などのメッセージが増えていますが、これは削除に伴って整合性を確認する処理を行ったようです。

G:\Dev\StudyTortoiseGit\Repo1ResetHard>git fsck --full
Checking object directories: 100% (256/256), done.
Checking objects: 100% (7/7), done.
Verifying commits in commit graph: 100% (3/3), done.
TortoiseGit と git でコミットの削除と削除直前の dangling commit を復元25

まとめ

今回は、プログラムなどのバージョン管理を行える、無料ソースコード管理 (SCM: software configuration management) ソフト Git で、他のコミットから到達不能になったコミット(dangling commit)を gc (garbage collect) の機能ですぐに削除する手順の例を紹介しました。

参照サイト Thank You!

記事一覧 → Compota-Soft-Press

コメント

Ads Blocker Image Powered by Code Help Pro

お願い - Ads Blocker Detected

このサイトは広告を掲載して運営しています。

ポップアップを閉じて閲覧できますが、よろしければ

このサイト内の広告を非表示にする拡張機能をオフにしていただけませんか?

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.

タイトルとURLをコピーしました