Pemulihan sekuat apa pun punya batas: objek yang sudah terhapus oleh pembersihan tidak kembali, dan repository yang rusak total tidak bisa menyembuhkan diri. Karena itu lapisan pertahanan terbaik bukan keterampilan recovery, melainkan cadangan yang dibuat sebelum masalah datang. Git menyediakan dua jalur resmi yang saling melengkapi: git clone --mirror yang menyalin seluruh refs ke sebuah mirror bare, dan git bundle yang membungkus riwayat menjadi satu berkas biasa — bisa dikirim lewat USB, email, atau disimpan di arsip. Chapter ini membuktikan keduanya pada repository yang sama, termasuk memperbarui mirror dan mengambil pembaruan dari bundle.
Repository Sumber: Termasuk Ref yang Nakal #
Agar cadangan teruji sungguhan, sumbernya dibuat berisi lebih dari dua branch: ada tag annotated, dan ada refs/pull/1/head — jenis ref tersembunyi yang dipakai layanan hosting seperti GitHub untuk menyimpan nomor pull request. Ref nakal ini sengaja dibuat dengan git update-ref:
mkdir -p latihan-backup/proyek && cd latihan-backup/proyek
git init -b main
git config user.name "Budi Santoso"
git config user.email "[email protected]"
printf 'beranda\n' > situs.md
git add situs.md
git commit -m "Buat halaman beranda"
git switch -c fitur
printf 'galeri v1\n' > galeri.md
git add galeri.md
git commit -m "Mulai halaman galeri"
git switch main
git tag -a v1.0 -m "Rilis pertama"
git update-ref refs/pull/1/head fitur
git show-refOutput yang Dihasilkan:
8670b1ea46d1ccf3990fa2d4a7f8b9fa87211ddb refs/heads/fitur
32936f314934e1b42f254677cc4ce6b4e92ad32f refs/heads/main
8670b1ea46d1ccf3990fa2d4a7f8b9fa87211ddb refs/pull/1/head
dc6ed59e57a16a0a6844913fb7128c0c2daec5ed refs/tags/v1.0Empat ref tercantum lengkap dengan hashnya — hash di mesin pembaca akan berbeda. refs/pull/1/head menunjuk commit yang sama dengan fitur; inilah calon korban yang biasanya hilang pada pencadangan separuh jalan.
git clone –mirror: Menyalin Seluruh Refs #
cd ..
git clone --mirror proyek backup.git
git -C backup.git show-refOutput yang Dihasilkan:
Cloning into bare repository 'backup.git'...
done.Output yang Dihasilkan:
8670b1ea46d1ccf3990fa2d4a7f8b9fa87211ddb refs/heads/fitur
32936f314934e1b42f254677cc4ce6b4e92ad32f refs/heads/main
8670b1ea46d1ccf3990fa2d4a7f8b9fa87211ddb refs/pull/1/head
dc6ed59e57a16a0a6844913fb7128c0c2daec5ed refs/tags/v1.0Keluaran show-ref di mirror identik baris demi baris dengan di sumber — termasuk refs/pull/1/head dan tag. Kunci perilakunya terbaca dari konfigurasi remotenya:
git -C backup.git config --get-regexp '^remote\.origin\.'Output yang Dihasilkan:
remote.origin.url /home/z/my-project/tutorial-extracted/work/sandbox/pemulihan-dan-recovery/part-b/latihan-backup/proyek
remote.origin.fetch +refs/*:refs/*
remote.origin.mirror trueJalur pada keluaran di atas menyesuaikan lokasi direktori sandbox. Baris remote.origin.fetch +refs/*:refs/* adalah jantung mirror: seluruh namespace refs disalin apa adanya — tidak dipindahkan ke refs/remotes seperti clone biasa — sementara remote.origin.mirror true membuat operasi push dari mirror menimpa seluruh refs tujuan. Mirror juga berbentuk bare: tanpa working tree, sehingga cocok disimpan di direktori cadangan, bukan dikerjakan di dalamnya.
Mirror vs Clone Biasa #
Clone biasa untuk kontras — dari direktori yang sama:
git clone proyek salinan-biasa
git -C salinan-biasa show-refOutput yang Dihasilkan:
Cloning into 'salinan-biasa'...
done.Output yang Dihasilkan:
b04807f3b9d2edfe784ff8d74863ffe2ea2df974 refs/heads/main
b04807f3b9d2edfe784ff8d74863ffe2ea2df974 refs/remotes/origin/HEAD
8670b1ea46d1ccf3990fa2d4a7f8b9fa87211ddb refs/remotes/origin/fitur
b04807f3b9d2edfe784ff8d74863ffe2ea2df974 refs/remotes/origin/main
dc6ed59e57a16a0a6844913fb7128c0c2daec5ed refs/tags/v1.0| Aspek | git clone biasa | git clone --mirror |
|---|---|---|
| Bentuk | repo kerja + .git | bare, tanpa working tree |
| Refs heads | jadi refs/remotes/origin/* | tetap refs/heads/* apa adanya |
Ref tersembunyi (mis. refs/pull/*) | tidak disalin | ikut tersalin |
remote.origin.fetch | +refs/heads/*:refs/remotes/origin/* | +refs/*:refs/* |
| Kecocokan penggunaan | mengerjakan kode | cadangan dan pemulihan server |
refs/pull/1/head lenyap dari salinan biasa — ref nakal hanya selamat lewat mirror. Perbedaan terakhir yang tak tampak di tabel: pembaruan. Salinan biasa menyinkronkan dengan git pull, sedangkan mirror — yang tak punya working tree — memakai git remote update. Kita uji setelah sumbernya maju:
cd proyek
printf 'beranda\nfaq\n' > situs.md
git add situs.md
git commit -m "Tambah halaman faq"
cd ..
git -C backup.git remote updateOutput yang Dihasilkan:
From /home/z/my-project/tutorial-extracted/work/sandbox/pemulihan-dan-recovery/part-b/latihan-backup/proyek
32936f3..b04807f main -> mainMirror mengejar: main berpindah dari 32936f3 ke b04807f tanpa satu pun push dari sumbernya.
git bundle: Cadangan dalam Satu Berkas #
Jalur kedua menjawab kebutuhan yang tak bisa dipenuhi mirror: cadangan berbentuk berkas tunggal. Perintah git bundle create membungkus refs beserta seluruh objeknya ke satu berkas — keluarannya senyap, jadi buktinya kita baca dari ls:
cd proyek
git bundle create ../cadangan.bundle --all
cd ..
ls -lh cadangan.bundleOutput yang Dihasilkan:
-rw-rw-r-- 1 z z 1.1K Oct 24 2026 cadangan.bundleBerkas 1.1K itu memuat dua branch, satu tag, satu ref pull, dan seluruh objeknya. Karena ia hanyalah berkas biasa — bisa dicopy, dikirim, disimpan — penerapannya fleksibel: kloning langsung darinya, atau ambil pembaruan darinya:
git clone cadangan.bundle hasil-clone
git -C hasil-clone remote -v
git -C hasil-clone log --onelineOutput yang Dihasilkan:
Cloning into 'hasil-clone'...Output yang Dihasilkan:
origin /home/z/my-project/tutorial-extracted/work/sandbox/pemulihan-dan-recovery/part-b/latihan-backup/cadangan.bundle (fetch)
origin /home/z/my-project/tutorial-extracted/work/sandbox/pemulihan-dan-recovery/part-b/latihan-backup/cadangan.bundle (push)Output yang Dihasilkan:
b04807f Tambah halaman faq
32936f3 Buat halaman berandaClone dari bundle bekerja seperti clone biasa: riwayat utuh, dan origin otomatis menunjuk ke berkas bundlenya — jalur pada keluaran menyesuaikan lokasi direktori. Ketika sumbernya maju dan bundel baru dibuat, repository lama cukup melakukan fetch dari berkas itu:
cd proyek
printf 'kontak v1\n' > kontak.md
git add kontak.md
git commit -m "Tambah halaman kontak"
git bundle create ../cadangan-baru.bundle --all
cd ../hasil-clone
git fetch ../cadangan-baru.bundle main
git log --oneline -1 FETCH_HEADOutput yang Dihasilkan:
From ../cadangan-baru.bundle
* branch main -> FETCH_HEADOutput yang Dihasilkan:
f81e550 Tambah halaman kontakgit fetch memperlakukan bundle layaknya remote: commit f81e550 berpindah ke FETCH_HEAD dan siap di-merge. Perintah git bundle verify <berkas> juga tersedia untuk memeriksa keutuhan bundle sebelum dipakai. Rujukan sintaksnya ada di git-bundle
dan git-clone
.
Memilih Jalur dan Menjadwalkannya #
Kapan memakai yang mana? Mirror unggul untuk cadangan mesin-ke-mesin yang hidup di direktori tetap — misalnya salinan harian di disk kedua atau cermin server tim. Bundle unggul untuk arsip bebas-jaringan: transfer lewat USB, lampiran email, atau simpanan jangka panjang ketika koneksi tak bisa diandalkan. Keduanya bisa dijadwalkan dengan cron — misalnya entri 0 2 * * * git -C /jalur/proyek bundle create /cadangan/proyek-$(date +\%F).bundle --all menghasilkan satu berkas cadangan bernama tanggal setiap pukul dua pagi. Pola bergulir seperti ini memberi riwayat cadangan berlapis: hari buruk pun bisa “dipulihkan ke kemarin”.
Dua jalur cadangan kini siap dipakai kapan pun operasi berisiko di depan mata. Tinggal merangkai semuanya — reflog, fsck, objek menggantung, cadangan — menjadi satu prosedur baku yang bisa diikuti dengan kepala dingin di saat panik; rangkumannya menanti di Prosedur Recovery Aman .