
Gitがコミットを維持する方法
Gitリポジトリは単純なキーと値のストレージを使用します。キーはSHA-1ハッシュであり、値は3つのタイプのいずれかのコンテナです:コミットの説明、ファイルツリーの説明、またはファイルの内容。 このリポジトリをデータベースとして使用するための低レベルの配管コマンドもあります。
echo 'test content' | git hash-object -w --stdin
このアーキテクチャ上の特徴により、Gitはファイルの内容によって名前を変更することを追跡するという泥だらけの言葉が生まれました。 「コミット」オブジェクトの名前を変更すると、「ファイルコンテンツ」オブジェクトへのリンクが含まれますが、コンテンツが変更されていない場合は、すでにリポジトリにあるオブジェクトへのリンクになります。

デフォルトでは、Gitはファイルのコンテンツ全体を保存します。100キロバイトのソースの行を変更すると、zlibで圧縮された100キロバイトすべてのオブジェクトがリポジトリに追加されます。 リポジトリが過度に膨張するのを防ぐために、Gitはプッシュコマンドの実行時に実行されるガベージコレクターを提供しますが、オブジェクトは元のファイルと次のリビジョン(diff)の違いを含むパックファイルに再パッケージされます。
コミットが死ぬとき

ただし、「不必要な」コミットは、resetコマンドを使用したときだけでなく発生します。 たとえば、一般的なリベース操作は、コミットに関する情報をコピーするだけで、誰にも必要のない「オリジナル」をリポジトリに残します。 そのような「失われた」オブジェクトがGitに蓄積するのを防ぐために、プッシュコマンドの実行時に自動的に呼び出されるか手動で呼び出されるガベージコレクションメカニズム(前述のガベージコレクタ)が提供されます。
ガベージコレクターは、参照されなくなったオブジェクトを検索し、それらをストレージから削除します。 reflog操作ログはこれに大きな役割を果たします。その中のリンクの寿命は限られています。デフォルトでは、リンクのないオブジェクトでは30日間、リンクのあるオブジェクトでは90日間です。 ガベージコレクターは、最初に期限切れのリンクをすべてreflogから削除し、次にリポジトリから参照されなくなったオブジェクトを削除します。 このアーキテクチャにより、開発者は30日間で「不要な」コミットを復元できます。そうしないと、この期間が過ぎるとリポジトリから完全に削除されます。
GitHubで何が起こったのですか?

Gitの内部へのこの短い余談は、たとえばバグトラッカーによって参照される「コミットの欠落」を検索する際に貴重な時間を節約できることを願っています。 私がどこかで間違いをしたか、コメントがある場合、私は喜んでコメントで話します。