Foto oleh Emine Canpolat via Pexels

Merge conflict terjadi ketika Git tidak bisa secara otomatis menggabungkan perubahan dari dua branch berbeda karena keduanya mengubah bagian kode yang sama dengan cara yang berbeda, memaksa developer untuk memutuskan secara manual perubahan mana yang seharusnya dipertahankan.

Meski terlihat menakutkan bagi pemula, merge conflict sebenarnya adalah bagian normal dari kolaborasi tim menggunakan Git, dan memahami cara membaca serta menyelesaikannya dengan tenang adalah keterampilan penting yang akan terus dipakai sepanjang karier sebagai developer.

Artikel ini membahas cara membaca marker konflik yang ditampilkan Git, langkah-langkah menyelesaikan konflik secara manual, serta penggunaan tool visual yang bisa mempermudah proses penyelesaian konflik yang kompleks.

Membaca Marker Konflik pada File

Marker konflik menunjukkan dua versi yang saling bertentangan

<<<<<<< HEAD const MAX_ITEM = 10; // versi branch saat ini ======= const MAX_ITEM = 20; // versi branch yang di-merge >>>>>>> feature/update-limit
Ketika konflik terjadi, Git menyisipkan marker khusus langsung ke dalam file yang bermasalah: bagian antara <<<<<<< HEAD dan ======= menunjukkan versi dari branch saat ini, sementara bagian antara ======= dan >>>>>>> menunjukkan versi dari branch yang sedang di-merge, dan developer harus memutuskan versi mana atau kombinasi keduanya yang seharusnya dipertahankan.

Menyelesaikan Konflik Secara Manual

Hapus marker, pilih kode final, lalu add dan lanjutkan proses

# 1. Edit file, hapus marker, pilih/gabungkan kode yang benar: const MAX_ITEM = 20; // keputusan akhir setelah diskusi tim # 2. Tandai sebagai selesai dengan git add git add file-yang-dikonflikkan.js # 3. Lanjutkan proses merge git commit # untuk merge, atau git rebase --continue # untuk rebase
Setelah memutuskan kode final yang seharusnya ada (bisa salah satu versi, kombinasi keduanya, atau bahkan solusi baru sama sekali), seluruh marker konflik harus dihapus dari file, lalu file tersebut di-add untuk menandai konflik sudah terselesaikan, sebelum proses merge atau rebase bisa dilanjutkan.

Membatalkan Merge yang Sedang Berlangsung

Merge abort membatalkan proses merge yang sedang konflik

git merge --abort -- Expected: mengembalikan repository ke kondisi -- SEBELUM proses merge dimulai, seolah-olah -- perintah merge tidak pernah dijalankan
Jika konflik terlalu rumit atau ternyata merge tersebut memang belum siap dilakukan, git merge --abort membatalkan seluruh proses dan mengembalikan repository persis ke kondisi sebelum merge dimulai, memberikan kesempatan untuk mempersiapkan diri lebih baik sebelum mencoba merge kembali.

Memakai Tool Visual untuk Konflik Kompleks

Tool visual mempermudah penyelesaian konflik yang kompleks

git mergetool # Membuka tool visual (seperti VS Code, Beyond Compare, # atau KDiff3) yang menampilkan kedua versi secara # berdampingan, memudahkan membandingkan dan memilih
Untuk konflik yang melibatkan banyak baris atau file sekaligus, tool visual seperti yang terintegrasi di VS Code atau git mergetool jauh lebih memudahkan dibanding mengedit marker konflik secara manual di text editor biasa, menampilkan kedua versi secara berdampingan dengan highlight yang jelas untuk setiap perbedaan.

Semakin sering developer melakukan pull dan push dalam interval kecil, semakin kecil pula kemungkinan konflik besar menumpuk, karena perbedaan antar versi kode tetap kecil dan mudah dikelola dibanding menunggu berhari-hari sebelum menyinkronkan perubahan dengan branch utama yang mungkin sudah berubah signifikan.

Menggunakan Git Mergetool untuk Konflik yang Rumit

