Bencana kedua lebih halus darinya reset: yang hilang bukan sekadar commit, melainkan satu branch utuh beserta seluruh pekerjaannya. Skenarionya klasik — kita membuat branch eksperimen, mengisinya dua commit, lalu di tengah suasana buruk memutuskan eksperimennya gagal dan menghapus branchnya. Git sebenarnya sudah berusaha menolong: git branch -d menolak menghapus branch yang pekerjaannya belum tergabung. Hari buruk dimulai tepat saat kita memaksa kehendak itu dengan -D. Bagian ini menjalankan keduanya, kehilangan branchnya sungguhan, lalu membangkitkannya kembali dari reflog HEAD.

Branch Eksperimen untuk Resep Fusi #

Sepulang dari bencana pertama, semangat justru naik: resep fusi bakso rendang layak dicoba di ruang terpisah. Buat branchnya:

bash
git switch -c eksperimen/fusi

Output yang Dihasilkan:

text
Switched to a new branch 'eksperimen/fusi'

Commit pertama branch ini menambahkan seksi baru berisi daftar bahan:

bash
printf '\n## Bakso Rendang\n\nBahan:\n- 250 gram daging rendang, suwir\n- 10 buah bakso sapi\n- 1 liter kaldu sapi\n' >> sample.txt
tail -n 7 sample.txt
git add sample.txt
git commit -m "Coba resep fusi bakso rendang"

Output yang Dihasilkan (perintah tail -n 7 sample.txt):

text

## Bakso Rendang

Bahan:
- 250 gram daging rendang, suwir
- 10 buah bakso sapi
- 1 liter kaldu sapi

Output yang Dihasilkan (perintah git commit):

text
[eksperimen/fusi 239f8fc] Coba resep fusi bakso rendang
 1 file changed, 7 insertions(+)

Commit kedua melengkapi langkah memasaknya:

bash
printf '\nLangkah:\n1. Didihkan kaldu sapi.\n2. Masukkan bakso dan suwiran rendang.\n3. Sajikan dengan bawang goreng.\n' >> sample.txt
tail -n 5 sample.txt
git add sample.txt
git commit -m "Lengkapi langkah resep fusi"

Output yang Dihasilkan (perintah tail -n 5 sample.txt):

text

Langkah:
1. Didihkan kaldu sapi.
2. Masukkan bakso dan suwiran rendang.
3. Sajikan dengan bawang goreng.

Output yang Dihasilkan (perintah git commit):

text
[eksperimen/fusi 6bba564] Lengkapi langkah resep fusi
 1 file changed, 5 insertions(+)

Perhatikan bahwa baris pertama keluaran commit kini menyebut eksperimen/fusi, bukan main — kita sedang bekerja di branch itu. Kondisi branch sebelum bencana:

bash
git log --oneline -3

Output yang Dihasilkan:

text
6bba564 Lengkapi langkah resep fusi
239f8fc Coba resep fusi bakso rendang
563d368 Lengkapi README dengan daftar resep

Branch ini maju dua commit dari main, dan keduanya belum tergabung ke mana pun.

Bencana Kedua: branch -D #

Kembali ke main — misalnya untuk mengerjakan hal lain, dan keputusan hapus diambil dari kursi yang “aman” ini:

bash
git switch main

Output yang Dihasilkan:

text
Switched to branch 'main'

Coba hapus dengan cara sopan dulu:

bash
git branch -d eksperimen/fusi

Output yang Dihasilkan:

text
error: the branch 'eksperimen/fusi' is not fully merged
hint: If you are sure you want to delete it, run 'git branch -D eksperimen/fusi'
hint: Disable this message with "git config advice.forceDeleteBranch false"

Git menolak, dan penolakan ini adalah perlindungan yang bekerja benar: -d hanya menghapus branch yang pekerjaannya sudah aman di branch lain, dan dua commit fusi kita jelas belum menyatu ke main — perilaku yang diurai di Menghapus Branch . Hari buruk berlanjut ketika peringatan itu justru dibalas paksa:

bash
git branch -D eksperimen/fusi

Output yang Dihasilkan:

text
Deleted branch eksperimen/fusi (was 6bba564).

Branch lenyap dari daftar:

bash
git branch

Output yang Dihasilkan:

text
* main

Mencari Alamat Terakhir #

Setiap branch punya reflog sendiri — jujur saja, mari coba dulu jalan yang paling masuk akal:

bash
git reflog show eksperimen/fusi

Output yang Dihasilkan:

text
fatal: ambiguous argument 'eksperimen/fusi': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

Perintah itu gagal karena penghapusan branch ikut menghapus berkas reflog milik branchnya — git reflog show eksperimen/fusi tidak lagi punya sumber bacaan. Namun reflog HEAD mencatat pergerakan dari kursi mana pun kita bekerja, termasuk selagi HEAD berdiri di branch yang sekarang sudah tidak ada:

