Reflog telah menyelamatkan kita dua kali, tetapi keduanya dari kesalahan yang kita lakukan sendiri di mesin sendiri. Jaring penyelamat itu punya tiga lubang: reflog tidak pernah meninggalkan mesin ini, entri lamanya dibersihkan git gc, dan semuanya lenyap bila folder .git itu sendiri hilang. Bagian penutup proyek ini menambal ketiganya dengan dua jalur cadangan resmi Git — mirror yang hidup di direktori tetap dan bundle yang bisa dibawa ke mana saja — lalu menguji keduanya dengan pemulihan total. Teori lengkap keduanya dibahas di Backup Repository
; di sini kita menjalankannya sampai tuntas pada buku-resep.
Mirror: Salinan Refs yang Utuh #
Dari dalam buku-resep, buat mirror sebagai folder tetangga:
git clone --mirror . ../buku-resep-backup.gitOutput yang Dihasilkan:
Cloning into bare repository '../buku-resep-backup.git'...
done.Kata kunci --mirror mengubah sifat salinan total: refspec yang dipasang adalah +refs/*:refs/*, sehingga seluruh namespace refs disalin apa adanya — tidak dipindah ke refs/remotes seperti clone biasa — dan hasilnya berbentuk bare tanpa working tree. Sumber clone-nya adalah . (directory ini), yang Git simpan sebagai jalur absolut.
Verifikasi pertama: tanyakan daftar refs pada mirror lewat ls-remote, lalu bandingkan dengan show-ref di sumber:
git ls-remote ../buku-resep-backup.git
git show-refOutput yang Dihasilkan (perintah git ls-remote ../buku-resep-backup.git):
467361217975d92baec94fe475f95e26009223c7 HEAD
467361217975d92baec94fe475f95e26009223c7 refs/heads/mainOutput yang Dihasilkan (perintah git show-ref):
467361217975d92baec94fe475f95e26009223c7 refs/heads/mainHash pada baris refs/heads/main sama persis di kedua sisi — mirror berdiri sejajar dengan sumber. Baris HEAD hanya muncul di ls-remote karena perintah itu juga melaporkan penunjuk default yang akan diambil clone berikutnya. Perbedaan tampilan pemisah (tab pada ls-remote, spasi pada show-ref) murni soal format keluaran — isinya tetap satu benda yang sama.
Memutakhirkan Mirror #
Mirror yang dibuat sekali akan menua — sumbernya terus hidup. Simulasikan pekerjaan baru: catat prosedur backup yang barusan kita rancang ke dalam README.md:
printf '# Buku Resep Warung\n\nKumpulan resep andalan warung — latihan pemulihan riwayat untuk\nCourse Git Proyek 05.\n\n## Isi\n\n- `sample.txt` — seluruh resep dalam satu berkas\n\n## Daftar Resep\n\n- Sup Jagung\n- Gudeg\n- Rendang\n- Bakso Rendang (fusi)\n\n## Cadangan\n\n- Mirror `../buku-resep-backup.git` — mutakhirkan dengan `git remote update`\n- Bundle `buku-resep.bundle` — buat ulang setiap pekan\n' > README.md
git add README.md
git commit -m "Catat prosedur backup pada README"Output yang Dihasilkan (perintah git commit):
[main 57a74dc] Catat prosedur backup pada README
1 file changed, 5 insertions(+)Riwayat final hari ini — sembilan commit, dua di antaranya pernah “hilang” dan kembali:
git log --onelineOutput yang Dihasilkan:
57a74dc Catat prosedur backup pada README
4673612 Sebutkan resep fusi pada README
6bba564 Lengkapi langkah resep fusi
239f8fc Coba resep fusi bakso rendang
563d368 Lengkapi README dengan daftar resep
84e2ae5 Tambah catatan penyajian
1c4a93c Tambah resep rendang
691f4f6 Tambah resep gudeg
12594d0 Rintis buku resep dengan resep supMirror masih tertinggal satu commit. Mirror tidak punya working tree, jadi pembaruannya tidak memakai git pull — melainkan git remote update yang dijalankan dari dalam mirror:
cd ../buku-resep-backup.git
git remote updateOutput yang Dihasilkan:
From /home/z/my-project/tutorial-extracted/work/sandbox/proyek-git/proyek-05/buku-resep/.
4673612..57a74dc main -> mainDua baris itu adalah laporan fetch: sumber buku-resep (jalur pada keluaran menyesuaikan lokasi direktori) memindahkan main dari 4673612 ke 57a74dc di sisi mirror. Verifikasi ulang kedua sisi:
git show-ref
cd ../buku-resep
git show-refOutput yang Dihasilkan (perintah git show-ref di dalam buku-resep-backup.git):
57a74dca575e7830b1421da7260d3f6e691b378b refs/heads/mainOutput yang Dihasilkan (perintah git show-ref di dalam buku-resep):
57a74dca575e7830b1421da7260d3f6e691b378b refs/heads/mainBaris demi baris identik — mirror kembali sejajar dengan sumber, dan prosedur ini bisa diulang kapan saja.
Bundle: Cadangan dalam Satu Berkas #
Jalur kedua menjawab kebutuhan yang tidak bisa dipenuhi mirror: cadangan berbentuk berkas tunggal yang bisa dikirim lewat USB, dilampirkan ke email, atau disimpan di arsip. Bungkus seluruh riwayat:
git bundle create buku-resep.bundle --allPerintah itu berhasil tanpa mengucap satu kata — git bundle create melaporkan dirinya lewat keluaran senyap. Bukti pertama ada di ukuran berkasnya:
ls -lh buku-resep.bundleOutput yang Dihasilkan:
-rw-rw-r-- 1 z z 3.3K Dec 14 2026 buku-resep.bundleUkuran dan tanggal pada keluaran kita akan menyesuaikan isi repository dan waktu pembuatan. Bukti kedua: minta Git memeriksa isi bundlenya sendiri:
git bundle verify buku-resep.bundleOutput yang Dihasilkan:
buku-resep.bundle is okay
The bundle contains these 2 refs:
57a74dca575e7830b1421da7260d3f6e691b378b refs/heads/main
57a74dca575e7830b1421da7260d3f6e691b378b HEAD
The bundle records a complete history.
The bundle uses this hash algorithm: sha1Tiga baris tengah adalah isi perjanjian: bundle membawa refs main dan HEAD yang sama dengan sumber, dan records a complete history menegaskan bahwa --all membungkus seluruh rantai commit — bukan potongan. Rujukan sintaks lengkapnya ada di dokumentasi git bundle
.
Uji Pemulihan Total #
Cadangan yang belum pernah dipakai untuk pulih hanyalah doa. Uji paling keras yang bisa dilakukan terhadap buku-resep.bundle: jadikan ia satu-satunya sumber kehidupan baru:
git clone buku-resep.bundle dari-bundleOutput yang Dihasilkan:
Cloning into 'dari-bundle'...Clone dari bundle berjalan seperti clone biasa — origin pada hasilnya menunjuk ke berkas bundle itu sendiri. Baca riwayat kehidupan barunya:
git -C dari-bundle log --onelineOutput yang Dihasilkan:
57a74dc Catat prosedur backup pada README
4673612 Sebutkan resep fusi pada README
6bba564 Lengkapi langkah resep fusi
239f8fc Coba resep fusi bakso rendang
563d368 Lengkapi README dengan daftar resep
84e2ae5 Tambah catatan penyajian
1c4a93c Tambah resep rendang
691f4f6 Tambah resep gudeg
12594d0 Rintis buku resep dengan resep supSembilan commit, baris demi baris identik dengan git log --oneline di sumber. Seandainya disk buku-resep hilang beserta reflog-nya, berkas 3.3K ini cukup untuk memulihkan seluruh pekerjaan. Selesai uji, folder dari-bundle/ boleh dihapus — ia hanya alat uji. Hubungan ketiganya terangkum begini:
Diagram itu dibaca sebagai tiga aliran cadangan: mirror ditarik terus-menerus lewat remote update, bundle dibuat ulang setiap kali disimpan, dan setiap bundle bisa di-clone menjadi repository hidup kapan diperlukan.
Jadwal Backup Harian, Mingguan, Bulanan #
Kedua jalur ini paling kuat saat dijadwalkan — ritual rutin mengalahkan niat baik. Pola yang dipakai tim kecil:
| Ritme | Alat | Perintah inti | Melindungi dari |
|---|---|---|---|
| Harian | remote (hosting atau pusat bare) | git push di akhir hari kerja | disk lokal rusak, laptop hilang |
| Mingguan | bundle | git bundle create cadangan-$(date +%F).bundle --all | kegagalan hosting, kebutuhan arsip offline |
| Bulanan | mirror | git clone --mirror baru, atau git remote update pada mirror lama | kerusakan menyeluruh, migrasi mesin |
Baris harian adalah git push biasa yang sudah dilatih di Proyek 03
— remote adalah cadangan termurah karena sudah menyatu dengan alur kerja. Bundle mingguan memberi titik pemulihan yang tidak bergantung pada koneksi atau layanan pihak ketiga, dan pemberian nama bertanggal menjadikannya arsip berlapis. Mirror bulanan mengunci keadaan utuh untuk jangka panjang. Otomatisasi lewat cron dan pola bundle inkremental dibahas di Backup Repository
.
Ringkasan Proyek #
Hari buruk yang direkayasa ini menutup dengan catatan pencapaian:
| Pencapaian | Bukti pada sesi |
|---|---|
| Membaca reflog sebagai peta pergerakan | lima entri commit terbaca dan diurai, HEAD@{n} dites dengan git rev-parse |
| Memulihkan commit tertelan reset | log kembali dari tiga ke lima commit setelah reset diarahkan ke hash dari HEAD@{1} |
| Memulihkan branch terhapus paksa | eksperimen/fusi bangkit dari reflog HEAD dengan tujuh commit utuh, lalu digabungkan ke main |
| Membangun backup dua jalur | mirror refs identik dengan sumber, dan bundle di-clone menjadi riwayat sembilan commit yang identik |
Konsep yang barusan dilatih tangan ini memiliki kedalaman teorinya masing-masing: anatomi reflog di git reflog , dua jalur pemulihan commit di Memulihkan Commit , dan prosedur lengkap saat insiden sungguhan datang di Prosedur Recovery Aman .
Kita kini bisa memulihkan apa pun yang Git catat — dan semuanya dicatat. Kompetensi terakhir yang belum dimiliki tim ini bukan menyelamatkan diri setelah kesalahan, melainkan mencegah kesalahan terulang secara otomatis: pemeriksaan yang berjalan sendiri setiap kali commit dibuat. Mesin penjaga itu bernama hooks, dan proyek berikutnya membangunnya: Proyek 06: Otomasi Git Hooks .