Merge yang salah arah, fitur yang ternyata belum siap, atau konflik yang berubah jadi rawa — semua orang pernah berada di salah satu titik itu. Kabar baiknya: Git menyediakan pintu darurat di setiap tahap, dan pintu mana yang dipakai ditentukan satu hal — seberapa jauh kesalahan itu sudah berjalan. Sebelum commit, satu perintah memulihkan segalanya. Sesudah commit tetapi sebelum dibagikan, riwayat masih boleh ditulis ulang. Sesudah dibagikan, riwayat jadi milik bersama dan pembatalan harus dibuat sebagai commit baru. Chapter ini menguji ketiganya pada repository sungguhan.
Sebelum Commit: git merge –abort #
Skenario pertama memakai kondisi paling umum: merge berhenti karena konflik, dan kita memutuskan menyerah daripada melanjutkan:
mkdir latihan-batal-abort && cd latihan-batal-abort
git init -b main
git config user.name "Budi Santoso"
git config user.email "[email protected]"
printf '# Toko Budi\n\nKontak: [email protected]\n' > README.md
git add README.md
git commit -m "Buat README toko"
git switch -c fitur-kontak
printf '# Toko Budi\n\nKontak: [email protected]\n' > README.md
git add README.md
git commit -m "Ganti kontak ke layanan pelanggan"
git switch main
printf '# Toko Budi\n\nKontak: [email protected]\n' > README.md
git add README.md
git commit -m "Ganti kontak ke tim penjualan"
git merge fitur-kontakOutput yang Dihasilkan (perintah git merge fitur-kontak):
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.Repository kini berada di keadaan setengah-merge seperti chapter Merge Conflicts . Pintu daruratnya:
git merge --abortPerintah ini tidak mencetak apa pun — diamnya adalah tanda sukses. Bukti pemulihannya dibaca dari tiga sisi:
git statusOutput yang Dihasilkan:
On branch main
nothing to commit, working tree cleancat README.mdOutput yang Dihasilkan:
# Toko Budi
Kontak: [email protected]git log --oneline --graph --allOutput yang Dihasilkan:
* 040425a Ganti kontak ke tim penjualan
| * fb33553 Ganti kontak ke layanan pelanggan
|/
* f76a000 Buat README tokoKondisi kembali persis sebelum merge dijalankan: working tree bersih, README.md utuh versi main, main tetap di commit terakhirnya, kedua branch kembali menyimpang. Berkas internal MERGE_HEAD dan MERGE_MSG yang menandai merge berjalan ikut dihapus — git commit biasa sudah tidak akan dianggap menutup merge.
Sesudah Commit, Sebelum Dibagikan: reset ke ORIG_HEAD #
Kasus kedua lebih licik: merge berhasil tanpa konflik, commit penggabung sudah lahir, baru kemudian kita sadar penggabungan itu salah. Selama commit itu belum dibagikan ke orang lain, riwayat masih boleh disetir mundur:
mkdir latihan-batal && cd latihan-batal
git init -b main
git config user.name "Budi Santoso"
git config user.email "[email protected]"
printf '# Situs\nberanda\n' > situs.md
git add situs.md
git commit -m "Buat halaman beranda"
git switch -c fitur-galeri
printf 'galeri-1.jpg\n' > galeri.md
git add galeri.md
git commit -m "Tambah berkas galeri"
git switch main
printf '# Situs\nberanda\ntentang\n' > situs.md
git add situs.md
git commit -m "Tambah halaman tentang"
git merge fitur-galeri -m "Gabungkan galeri"Output yang Dihasilkan (perintah git merge fitur-galeri -m "Gabungkan galeri"):
Merge made by the 'ort' strategy.
galeri.md | 1 +
1 file changed, 1 insertion(+)
create mode 100644 galeri.mdDi sinilah ORIG_HEAD masuk. Git menulis berkas internal .git/ORIG_HEAD setiap kali HEAD berpindah karena operasi berbahaya — merge, reset, atau rebase — mencatat posisi sebelum pindah:
cat .git/ORIG_HEAD
git log --oneline -1Output yang Dihasilkan (perintah cat .git/ORIG_HEAD):
ca1710efd2f10d37addf7e446cd66a041432bda0Output yang Dihasilkan (perintah git log --oneline -1):
51be0f0 Gabungkan galeriIsi ORIG_HEAD adalah ca1710e — commit “Tambah halaman tentang”, ujung main sebelum merge. Kembalikan keseluruhan branch ke titik itu:
git reset --hard ORIG_HEADOutput yang Dihasilkan:
HEAD is now at ca1710e Tambah halaman tentanggit log --oneline --graph --allOutput yang Dihasilkan:
* ca1710e Tambah halaman tentang
| * 8274166 Tambah berkas galeri
|/
* 21074d0 Buat halaman berandaMerge commit lenyap dari riwayat main; kedua branch kembali menyimpang seolah tak pernah digabungkan. Hash pada keluaran mesin pembaca akan berbeda, polanya tetap. Jalan kedua yang setara: karena merge commit selalu satu langkah di depan ujung main semula, git reset --hard HEAD~1 juga jatuh ke titik yang sama. Kita buktikan — merge diulang sekali lagi, lalu:
git reset --hard HEAD~1Output yang Dihasilkan:
HEAD is now at ca1710e Tambah halaman tentangSesudah Dibagikan: git revert -m 1 #
Komit merge yang sudah di-push dan dipakai rekan kerja tidak boleh di-reset — menulis ulang riwayat bersama akan memutus salinan semua orang. Pembatalannya dibuat jujur di muka: satu commit baru yang membalik efek merge. Merge diulang sekali lagi, lalu:
git revert -m 1 HEAD --no-editOutput yang Dihasilkan:
[main 42f4573] Revert "Gabungkan galeri"
Date: Thu Oct 15 20:50:00 2026 +0700
1 file changed, 1 deletion(-)
delete mode 100644 galeri.mdFlag -m 1 (mainline) wajib ada karena commit merge punya dua parent — Git harus diberi tahu sisi mana yang dianggap “jalur utama” yang dibalik. Angka 1 berarti parent pertama: sisi tempat kita berdiri saat merge (main), sesuai konvensi first-parent dari chapter Three-Way Merge
. Commit baru bertajuk Revert "Gabungkan galeri" lahir di puncak riwayat:
git log --oneline --graph --allOutput yang Dihasilkan:
* 42f4573 Revert "Gabungkan galeri"
* 361af8d Gabungkan galeri
|\
| * 8274166 Tambah berkas galeri
* | ca1710e Tambah halaman tentang
|/
* 21074d0 Buat halaman berandaBaca grafnya: merge 361af8d tetap tercatat, dan di atasnya berdiri 42f4573 yang membatalkan efeknya — galeri.md hilang kembali dari working tree. Riwayat tidak disembunyikan; ia justru menceritakan keputusan beserta pembatalannya. Sesudah revert, pengembangan bisa lanjut dari titik itu. Cabang pembatalan commit secara umum — termasuk untuk commit biasa dan perdebatan kapan revert mengalahkan reset — dibahas tuntas di chapter git revert
; aturan main-main dengan riwayat bersama dirangkum di Aturan Aman Mengubah Riwayat
.
Tabel Situasi ke Solusi #
| Situasi | Perintah | Hasil |
|---|---|---|
| Merge berjalan, konflik belum selesai | git merge --abort | Keadaan kembali persis sebelum merge |
| Commit merge sudah dibuat, belum dibagikan | git reset --hard ORIG_HEAD (atau HEAD~1) | Riwayat ditulis ulang, merge hilang |
| Commit merge sudah dibagikan | git revert -m 1 <hash-merge> | Commit baru pembatal, riwayat tetap utuh |
Makin lama kesalahan dibiarkan, makin panjang jalan pulangnya — dan makin besar andil orang lain di dalamnya. Dokumentasi resmi masing-masing perintah ada di git-scm.com/docs/git-merge dan git-scm.com/docs/git-revert . Setelah merge selesai dibatalkan atau justru diterima, satu tugas rumah tangga menunggu: membersihkan branch-branch yang sudah menyelesaikan tugasnya: Menghapus Branch .