bash
git reflog

Output yang Dihasilkan:

text
563d368 HEAD@{0}: checkout: moving from eksperimen/fusi to main
6bba564 HEAD@{1}: commit: Lengkapi langkah resep fusi
239f8fc HEAD@{2}: commit: Coba resep fusi bakso rendang
563d368 HEAD@{3}: checkout: moving from main to eksperimen/fusi
563d368 HEAD@{4}: reset: moving to 563d368f9cb39a5543dee7b50dfe277004449483
1c4a93c HEAD@{5}: reset: moving to HEAD~2
563d368 HEAD@{6}: commit: Lengkapi README dengan daftar resep
84e2ae5 HEAD@{7}: commit: Tambah catatan penyajian
1c4a93c HEAD@{8}: commit: Tambah resep rendang
691f4f6 HEAD@{9}: commit: Tambah resep gudeg
12594d0 HEAD@{10}: commit (initial): Rintis buku resep dengan resep sup

Sebelas baris itu adalah kisah hari kita yang utuh. Empat baris teratas milik branch yang hilang:

  1. HEAD@{3} — checkout: moving from main to eksperimen/fusi membuktikan kita pernah berdiri di branch itu, berangkat dari 563d368.
  2. HEAD@{2} dan HEAD@{1} — dua commit fusi, dibuat selagi HEAD berada di branch; 6bba564 di HEAD@{1} adalah posisi terakhir eksperimen/fusi.
  3. HEAD@{0} — keberangkatan terakhir kita dari branch itu ke main.

Alamat ketemu. Seperti biasa, uraikan dulu supaya yakin:

bash
git rev-parse HEAD@{1}

Output yang Dihasilkan:

text
6bba56465cc140f43595b0b5c413a626f503f045

Membangkitkan Branch #

Satu perintah git branch dengan nama branch dan titik berdirinya — sama seperti mendaftarkan branch baru, hanya saja titik berdirinya adalah commit yang “hilang”:

bash
git branch eksperimen/fusi 6bba56465cc140f43595b0b5c413a626f503f045

Perintah itu berhasil tanpa keluaran apa pun — git branch memang senyap saat sukses. Jangan percaya begitu saja; periksa riwayat branchnya:

bash
git log --oneline eksperimen/fusi

Output yang Dihasilkan:

text
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 sup

Log utuh: dua commit fusi masih menempel pada lima commit buku resep, tidak satu pun hilang. Branch sudah hidup kembali sebagai penunjuk biasa — persis keadaan sebelum -D dijalankan. Seluruh bentuk perintah git branch yang dipakai di sini terdokumentasi di git-branch .

Merge Kembali ke main #

Kerja eksperimen ini layak masuk buku resep, jadi gabungkan. Karena main diam di 563d368 sejak branch dibuat, penggabungan berjalan sebagai fast-forward — mekanisme yang dibedah di Fast-Forward Merge :

bash
git merge eksperimen/fusi

Output yang Dihasilkan:

text
Updating 563d368..6bba564
Fast-forward
 sample.txt | 12 ++++++++++++
 1 file changed, 12 insertions(+)

Pemulihan belum lengkap sampai dokumentasinya ikut kembali — sebutkan resep fusi di daftar resep README.md, lalu catat:

bash
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' > README.md
git add README.md
git commit -m "Sebutkan resep fusi pada README"

Output yang Dihasilkan (perintah git commit):

text
[main 4673612] Sebutkan resep fusi pada README
 1 file changed, 1 insertion(+)

Sekarang rapikan branch yang pekerjaannya sudah tersatu — dan perhatikan siapa yang kini diizinkan menghapus:

bash
git branch -d eksperimen/fusi

Output yang Dihasilkan:

text
Deleted branch eksperimen/fusi (was 6bba564).

Perintah -d yang tadi ditolak kini diloloskan tanpa protes: seluruh commit fusi sudah tergabung di main, jadi penghapusan tidak lagi membuang pekerjaan siapa pun. Lingkaran hari buruk tertutup sempurna. Keadaan akhir bagian ini:

bash
git log --oneline

Output yang Dihasilkan:

text
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 sup

Dan isi berkasnya kini memuat lima seksi:

bash
grep '^## ' sample.txt

Output yang Dihasilkan:

text
## Sup Jagung
## Gudeg
## Rendang
## Catatan Penyajian
## Bakso Rendang

Dua bencana, dua pemulihan total. Tetapi reflog punya batas: ia lokal, ia bisa kedaluwarsa, dan ia ikut lenyap bila foldernya hilang. Sebelum hari ditutup, kita memasang jaring pengaman yang tidak bergantung pada keberuntungan: Bagian 4: Membuat Backup Aman .