Dapatkan daftar semua komitmen git, termasuk yang 'hilang'

139

Katakanlah saya memiliki grafik seperti ini:

A---B---C---D (master)
     \
      \-E---F (HEAD)

Jika saya melakukannya git log --all --oneline, saya akan mendapatkan semua enam komitmen saya.

Tetapi jika grafiknya adalah

A---B---C---D (master, HEAD)
     \
      \-E---F

Saya tidak akan melihat E dan F. Bisakah saya meminta git untuk memberi tahu saya semua komitmen, termasuk yang ada di cabang yang tidak disebutkan namanya?

Terima kasih

Amadan
sumber

Jawaban:

63

Tidak terlalu mudah - jika Anda kehilangan pointer ke ujung cabang, itu seperti menemukan jarum di tumpukan jerami. Anda dapat menemukan semua komit yang tampaknya tidak direferensikan lagi- git fsck --unreachableakan melakukan ini untuk Anda- tetapi itu akan mencakup komit yang Anda buang setelah git commit --amend, komit lama pada cabang yang Anda rebase dll. Jadi, lihat semua komit ini sekaligus kemungkinan besar terlalu banyak informasi yang harus dilalui.

Jadi jawaban yang kurang ajar adalah, jangan lupa hal-hal yang Anda minati. Lebih serius lagi, reflog akan menyimpan referensi ke semua komitmen yang telah Anda gunakan selama 60 hari terakhir atau lebih secara default. Lebih penting lagi, mereka akan memberikan beberapa konteks tentang apa yang mereka komit yang .

araqnid
sumber
7
+1: Sama sekali tidak ada perbedaan antara komit yang sengaja menjadi yatim piatu oleh commit --amendatau rebasedan yang tidak sengaja menjadi yatim piatu dengan bekerja dengan KEPALA lepas, katakanlah.
Cascabel
3
memang. mungkin cara termudah untuk pulih dari situasi itu adalah dengan melihat reflog untuk HEAD itu sendiri.
araqnid
@ Jeffromi: Hebat menunjukkan tentang git commit --amenddll meninggalkan jalan buntu, kehilangan komitmen. Saya melakukan rebasing dan yang lainnya dan berakhir dengan beberapa komit yang tidak dapat dijangkau dari cabang mana pun, dan merasa agak kotor meninggalkan mereka di repo. Sekarang pikiran itu tidak cukup mengganggu lagi. :)
Emil Lundberg
2
@araqnid Saya mendapatkan acar yang sama dengan poster asli dan saran Anda untuk melihat reflog adalah hal yang harus dilakukan.
Ignazio
7
Saya setuju dengan jawaban ini, tetapi dalam kasus di mana seseorang perlu melihat semua komitmen, termasuk yang yatim piatu baik disengaja atau tidak, git fsck --unreachabletidak memberikan itu. Saya baru saja mencobanya. Pendekatan yang lebih baik adalah --reflogpilihan untuk git log, seperti yang dijawab kenorb . Apa yang sangat baik tentang ini adalah bahwa dikombinasikan dengan --graph, Anda mendapatkan konteks visual yang mudah diurai, seperti yang diilustrasikan dalam pertanyaan asli. Misalnya, coba:git log --graph --all --oneline --reflog
Inigo
111

Mencoba:

git log --reflog

yang mencantumkan semua komit git dengan berpura-pura bahwa semua objek yang disebutkan oleh reflogs ( git reflog) terdaftar pada baris perintah sebagai <commit>.

kenorb
sumber
1
Inilah yang saya cari - fungsi argumen --reflog.
Anomaly
3
Btw, gitk juga mendukung itu: gitk --reflog.
ald.li
50

Ketika saya mengatasi masalah ini saya menggunakan perintah berikut:

git reflog |  awk '{ print $1 }' | xargs gitk

Ini memungkinkan saya memvisualisasikan komitmen baru yang telah menjadi tanpa kepala.

Saya sudah membungkus ini dengan penolong naskah yang disebut ~/bin/git-reflog-gitk.

Kieran
sumber
1
Ini hanya MENYIMPAN saya waktu besar ... Terima kasih!
Bret Royster
ini luar biasa! Terima kasih! itu benar-benar memvisualisasikan bagian-bagian penting dari pohon.
Mladen B.
Hanya tip: Ini hanya akan berfungsi untuk pekerjaan lokal Anda sebagai catatan reflog when the tips of branches and other references were updated in the *local repository*. Anda mungkin ingin menggunakan git log --reflogjika Anda ingin melakukan ini untuk perubahan referensi non-lokal
Krishna Gupta
29

Apa yang menyelamatkan hidup saya adalah perintah berikut:

git reflog

Di sana Anda menemukan layar dengan komit riwayat yang dilakukan untuk git seperti ini:

masukkan deskripsi gambar di sini

Pada titik ini, Anda hanya perlu menemukan HEAD@{X}yang Anda butuhkan, membuat cabang sementara dan pindah ke sana seperti ini:

git checkout -b temp_branch HEAD@{X}

Dengan begitu Anda akan memiliki cabang sementara dengan komit Anda yang hilang tanpa rebasing atau menghancurkan lebih banyak gudang git Anda.

Semoga ini membantu...

Sonhja
sumber
26

Seperti @Kieran's Answer, tetapi untuk konsol: git log --oneline --all --graph --decorate $(git reflog | awk '{print $1}')

