173

特定のブランチの下にないコミットがたくさんあるGitリポジトリがありますが、git showそれらを含むブランチを一覧表示しようとすると、何も報告されません。

これは(-Dブランチの結果として)ぶら下がっているコミット/ツリーの問題だと思ったので、リポジトリをプルーニングしましたが、その後も同じ動作が見られます:

$ git fetch origin

$ git fsck --unreachable
$ git fsck

出力なし、ぶら下がっているものはありません(右?)。しかし、コミットは存在します

$ git show 793db7f272ba4bbdd1e32f14410a52a412667042
commit 793db7f272ba4bbdd1e32f14410a52a412667042
Author: ...

そしてそれはどのブランチからも到達できません

$ git branch --contains 793db7f272ba4bbdd1e32f14410a52a412667042

出力はありません。

そのコミットの状態は正確には何ですか?同様の状態のすべてのコミットを一覧表示するにはどうすればよいですか?そのようなコミットを削除するにはどうすればよいですか?

4

8 に答える 8

301

ダングリング コミット (スタッシュや他の reflog からまだ到達可能なものを含む) をすべて削除するには、次のようにします。

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

しかし、これがあなたが望むものであることを確認してください。manページを読むことをお勧めしますが、要点は次のとおりです。

git gc到達不能なオブジェクト (コミット、ツリー、ブロブ (ファイル)) を削除します。あるブランチの履歴の一部でない場合、オブジェクトは到達不能です。実際にはもう少し複雑です:

stash は reflog を使用して実装されます (つまり、ブランチやタグではありません)。つまり、ガベージ コレクションの対象となります。

git gc他にもいくつかのことを行いますが、ここでは関係がなく、危険ではありません。

2 週間未満の到達不能オブジェクトは削除されないため、--prune=now「今より前に作成された到達不能オブジェクトを削除する」という意味を使用します。

reflog を介してオブジェクトに到達することもできます。ブランチはプロジェクトの履歴を記録しますが、reflog はこれらのブランチの履歴を記録します。修正、リセットなどを行うと、コミットはブランチ履歴から削除されますが、間違いを犯したことに気付いた場合に備えて、git はそれらを保持します。reflog は、ブランチ (または HEAD) で実行された破壊的な (およびその他の) 操作を見つける便利な方法であり、破壊的な操作を簡単に元に戻すことができます。

したがって、ブランチから到達できないすべてのものを実際に削除するには、reflog も削除する必要があります。--allこれは、 reflogを期限切れにすることによって行います。ここでも git はユーザーを保護するために reflog を少し保持しているため、そうしないように再度指示する必要があります--expire-unreachable=now

私は主に reflog を使用して破壊的な操作から回復するので、通常は--expire=now代わりに reflog を完全に消去します。

于 2010-12-24T22:42:02.670 に答える
81

出力なし、ぶら下がっているものはありません(そうですか?)

reflog から参照されるコミットは到達可能と見なされることに注意してください。

そのコミットの状態は正確には何ですか?同様の状態のすべてのコミットを一覧表示するにはどうすればよいですか

それらをあなたに見せるよう--no-reflogsに説得するために渡します。git fsck

そのようなコミットを削除するにはどうすればよいですか?

reflog エントリの有効期限が切れると、それらのオブジェクトも によってクリーンアップされgit gcます。

gc.pruneexpire有効期限は、、、gc.reflogexpireおよび設定によって規制されgc.reflogexpireunreachableます。参照。git help config.

デフォルトはすべて非常に合理的です。

于 2010-09-22T00:57:32.493 に答える
14
git branch --contains 793db7f272ba4bbdd1e32f14410a52a412667042

たぶん

git branch -a --contains 793db7f272ba4bbdd1e32f14410a52a412667042

リモートからのブランチについてもレポートします

于 2011-03-13T01:36:42.310 に答える
8

同様の問題がありました。を実行git branch --contains <commit>しましたが、質問と同じように出力が返されませんでした。

でも走った後も

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

私のコミットは、を使用してまだアクセスできgit show <commit>ました。これは、切り離された/ぶら下がった「ブランチ」のコミットの 1 つがタグ付けされたためです。タグを削除し、上記のコマンドを再度実行したところ、成功しました。git show <commit>返されましたfatal: bad object <commit>-まさに私が必要としていたものです。うまくいけば、これは私と同じように立ち往生している他の誰かを助けるでしょう.

于 2016-05-19T23:28:45.960 に答える
2

git gc --prune=<date>デフォルトでは、2 週間以上前のオブジェクトを削除します。より新しい日付を設定できます。ただし、一般に、ゆるいオブジェクトを作成する git コマンドは git gc --auto を実行します (これは、ゆるいオブジェクトの数が構成変数 gc.auto の値を超えると、それらを削除します)。

これらのコミットを削除してもよろしいですか? gc.auto のデフォルト設定では、ルーズ オブジェクトが不当な量のメモリを占有しないことが保証されます。ルーズ オブジェクトを一定時間保存することは、一般的には良い考えです。そうすれば、明日、削除されたブランチに必要なコミットが含まれていることに気付いた場合、それを回復できます。

于 2010-09-21T23:45:58.387 に答える
0

隠し場所が本当に「存在しない」隠し場所であり、タグではない
git fsck --full
場合、役立つ場合があります。他の解決策がなかったとき、それは私にとってはうまくいきました。

( Git: 壊れたスタッシュを削除すると、このスレッドよりも私の問題がより正確に説明されます)

于 2021-08-14T22:04:01.537 に答える