Memakai mergetool untuk konflik yang melibatkan banyak baris sekaligus

$ git merge fitur/validasi-harga Auto-merging ProdukService.cs CONFLICT (content): Merge conflict in ProdukService.cs $ git mergetool # membuka tool visual (mis. vscode) menampilkan tiga panel: # versi lokal, versi incoming, dan hasil gabungan $ git diff --check # memverifikasi tidak ada sisa marker <<<<<<< ======= >>>>>>> tertinggal

Untuk konflik sederhana yang hanya melibatkan satu atau dua baris, menyelesaikannya langsung di editor teks biasa sudah cukup. Namun pada konflik yang melibatkan banyak baris sekaligus di berbagai bagian file, git mergetool membuka aplikasi perbandingan visual yang menampilkan versi lokal, versi incoming, dan area hasil gabungan secara berdampingan, sehingga lebih mudah menelusuri perbedaan dibanding membaca marker konflik mentah.

Setelah konflik diselesaikan secara manual, penting untuk memeriksa ulang bahwa tidak ada marker konflik seperti <<<<<<<, =======, atau >>>>>>> yang tertinggal di file, karena marker yang lupa dihapus akan menyebabkan kode tidak bisa dikompilasi atau bahkan ter-commit sebagai bagian dari kode sungguhan. Perintah git diff --check bisa dipakai untuk mendeteksi sisa marker tersebut sebelum commit penyelesaian konflik dibuat.

Strategi Resolusi Konflik Cepat dengan --ours dan --theirs

--ours dan --theirs memilih seluruh isi satu sisi tanpa mengedit manual per baris

# Saat konflik terjadi, pilih salah satu sisi secara utuh untuk file tertentu $ git merge branch-lain CONFLICT (content): Merge conflict in appsettings.Development.json # Pertahankan versi branch saat ini (lokal) untuk file konfigurasi $ git checkout --ours appsettings.Development.json $ git add appsettings.Development.json # Atau pakai sepenuhnya versi yang masuk (incoming) untuk file tertentu $ git checkout --theirs CHANGELOG.md $ git add CHANGELOG.md $ git commit # Hanya file lain yang masih konflik yang perlu diselesaikan manual

Untuk file tertentu yang memang dimaksudkan untuk selalu mengikuti satu sisi secara utuh saat konflik, seperti file konfigurasi environment lokal atau file yang memang sengaja dibuat berbeda antar branch, menyelesaikan konflik baris per baris secara manual menjadi pekerjaan yang tidak perlu. Git menyediakan git checkout --ours dan --theirs untuk langsung memakai seluruh isi dari salah satu sisi pada file yang dipilih, tanpa perlu membuka editor sama sekali. Opsi ini jauh lebih cepat dibanding menghapus marker konflik secara manual untuk file yang isinya memang sudah diputuskan sebelumnya.

--ours mengacu pada versi dari branch yang sedang aktif saat proses merge dijalankan, sedangkan --theirs mengacu pada versi dari branch yang sedang digabungkan masuk. Penting dipahami bahwa makna --ours dan --theirs bisa terbalik ketika dipakai dalam konteks git rebase dibanding git merge, karena pada rebase branch yang sedang di-replay dianggap sebagai 'theirs' meski secara intuisi terasa sebagai milik sendiri. Kebingungan arah ini sering menjadi sumber kesalahan, sehingga developer disarankan selalu memeriksa isi file setelah checkout sebelum melanjutkan commit.

Strategi ini sebaiknya hanya dipakai untuk file yang memang diketahui aman diambil utuh dari satu sisi, bukan untuk file kode sumber yang kemungkinan besar memiliki perubahan penting dari kedua sisi sekaligus. Memakai --ours secara serampangan pada file kode berisiko menghilangkan perubahan penting dari rekan tim tanpa disadari, karena perintah ini tidak memberi peringatan apa pun atas kode yang hilang dari sisi yang tidak dipilih. Sebagai langkah aman, meninjau ulang diff hasil akhir sebelum commit tetap dianjurkan meski strategi ini dipakai untuk mempercepat penyelesaian.

