Apa perbedaan antara git reflog dan log?

158

Halaman manual mengatakan bahwa log menunjukkan log komit dan reflog mengelola informasi reflog. Apa sebenarnya informasi reflog dan apa yang tidak dimiliki log? Log tampaknya jauh lebih terperinci.

Noich
sumber

Jawaban:

221

git logmenunjukkan KEPALA saat ini dan leluhurnya. Yaitu, ia mencetak titik HEAD komit ke, lalu induknya, induknya, dan sebagainya. Itu melintasi kembali melalui keturunan repo, dengan secara rekursif mencari orang tua masing-masing komit.

(Dalam praktiknya, beberapa komit memiliki lebih dari satu orangtua. Untuk melihat log yang lebih representatif, gunakan perintah seperti git log --oneline --graph --decorate.)

git reflogsama sekali tidak melintasi nenek moyang HEAD. Reflog adalah daftar komit yang diatur oleh HEAD: itu membatalkan sejarah repo Anda. Reflog bukan bagian dari repo itu sendiri (itu disimpan secara terpisah untuk komit itu sendiri) dan tidak termasuk dalam dorongan, pengambilan atau klon; ini murni lokal.

Selain itu: memahami reflog berarti Anda tidak dapat benar-benar kehilangan data dari repo setelah dilakukan. Jika Anda secara tidak sengaja mengatur ulang ke komit yang lebih lama, atau melakukan rebase yang salah, atau operasi lain yang secara visual "menghilangkan" komit, Anda dapat menggunakan reflog untuk melihat di mana Anda sebelumnya dan git reset --hardkembali ke ref itu untuk mengembalikan keadaan Anda sebelumnya. Ingat, referensi tidak hanya menunjukkan komitmen tetapi seluruh sejarah di baliknya.

ben_h
sumber
26
Peringatan: Anda kadang-kadang BISA kehilangan data karena entri reflog tidak bertahan selamanya - mereka dibersihkan pada kondisi tertentu. Lihat jawaban ini dan dokumen untuk git-reflog dan git-gc . Secara umum, jika operasi destruktif tidak lebih dari 2 minggu yang lalu, Anda kemungkinan besar aman.
mcmlxxxvi
@ mcmlxxxvi Saya memiliki dua folder lokal untuk repo yang sama, dapatkah saya menggabungkan reflog untuk dua folder?
Tmx
@ TMX, saya tidak begitu mengerti kasus Anda - apa maksud Anda dengan dua folder lokal untuk repo yang sama ? Jika Anda memiliki dua klon dari repo yang sama, yang terbaru, dan Anda ingin "menggabungkan" riwayat edit mereka, .git/logs/refs/<branch>entri memiliki format <old_rev> <new_rev> [...] <timestamp> [...]. Anda dapat mencoba menggabungkan dan mengurutkan berdasarkan cap waktu. Namun, beberapa baris new_revmungkin tidak cocok dengan yang berikutnya old_rev, dalam hal ini saya curiga reflog tidak valid. Anda kemudian dapat mencoba memasukkan entri palsu untuk "memperbaiki" urutan, tetapi tampaknya terlalu merepotkan bagi saya.
mcmlxxxvi
62
  • git log menunjukkan log komit yang dapat diakses dari referensi (kepala, tag, remote)
  • git reflogadalah catatan dari semua komitmen yang direferensikan dalam repo Anda kapan saja.

Itu sebabnya git reflog( rekaman lokal yang dipangkas setelah 90 hari secara default) digunakan ketika Anda melakukan operasi "destruktif" (seperti menghapus cabang), untuk mendapatkan kembali SHA1 yang direferensikan oleh cabang itu.
Lihat git config:

gc.reflogexpire
gc.<pattern>.reflogexpire

git reflogkedaluwarsa menghapus entri reflog yang lebih lama dari waktu ini; default ke 90 hari.
Dengan " <pattern>" (mis. " refs/stash") Di tengah pengaturan hanya berlaku untuk referensi yang cocok dengan <pattern>.

Internet aman

git reflogsering disebut sebagai " jaring pengaman Anda "

Jika ada masalah, saran umum, ketika git log tidak menunjukkan kepada Anda apa yang Anda cari, adalah:

" Tetap tenang dan gunakangit reflog "

tetap tenang

Sekali lagi, reflog adalah rekaman lokal SHA1 Anda.
Berbeda dengan git log: jika Anda mendorong repo Anda ke repo hulu , Anda akan melihat hal yang sama git log, tetapi tidak harus sama git reflog.

VONC
sumber
14

Berikut penjelasan reflogdari buku Pro Git :

Salah satu hal yang dilakukan Git di latar belakang saat Anda sedang pergi bekerja adalah menyimpan reflog - log di mana HEAD dan referensi cabang Anda berada selama beberapa bulan terakhir.

Anda dapat melihat reflog Anda dengan menggunakan git reflog:

$ git reflog
734713b... HEAD@{0}: commit: fixed refs handling, added gc auto, updated
d921970... HEAD@{1}: merge phedders/rdocs: Merge made by recursive.
1c002dd... HEAD@{2}: commit: added some blame and merge stuff
1c36188... HEAD@{3}: rebase -i (squash): updating HEAD
95df984... HEAD@{4}: commit: # This is a combination of two commits.
1c36188... HEAD@{5}: rebase -i (squash): updating HEAD
7e05da5... HEAD@{6}: rebase -i (pick): updating HEAD

