Jelajahi komit yatim piatu di Git

102

Repositori git saya entah bagaimana menjadi miring - Saya memuat msysgit pagi ini dan alih-alih nama cabang ditampilkan setelah direktori saat ini, ia mengatakan "((ref: re ...))", 'status git' melaporkan semuanya sebagai file baru, 'git log' dan 'git reflog' beri tahu saya "fatal: revisi default buruk 'HEAD'", dan seterusnya.

Melakukan 'git reflog --all' atau 'gitk --all' menunjukkan kepada saya bahwa sisa repositori masih utuh, tetapi sepertinya cabang yang saya kerjakan baru saja menghilang, yang menjelaskan mengapa HEAD tampaknya tidak ada / menunjuk ke apapun.

Saya tahu git menyimpan semua jenis gumpalan informasi, dan saya berasumsi bahwa komit saya entah bagaimana menjadi yatim piatu, jadi apakah ada beberapa perintah yang akan menunjukkan kepada saya komit tersebut sehingga saya dapat mengatur ulang HEAD ke mereka?

EDIT: Ya ampun. Saya menemukan 'git fsck', dan 'git fsck --full' melaporkan "fatal: object 03ca4 ... rusak". Apa yang bisa saya lakukan tentang itu?

EDIT: Oh sayang oh sayang. Saya memeriksa cabang lain, lalu mencoba membuat ulang cabang asli dengan nama yang sama menggunakan 'git checkout -b lostbranchname', dan git mengatakan "kesalahan: tidak dapat menyelesaikan referensi referensi / kepala / nama cabang yang hilang: Tidak ada kesalahan, fatal: Gagal untuk mengunci ref untuk pembaruan: Tidak ada kesalahan ". 'Tidak ada kesalahan' pasti merupakan kesalahan yang sangat parah. Jadi sepertinya masih berkeliaran, tapi tidak bisa digunakan dan tidak bisa dibunuh.

EDIT: Super duper ya ampun. Saya telah melakukan banyak pembongkaran dan pengemasan ulang dan penggantian hal-hal seperti yang disarankan di sini: Bagaimana memulihkan objek Git yang rusak karena kegagalan hard disk? , tapi sekarang saya mendapatkan hash lain yang dilaporkan korup, untuk sesuatu yang tidak berbahaya seperti 'status git'. Saya pikir semuanya disemprot. Git menyenangkan dan semuanya, tapi aku seharusnya tidak berurusan dengan hal semacam ini.

Ben Hymers
sumber
Mengenai git checkout -b lostbranchname- jika Anda hanya peduli tentang nama cabang (bukan isinya), Anda dapat menghapus (atau mengganti nama) secara manual .git/refs/heads/lostbranchname- mudah-mudahan akan berhasil.
Antony Hatchkins
1
Dan Anda tidak memiliki upstream tempat Anda mendorong folder git ini?
Lakshman Prasad
1
Sayangnya tidak, ini sebenarnya semacam repositori pengganti untuk sistem kontrol sumber yang lebih rendah, saya hanya menggunakannya secara lokal untuk mendapatkan semua fitur dan kenyamanan git tanpa kerumitan sistem lain. Tapi setidaknya sistem lain tidak merusak dirinya sendiri secara acak. Namun, itu berarti semua yang hilang adalah perubahan saya sejak terakhir kali saya check in ke sistem lain, yang sudah saya pulihkan. Saatnya memulai repositori baru!
Ben Hymers
7
Saya ragu untuk mengatakan bahwa git membuat Anda "berurusan dengan hal semacam ini" atau merusak dirinya sendiri. Tidak ada selain cadangan yang dapat sepenuhnya stabil terhadap kehilangan data.
Cascabel
1
Saya benar-benar tahu, saya (secara alami) sedikit jengkel karena saya kehilangan sejarah indah saya. Ini bukan salah git, sistem lain mana pun akan berperilaku seperti kesalahan sistem file yang diberikan.
Ben Hymers

Jawaban:

135

Daripada membiarkan ini terbuka, saya pikir saya akan memberikan jawaban untuk pertanyaan saya sendiri. Menggunakan git reflog --alladalah cara yang baik untuk menelusuri komit yatim piatu - dan menggunakan hash SHA1 dari situ Anda dapat merekonstruksi riwayat.

Namun dalam kasus saya, repositori rusak jadi ini tidak membantu; git fsckdapat membantu Anda menemukan dan terkadang memperbaiki kesalahan dalam repositori itu sendiri.