Git Rerere agar Konflik Berulang Tidak Perlu Diselesaikan Manual Lagi

Rerere mengingat cara konflik sebelumnya diselesaikan

$ git config --global rerere.enabled true # Konflik pertama kali diselesaikan manual seperti biasa $ git merge fitur/validasi-harga CONFLICT (content): Merge conflict in ProdukService.cs # ...selesaikan manual, lalu git add dan commit... # Git mencatat pola resolusi ini secara otomatis # Saat konflik identik muncul lagi di percobaan rebase berikutnya $ git rebase main # rerere: Resolved 'ProdukService.cs' using previous resolution. # Konflik langsung terselesaikan tanpa campur tangan manual

Git rerere, singkatan dari reuse recorded resolution, mencatat cara sebuah konflik diselesaikan secara manual dan menyimpannya agar bisa dipakai ulang otomatis jika konflik yang persis sama muncul kembali di kemudian hari. Fitur ini sangat membantu saat sebuah branch perlu di-rebase berkali-kali terhadap main yang terus berubah, karena konflik serupa cenderung muncul berulang pada baris yang sama.

Setelah diaktifkan lewat konfigurasi rerere.enabled, Git secara diam-diam merekam setiap resolusi konflik yang dilakukan, lalu menerapkannya secara otomatis ketika pola konflik yang identik terdeteksi lagi. Meski begitu, hasil resolusi otomatis ini tetap perlu ditinjau ulang sebelum commit final, karena perubahan kode di sekitar area konflik bisa saja membuat resolusi lama tidak lagi tepat untuk konteks terbaru.

Kesalahan Umum yang Sering Terjadi

Lupa Menghapus Marker Konflik Setelah Menyelesaikannya

Lupa menghapus marker seperti <<<<<<< HEAD atau ======= setelah memilih kode final akan menyebabkan marker tersebut ikut ter-commit sebagai bagian dari kode, yang jika tidak terdeteksi bisa menyebabkan error sintaks atau bug yang membingungkan.

Panik dan Menghapus Salah Satu Versi Tanpa Memahami Konteksnya

Menghapus salah satu versi kode secara sembarangan tanpa memahami mengapa perubahan tersebut dibuat berisiko menghilangkan perbaikan bug atau fitur penting yang sebenarnya perlu dipertahankan dari salah satu branch.

Tidak Berkomunikasi dengan Penulis Kode yang Berkonflik

Menyelesaikan konflik sendirian tanpa berdiskusi dengan developer yang menulis perubahan yang saling bertentangan bisa menghasilkan keputusan yang salah tentang perubahan mana yang sebenarnya seharusnya dipertahankan berdasarkan konteks bisnis yang mungkin tidak diketahui sepenuhnya.

Kapan Pendekatan Ini Tidak Cocok Dipakai

Menyelesaikan konflik secara manual lewat text editor memberikan kontrol penuh dan pemahaman mendalam tentang apa yang sebenarnya berubah, namun bisa memakan waktu lebih lama untuk konflik yang melibatkan banyak baris sekaligus.

Tool visual seperti git mergetool mempercepat proses penyelesaian konflik dengan tampilan yang lebih intuitif, namun membutuhkan setup tambahan dan terkadang kurang transparan dibanding melihat langsung marker konflik mentah di file teks biasa.

Ringkasan

Merge conflict adalah bagian normal dari kolaborasi dengan Git, dan memahami cara membaca marker konflik serta menyelesaikannya dengan tenang adalah keterampilan penting bagi setiap developer. Jangan ragu memakai git merge --abort jika konflik terasa terlalu rumit untuk diselesaikan saat itu juga, dan selalu berkomunikasi dengan tim ketika konflik melibatkan keputusan yang tidak sepenuhnya jelas konteksnya.

Seri Belajar Git & CI/CD:

← Sebelumnya: Merge vs Rebase di Git

→ Selanjutnya: Pengenalan CI/CD untuk Developer