Setiap kali tip cabang Anda diperbarui dengan alasan apa pun, Git menyimpan informasi itu untuk Anda dalam sejarah sementara ini. Dan Anda dapat menentukan komitmen yang lebih lama dengan data ini, juga.

The reflogperintah juga dapat digunakan untuk menghapus entri atau berakhir entri dari reflog yang terlalu tua. Dari dokumentasi Linux Kernel Git resmi untukreflog :

Subperintah expire ini digunakan untuk memangkas entri reflog yang lebih lama.

Untuk menghapus satu entri dari reflog, gunakan sub perintah deletedan tentukan entri yang tepat (mis git reflog delete master@{2}.).

Komunitas
sumber
Tetapi bukankah ini git logmemberi Anda informasi yang sama? Maaf jika tampaknya sudah jelas, saya sangat baru di GIT dan ingin mendapatkan beberapa dasar sebelum OMG pertama saya.
Noich
2
Git log adalah catatan dari komitmen Anda . Reflog, seperti yang dinyatakan oleh buku Pro Git, adalah catatan referensi Anda (pada dasarnya, pointer dan pointer cabang Anda HEAD), dan yang menunjukkan komitmen mereka. Apakah itu masuk akal? Di samping catatan, logjuga dapat menunjukkan Anda informasi reflog, tetapi Anda harus melewati bendera opsi khusus sebagai argumen untuk itu --walk-reflogs,.
3
Juga, karena Anda seorang pemula Git, saya sangat menyarankan Anda membaca buku Pro Git, itulah bagaimana saya belajar sebagian besar dari apa yang saya pelajari tentang Git. Saya merekomendasikan bab 1-3 dan 6-6.5. Saya juga sangat menyarankan agar Anda belajar cara rebase baik secara interaktif maupun non-interaktif.
8

Saya ingin tahu tentang ini juga dan hanya ingin menguraikan dan meringkas sedikit:

  1. git logmemperlihatkan riwayat semua komitmen Anda untuk cabang tempat Anda berada. Periksa cabang yang berbeda dan Anda akan melihat riwayat komit yang berbeda. Jika Anda ingin melihat Anda komit riwayat untuk semua cabang, ketik git log --all.

  2. git reflogmenunjukkan catatan referensi Anda seperti kata Cupcake. Ada entri setiap kali komit atau checkout dilakukan. Coba bolak-balik antara dua cabang beberapa kali menggunakan git checkoutdan menjalankan git reflogsetelah setiap checkout. Anda akan melihat entri teratas diperbarui setiap kali sebagai entri "checkout". Anda tidak melihat entri jenis ini di git log.

Referensi: http://www.lornajane.net/posts/2014/git-log-all-branches

mitch
sumber
1

Saya suka menganggap perbedaan antara git log dan reflog sebagai perbedaan antara catatan pribadi dan catatan publik.

Pribadi vs publik

Dengan reflog git, ia melacak semua yang telah Anda lakukan secara lokal. Apakah Anda berkomitmen? Reflog melacaknya. Apakah Anda melakukan hard reset? Reflog melacaknya. Apakah Anda mengubah komit ? Reflog melacaknya. Semua yang Anda lakukan secara lokal, ada entri untuk itu di reflog.

Ini tidak berlaku untuk log. Jika Anda mengubah komit, log hanya menunjukkan komit baru. Jika Anda melakukan reset dan melewatkan beberapa commit dalam riwayat Anda, commit yang Anda lewatkan tidak akan muncul di log. Saat Anda mendorong perubahan ke pengembang lain atau ke GitHub atau semacamnya, hanya konten yang dilacak dalam log yang akan muncul. Untuk pengembang lain, itu akan terlihat seperti pengaturan ulang tidak pernah terjadi atau perubahan tidak pernah terjadi.

Log dipoles. Reflog adalah singkat.

Jadi ya, saya suka analogi 'privat vs publik'. Atau mungkin log vs reflog yang lebih baik analogi adalah 'dipoles vs singkat.' Reflog menunjukkan semua cobaan dan kesalahan Anda. Log hanya menunjukkan versi bersih dan terpoles dari riwayat pekerjaan Anda.

Lihatlah gambar ini untuk menekankan poinnya. Sejumlah perubahan dan pengaturan ulang telah terjadi sejak repositori diinisialisasi. Reflog menunjukkan semuanya. Namun perintah log membuatnya seolah-olah hanya ada satu komit terhadap repo:

Log dipoles.  Reflog adalah singkat.

Kembali ke ide 'jaring pengaman'

Juga, karena reflog melacak hal-hal yang Anda ubah dan melakukan reset , memungkinkan Anda untuk kembali dan menemukan komitmen karena itu akan memberi Anda id komitmen. Dengan asumsi repositori Anda belum dibersihkan dari komit lama, yang memungkinkan Anda untuk menghidupkan kembali item yang tidak lagi terlihat di log. Begitulah reflog kadang-kadang berakhir menyelamatkan kulit seseorang ketika mereka perlu mendapatkan kembali sesuatu yang mereka pikir mereka kehilangan secara tidak sengaja.

Cameron McKenzie
sumber
-6

Sebenarnya, reflog adalah alias untuk

 git log -g --abbrev-commit --pretty=oneline

jadi jawabannya harus: ini adalah kasus khusus.

pengguna10028634
sumber
9
Di git log, -gadalah bentuk pendek untuk --walk-reflogs. Jadi, itu tidak menjelaskan apa pun.
Adrian W