Saya punya repositori Git dengan banyak commit yang tidak di bawah cabang tertentu, saya bisa git show
melakukannya, tetapi ketika saya mencoba membuat daftar cabang yang mengandungnya, ia tidak melaporkan apa-apa.
Saya pikir ini adalah masalah komit / pohon yang menjuntai (sebagai akibat dari -D cabang), jadi saya memangkas repo, tetapi saya masih melihat perilaku yang sama setelah itu:
$ git fetch origin
$ git fsck --unreachable
$ git fsck
Tidak ada output, tidak ada yang menggantung (kan?). Tetapi komit ada
$ git show 793db7f272ba4bbdd1e32f14410a52a412667042
commit 793db7f272ba4bbdd1e32f14410a52a412667042
Author: ...
dan itu tidak dapat dijangkau melalui cabang apa pun seperti
$ git branch --contains 793db7f272ba4bbdd1e32f14410a52a412667042
tidak memberikan hasil.
Apa sebenarnya keadaan komitmen itu? Bagaimana saya bisa membuat daftar semua komitmen dalam kondisi yang sama? Bagaimana saya bisa menghapus komit seperti itu?
git
branch
git-dangling
Samer Buna
sumber
sumber
Jawaban:
Perhatikan bahwa komit yang dirujuk dari reflog Anda dianggap dapat dijangkau.
Lewati
--no-reflogs
untuk meyakinkangit fsck
untuk menunjukkannya kepada Anda.Setelah entri reflog Anda kedaluwarsa, benda-benda itu juga akan dibersihkan oleh
git gc
.Kadaluwarsa diatur oleh
gc.pruneexpire
,gc.reflogexpire
dangc.reflogexpireunreachable
pengaturan. Lihgit help config
.Defaultnya semua cukup masuk akal.
sumber
git help glossary
mendefinisikannya seperti itu ... sedangkan definisi untuk "dapat dijangkau" tidak dipersempit seperti itu, sehingga mereka bertentangan. Lucu - jadi apa yang saya katakan sebenarnya konsisten dengan kebingungan dalamgitglossary
... Bukan konsep yang membingungkan, hanya terminologi. Intinya adalah bahwa "menggantung" komit adalah hal-hal yang tidak ada hubungannya. Apakah itu membantu jika saya mengatakan “reflogs untuk sebaliknya komit unreachable” ...?master
, Anda melakukannyagit commit
, dan mendapatkan komit000001
. Maka Anda lakukangit commit --amend
, yang memberi Anda komit000002
. Tidak ada tag atau cabang yang menunjuk000001
lagi, dan Anda tidak dapat melihatnya di log Anda tanpa--reflog
opsi, tetapi jika Anda mau, Anda masih bisa mendapatkannya dengangit checkout 000001
. Sekarang pertanyaannya adalah, Apakah000001
sebuah menjuntai komit, atau tidak terjangkau komit, atau tidak, atau keduanya?Untuk menghapus semua komitmen yang menjuntai dan yang dapat dijangkau dari reflog lakukan ini:
Tetapi yakinlah bahwa inilah yang Anda inginkan. Saya sarankan Anda membaca halaman manual tetapi inilah intinya:
git gc
menghapus objek yang tidak terjangkau (komit, pohon, gumpalan (file)). Objek tidak dapat dijangkau jika bukan bagian dari sejarah cabang tertentu. Sebenarnya ini sedikit lebih rumit:git gc
melakukan beberapa hal lain tetapi mereka tidak relevan di sini dan tidak berbahaya.Objek yang tidak terjangkau yang lebih muda dari dua minggu tidak dihapus sehingga kami menggunakan
--prune=now
yang berarti "menghapus objek yang tidak terjangkau yang dibuat sebelum sekarang".Objek juga dapat dicapai melalui reflog. Sementara cabang mencatat sejarah beberapa proyek, reflog mencatat sejarah cabang-cabang ini. Jika Anda mengubah, setel ulang dll. Komit dihapus dari riwayat cabang tetapi git menyimpannya jika Anda menyadari bahwa Anda telah membuat kesalahan. Reflog adalah cara yang mudah untuk mengetahui operasi destruktif (dan lainnya) apa yang dilakukan pada cabang (atau KEPALA), sehingga memudahkan untuk membatalkan operasi yang merusak.
Jadi kita juga harus menghapus reflog untuk benar-benar menghapus semua yang tidak dapat dijangkau dari cabang. Kami melakukannya dengan berakhirnya
--all
reflog. Sekali lagi git menyimpan sedikit dari reflogs untuk melindungi pengguna jadi kami lagi harus mengatakan tidak untuk melakukannya:--expire-unreachable=now
.Karena saya terutama menggunakan reflog untuk memulihkan dari operasi destruktif yang biasanya saya gunakan
--expire=now
, yang mengisi reflog sepenuhnya.sumber
git reflog expire --expire-unreachable=now --all
menjatuhkan semua simpanan Anda!Saya memiliki masalah yang sama, masih setelah mengikuti semua saran di utas ini:
Jika bukan reflog dan bukan cabang, ... itu pasti sebuah tag !
Saya menghapus tag dengan
git tag -d <tagname>
dan membersihkan pembersihan, dan komitmen lama hilang.sumber
mungkin hanya perlu
untuk juga melaporkan cabang dari remote
sumber
git push -d origin next
tidak membantu.git fetch --prune
berhasil. tetapi dalam semua jawaban, saya kehilangan tanda centang untuk tag yang mereferensikan komit ini. Saya masih tidak tahu cara memeriksa tag dengan komit (saya menghapus semua).git fsck --unreachable
itu sebenarnya berkomunikasi melalui jaringan dengan remote untuk mengetahui komit mana yang dapat dijangkau?git fsck --unreachable
tidak perlu berkomunikasi melalui jaringan dengan remote untuk mengetahui cabang-cabang mana yang berisi komit. Info cabang jarak jauh disimpan secara lokal, di bawah misalnya.git/refs/remotes/origin
(atau dipacked-refs
).Saya punya masalah serupa. Saya berlari
git branch --contains <commit>
, dan tidak ada output seperti pada pertanyaan.Tetapi bahkan setelah berlari
komit saya masih dapat diakses menggunakan
git show <commit>
. Ini karena salah satu komit di "cabangnya" yang terlepas / menjuntai telah ditandai. Saya menghapus tag, menjalankan perintah di atas lagi, dan saya emas.git show <commit>
kembalifatal: bad object <commit>
- persis apa yang saya butuhkan. Semoga ini bisa membantu orang lain yang sama macetnya dengan saya.sumber
Saya tidak sengaja mengenai situasi yang sama dan menemukan simpanan saya berisi referensi ke komit yang tidak dapat dijangkau, dan dengan demikian komit yang dianggap tidak dapat dijangkau itu dapat dicapai dari simpanan.
Inilah yang saya lakukan untuk membuatnya benar-benar tidak dapat dijangkau.
sumber
git gc --prune=<date>
default untuk memangkas objek yang lebih tua dari dua minggu lalu. Anda dapat menetapkan tanggal yang lebih baru. Tetapi, perintah git yang membuat objek longgar umumnya akan menjalankan git gc --auto (yang memangkas objek yang longgar jika jumlahnya melebihi nilai variabel konfigurasi gc.auto).Apakah Anda yakin ingin menghapus komit ini? Pengaturan default gc.auto akan memastikan bahwa objek yang longgar tidak memakan jumlah memori yang tidak masuk akal, dan menyimpan objek yang longgar untuk jangka waktu tertentu umumnya merupakan ide yang bagus. Dengan begitu, jika Anda menyadari besok bahwa cabang Anda yang dihapus berisi komit yang Anda butuhkan, Anda dapat memulihkannya.
sumber