Ben Hymers
sumber
3
Terima kasih. Ini adalah satu-satunya tempat saya menemukan informasi ini ketika mencoba menarik permintaan tarik yatim piatu di github. Memecahkan masalah saya.
SystemParadox
6
seandainya ada yang menginginkan semua di gitk: [alias] orphank = !gitk --all --date-order ``git reflog | cut -c1-7``&(edit: bayangkan double backticks di mana satu - escaping tampaknya tidak berfungsi di sini)
mbx
1
Tip luar biasa @mbx! Sangat berguna untuk dapat melihat hubungan antara yatim piatu secara grafis!
Ben Hymers
@BenHymers Akan keren, jika kita bisa mendapatkan garis putus-putus untuk hubungan komit seperti "rebase / squash" juga. Saya belum menemukan cara untuk melakukan itu.
mbx
Saya tidak tahu tentang reflog ketika saya menulis jawaban di atas. Ini adalah alat yang sangat berguna!
Jamey Hicks
17

Dengan git 2.9.x / 2.10 (Q3 2016), Anda tidak perlu menggunakan git reflog --alllagi, git reflogsudah cukup.

Lihat commit 71abeb7 (03 Jun 2016) oleh SZEDER Gábor ( szeder) .
(Digabung oleh Junio ​​C Hamano - gitster- di commit 7949837 , 06 Jul 2016)

reflog: lanjutkan berjalan di reflogroot commit sebelumnya

Jika repositori berisi lebih dari satu root commit, maka reflog HEAD-nya mungkin berisi beberapa "peristiwa pembuatan", yaitu entri yang nilai "from" -nya adalah null sha1.
Mendaftar reflog seperti itu saat ini berhenti sebelum waktunya pada entri pertama, bahkan ketika reflog tersebut masih berisi entri yang lebih lama.
Ini dapat menakut-nakuti pengguna agar berpikir bahwa reflog mereka terpotong setelah ' git checkout --orphan'.

Lanjutkan berjalan reflog melewati peristiwa pembuatan tersebut berdasarkan nilai "baru" entri reflog sebelumnya.

VonC
sumber
4

Salah satu fitur bagus dari git adalah ia mendeteksi korupsi. Namun, tidak termasuk koreksi kesalahan untuk melindungi dari korupsi.

Saya harap Anda telah mendorong konten repositori ini ke komputer lain atau Anda memiliki cadangan untuk memulihkan bagian yang rusak.

Saya tidak memiliki pengalaman dengan git di windows tetapi belum pernah melihat perilaku seperti ini dengan git di Linux atau OS X.

Jamey Hicks
sumber
3

Saya biasanya menemukan git refloghasilnya membingungkan. Jauh lebih mudah bagi saya untuk memahami grafik komit dari git log --graph --reflog. Mengganti format untuk hanya menampilkan ringkasan komit juga dapat membuat grafik lebih mudah diikuti:

$ git alias graph "log --graph --all --format='%h %s%n        (%an, %ar)%d' --abbrev-commit
$ git graph --reflog

* f06abeb Add feature
|         (Sue Dakota, 4 days ago) (HEAD -> master)
* f126291 Fix the build
|         (Oski M. Wizard, 5 days ago) (origin/master, master)
* 3c4fb9c Break the build
|         (Alyssa P. Hacker, 5 days ago)
| * e3124bf fixup! More work for feature
| |         (Sue Dakota, 4 days ago)
| | * 6a7a52e Lost commit
| |/          (Sue Dakota, 4 days ago)
| * 69d9438 More work for feature
| |         (Sue Dakota, 2 weeks ago)
| * 8f69aba Initial work for feature
|/          (Sue Dakota, 3 weeks ago)
* d824fa9 Fix warnings from the linter
|         (Theo Ristudent, 4 weeks ago)
* 9f782b8 Fix tests flakes
|         (Tess Driven, 5 weeks ago)

Dari situ jelas bahwa e3124bfdan 6a7a52emerupakan yatim piatu yang tidak direferensikan, dan ada konteks dari leluhur mereka yang melakukan.

jamesdlin.dll
sumber
Baru saja menyelamatkan saya dari jam kerja yang hilang! secara tidak sengaja menghapus cabang lokal yang memiliki komitmen tidak terdorong di atasnya, git reflog --alltidak menunjukkannya, dengan git log --graph --reflogmereka sangat terlihat ...
Adam.Er8