gitでブランチを削除すると、ブランチが履歴から削除されますか?


189

svnから来て、gitに慣れてきました。

ブランチがgitで削除されると、履歴から削除されますか?

svnでは、削除操作を元に戻す(リバースマージ)ことで、ブランチを簡単に回復できます。svnでのすべての削除と同様に、ブランチは実際には削除されず、現在のツリーから削除されるだけです。

ブランチが実際にgitの履歴から削除された場合、そのブランチからマージされた変更はどうなりますか?それらは保持されますか?

回答:


249

ブランチはgitのコミットへのポインタにすぎません。gitでは、各コミットに完全なソースツリーがあります。これはsvnとは非常に異なる構造であり、すべてのブランチとタグ(慣例により)は、特別な「トランク」とともにリポジトリの個別の「フォルダー」にあります。

ブランチが削除される前に別のブランチにマージされた場合、最初のブランチが削除されても、他のブランチからすべてのコミットに到達できます。彼らはそのままでした。

ブランチが別のブランチにマージされずに削除された場合、そのブランチのコミット(まだ到達可能なコミットから分岐されたポイントまで)は表示されなくなります。

コミットは引き続きリポジトリに保持され、削除後すぐに回復することができますが、最終的にはガベージコレクションされます。


3
答えてくれてありがとう。「各コミットには完全なソースツリーがある」という意味を明確にできますか?私が理解しているように、gitの各コミットは、ツリー全体ではなく親コミットを参照する一連のデルタです。
Ken Liu

2
@Ken Liu:コミットには、ゼロ以上の親コミットへのポインタ、ツリーオブジェクト、およびコミットに関するメタデータが含まれています。したがって、コミットは、カップルソースツリーと、その親に対して表示したときに導入された変更の両方を一意に識別します。
CBベイリー

9
@Ken Liu:それはあなたが 'contain'によって何をしていたかに依存しますが、はい、本質的に各コミットは完全なツリーを含みます。オブジェクトデータベースでは、オブジェクトはIDでインデックス付けされるため、オブジェクトはそれらを参照するすべてのオブジェクト(ツリーとコミット)間で共有されるため、暗黙のストレージオーバーヘッドは最初のサウンドほど悪くありません。gitには効率的なストレージ最適化(パックファイル)もあり、ディスクスペースをさらに効率的に使用できます。
CBベイリー

22
「最終的にはガベージコレクションされます」 -最終的にはいつですか?
BadHorsie

7
@BadHorsie、それは依存します。
AliOli 2016

86

Gitでは、ブランチはコミットの有向非循環グラフ(DAG)でのコミットへの単なるポインター(参照)です。つまり、ブランチを削除すると、コミットへの参照のみが削除され、DAG内の一部のコミットが到達不能になり、見えなくなる可能性があります。ただし、削除されたブランチにあったすべてのコミットは、少なくとも到達不能なコミットがプルーニングされる(たとえばを使用するgit gc)まで、リポジトリに残ります。

git branch -d削除しても到達できないコミットが残されないことが確実でない場合は、ブランチの削除を拒否することに注意してください。git branch -D到達不能なコミットを残す可能性がある場合は、強力なブランチを使用してブランチを強制的に削除する必要があります。

また、到達不能なコミットが存在する場合、それは削除されたブランチの最後のヒントと、別の既存のブランチにマージされたコミット、タグ付きコミット、またはブランチポイントの間のコミットのみであることにも注意してください。どちらか遅い方です。たとえば、次の状況で:

---- O ---- * ---- * ---- / M ---- * <-マスター<-ヘッド
     \ /
      \ --.----.-- /-x --- y <-削除されたブランチ

ブランチを削除すると、「x」と「y」だけが到達不能になります。

gc.reflogExpireデフォルトの90日の期間内に削除されたブランチを操作した場合、削除されたブランチの最後のヒントがHEAD reflogに記録されます(git reflog show HEADまたはを参照git log --oneline --walk-reflogs HEAD)。HEAD reflogを使用して、削除されたポインターを回復できるはずです。また、この場合、削除されたブランチのみの到達不能なコミットは、gc.reflogExpireUnreachable期間(デフォルトでは30日)内のプルーニング(削除)から保護されることにも注意してください。

HEADのreflogで削除したばかりのブランチの先端が見つからない場合は、を使用git fsckして「到達不能コミット<sha1>」を見つけ、それらを調べて(git show <sha1>またはを介してgit log <sha1>)削除したブランチの先端を見つけます。

削除したブランチの先端を見つける方法に依存せず、削除を取り消すか、削除したブランチを次のように再作成できます。

git branch <deleted-branch> <found-sha1-id>

ただし、ブランチのreflogは失われることに注意してください。


git-resurrect.shスクリプトもありcontrib/、指定された名前のブランチチップのトレースを検索して、復活(削除解除)するのに役立ちます。


1
驚くばかり!git reflog show HEADコミットをリストし、あなたが言ったように新しいブランチを作成しました。
Steven Almeroth、2015年

2

誤ってブランチを削除してしまうことが心配で、リポジトリのローカルコピーがなくなった場合は、GerritなどのエンタープライズGitサーバーに拡張機能があり、履歴の書き換えとブランチの削除を検出し、それらを特別な参照の下でバックアップして、必要に応じて復元でき、ガベージコレクションによって削除されません。Gerrit管理者は、法的な理由で必要な場合でも、選択したコミットを削除できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.