Florian Fida
sumber
Apakah Anda perlu memasukkan bagian terakhir: $ (git reflog | awk '{print $ 1}')? Apa fungsinya? Setelah mencoba solusi Anda, sepertinya itu menghasilkan output yang sama bahkan tanpa bagian terakhir itu.
wmock
Jika Anda memindahkan pointer cabang Anda dan meninggalkan beberapa komit tanpa referensi (seperti yang dilakukan OP), mereka tidak akan muncul lagi git log --all. Contoh cepat: Setelah git reset --hard @^komit @ @ 0 0 komit Anda hanya akan berada di reflog, dan karena git reflogtidak mendukung --graphAnda harus melewati komit git log --graphuntuk mendapatkan representasi visual.
Florian Fida
5
Anda dapat menggunakan --reflogsebagai gantinya $(git reflog | awk '{print $1}')
Sild
Saya dibandingkan git log --oneline --all --graph --decorate $(git reflog | awk '{print $1}')dengan git log --oneline --all --graph --decorate --reflog, mereka hampir identik kecuali --reflog termasuk rincian seperti entri WIP.
Script Wolf
@FlorianFida, bukannya reflogmengapa tidak digunakan log --reflogsebagai gantinya?
Pacerier
9

Bagaimana saya mengatasi masalah ini? Gunakan git fsckdan masuk!

Pertama buat file yang mengandung komit dan gumpalan yang hilang (tidak dapat dijangkau). (CATATAN: jika Anda melakukan sesuatu seperti git gcitu maka akan mengumpulkan sampah semua komitmen mereka dan Anda tidak akan menemukannya di sini!)

$git fsck --lost-found > lost_found.commits

Itu memberi Anda file seperti ini:

menjuntai berkomitmen dec2c5e72a81ef06963397a49c4b068540fc0dc3
menjuntai gumpalan f8c2579e6cbfe022f08345fa7553feb08d60a975
menjuntai gumpalan 0eb3e86dc112332ceadf9bc826c49bd371acc194
menjuntai gumpalan 11cbd8eba79e01f4fd7f496b1750953146a09502
menjuntai berkomitmen 18733e44097d2c7a800650cea442febc5344f9b3
menggantung gumpalan 1e53a5cdb3ecdde27081ec6e8b31e4070106ee05

Anda kemudian dapat membuka file ini dengan editor teks favorit Anda untuk menyalin hash komit / blog dari sana. (* batuk * vim macro sangat cocok untuk ini * batuk *)

Sekarang Anda dapat masuk kembali dari komit ini dengan sesuatu seperti git log --oneline <commit hash>. Atau, gitk, tig, atau penampil git lainnya harus berfungsi.

Dalam kasus Anda jika Anda menemukan hash untuk melakukan F log akan menunjukkan kepada Anda sesuatu seperti ini,

A---B---E---F

Cepat dan mudah! Sekarang Anda dapat menemukan konteks di balik semua komitmen yang menggantung itu.

PS Ya, saya tahu, posting terlambat, tapi oh well, seseorang mungkin menemukannya di sini dan merasa berguna. (Kemungkinan besar saya dalam 6 bulan ketika saya google ini lagi)

bsimmons
sumber
5

Saya beruntung dapat memulihkan komit dengan melihat reflog yang terletak di .git/logs/HEAD

Saya kemudian harus scoll ke ujung file , dan saya menemukan komit saya baru saja kehilangan.

Script Game
sumber
Inilah yang baru saja saya lakukan ketika saya mengacaukan sesuatu. Mencoba berkomitmen untuk menguasai dan Stash menolak ketika aku mendorong. Saya mereset --hard, lalu menyadari kesalahan saya. Komit ada di reflog, jadi saya memeriksanya, membuat cabang dari itu, lalu mendorongnya. Semuanya berhasil pada akhirnya.
David
5

Kami akan git logkadang-kadang tidak baik untuk mendapatkan semua detil komit, sehingga untuk melihat ini ...

Untuk Mac: Ikutilah proyek git Anda dan ketik:

$ nano .git/logs/HEAD

untuk melihat Anda semua melakukan itu, atau:

$ gedit .git/logs/HEAD

untuk melihat Anda semua melakukan itu,

maka Anda dapat mengedit di salah satu browser favorit Anda.

Vinod Joshi
sumber
3

@bimmons

git fsck --lost-found | grep commit

Kemudian buat cabang untuk masing-masing:

$ git fsck --lost-found | grep commit
Checking object directories: 100% (256/256), done.
dangling commit 2806a32af04d1bbd7803fb899071fcf247a2b9b0
dangling commit 6d0e49efd0c1a4b5bea1235c6286f0b64c4c8de1
dangling commit 91ca9b2482a96b20dc31d2af4818d69606a229d4

$ git branch  branch_2806a3 2806a3
$ git branch  branch_6d0e49 6d0e49
$ git branch  branch_91ca9b 91ca9b

Sekarang banyak alat akan menunjukkan kepada Anda visualisasi grafis dari komitmen yang hilang itu.

yakoda
sumber
2

Jika Anda menggunakan Git Extensions GUI, ia dapat menunjukkan kepada Anda visualisasi grafis dari komitmen menjuntai jika Anda memeriksa "Lihat -> Tampilkan referensi reflog". Ini akan menunjukkan komit menggantung di pohon, seperti semua yang direferensikan lainnya. Dengan cara ini lebih mudah untuk menemukan apa yang Anda cari.

Lihat gambar ini untuk demonstrasi. Komit C2, C3, C4, dan C5 pada gambar menjuntai tetapi masih terlihat.

Zdovc
sumber
2
git log --reflog

menyelamatkan saya! Saya kehilangan KEPALA saat saya bergabung dan tidak dapat menemukan daftar komitmen saya! Tidak ditampilkan di pohon sumber tetapi git log --reflogtunjukkan semua komit lokal saya sebelumnya

Sultanmyrza Kasymbekov
sumber