Merge conflict terjadi kalau dua branch mengubah baris yang sama di file yang sama dengan isi berbeda. Git gak bisa menebak mana yang benar, jadi dia berhenti dan minta kamu yang memutuskan. Bayangin kamu dan temanmu sama-sama mengedit judul poster promo. Kamu tulis "Promo Ramadan", dia tulis "Promo Lebaran". Bagian poster yang lain bisa disatukan begitu saja, tapi judulnya gak bisa ditebak: harus ada orang yang memilih.
🧪 Tebakan cepat:
fitur-adanfitur-bsama-sama dibuat darimain, dan keduanya mengubah baris<h1>diindex.html. Kamu mergefitur-adulu, lalufitur-b. Merge yang mana yang berhenti karena conflict? Tebak dulu, jawabannya ada di bagian "Contoh: dua branch, satu baris".
Kapan conflict muncul
Ingat 3-way merge dari pelajaran Merging: Git membandingkan base (commit tempat dua branch berpisah), sisi branch-mu, dan sisi branch yang di-merge, baris demi baris.
| Yang terjadi sejak base | Hasil merge |
|---|---|
| Cuma satu sisi mengubah baris itu | otomatis, perubahan itu dipakai |
| Dua sisi mengubah baris yang berbeda, walau di file yang sama | otomatis, dua-duanya dipakai |
| Dua sisi mengubah baris yang sama dengan isi berbeda | conflict |
Jadi yang bikin conflict bukan "file yang sama diubah", tapi baris yang sama diubah oleh dua sisi.
Contoh: dua branch, satu baris
index.html berisi <h1>Original</h1>. Dua branch dibuat dari commit yang sama, lalu masing-masing mengganti judulnya:
git init
git add .
git commit -m "initial"
git branch fitur-a # dua branch dari commit yang sama
git branch fitur-b
git switch fitur-a # atau: git checkout fitur-a
echo "<h1>Promo Ramadan</h1>" > index.html
git add .
git commit -m "update dari fitur-a"
git switch fitur-b
echo "<h1>Promo Lebaran</h1>" > index.html
git add .
git commit -m "update dari fitur-b"
git switch main
git merge fitur-a # mulus
git merge fitur-b # berhenti
Dua merge terakhir mencetak ini (hash-mu pasti beda):
$ git merge fitur-a
Updating 1a2b3c4..5d6e7f8
Fast-forward
index.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
$ git merge fitur-b
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
- Merge pertama mulus.
mainbelum berubah sejakfitur-adibuat, jadi terjadi fast-forward:maindigeser ke "update dari fitur-a". - Merge kedua conflict. Sekarang
mainberisi "Promo Ramadan",fitur-bberisi "Promo Lebaran", dan base keduanya "Original". Dua sisi mengubah baris<h1>yang sama. Itu jawaban tebakannya: yang berhenti adalah merge kedua, karena merge pertama belum punya saingan.
Membaca tanda conflict
Git menulis dua versinya ke dalam file, dipisah tanda khusus:
<<<<<<< HEAD
<h1>Promo Ramadan</h1>
=======
<h1>Promo Lebaran</h1>
>>>>>>> fitur-b
<<<<<<< HEADmembuka versi branch tempat kamu berada, yaitumainyang sudah membawa perubahanfitur-a.=======memisahkan versi kamu (di atas) dari versi branch lain (di bawah).>>>>>>> fitur-bmenutup versi dari branch yang di-merge.
git status juga memberi tahu file mana yang bermasalah:
$ git status
On branch main
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: index.html
no changes added to commit (use "git add" and/or "git commit -a")
both modified artinya dua sisi mengubah file ini, dan conflict-nya belum diselesaikan.
Menyelesaikan: edit, add, commit
- Tulis isi yang benar: versimu, versi mereka, atau gabungan keduanya. Hapus ketiga tandanya.
git add index.htmlmenandai file itu sudah beres.git commitmenyelesaikan merge. Git membuat merge commit dengan dua parent.
echo "<h1>Promo Ramadan dan Lebaran</h1>" > index.html # isi baru, tanpa tanda conflict
git add index.html # tandai sudah beres
git commit -m "resolve conflict" # merge selesai
- Biasanya kamu mengedit file-nya di editor. VS Code bahkan memberi tombol Accept Current, Accept Incoming, dan Accept Both.
echodi sini cuma cara cepat menulis ulang isinya dari terminal. git committanpa-mjuga boleh: Git sudah menyiapkan pesan bawaanMerge branch 'fitur-b'.- Belum siap memutuskan?
git merge --abortmembatalkan merge dan mengembalikan semuanya ke keadaan sebelumgit merge fitur-b.
⚠️ Jebakan yang sering ketemu
- Tanda conflict ikut ter-commit. Git asli gak menghalangi
git adduntuk file yang masih berisi<<<<<<<, jadi tandanya bisa ikut ter-commit dan halamanmu rusak. Cari<<<<<<<sebelumgit add. Simulator di Lab dan latihan sengaja menolakgit addselama tandanya masih ada. - Commit sebelum
git add. Git menolak denganCommitting is not possible because you have unmerged files.Add dulu file yang sudah dibereskan. - Pindah branch di tengah conflict. Git menolak pindah branch sampai merge-nya selesai. Selesaikan dengan add dan commit, atau batalkan dengan
git merge --abort. - Asal pilih versi sendiri. Versi temanmu mungkin sama pentingnya. Kalau ragu, tanya dulu orangnya.
TL;DR: Conflict muncul kalau dua branch mengubah baris yang sama dengan isi berbeda sejak base-nya. Git berhenti dengan CONFLICT (content), menulis <<<<<<< HEAD (versimu), ======= (pemisah), dan >>>>>>> nama-branch (versi mereka) ke file, dan git status menandai file itu both modified. Selesaikan dengan menulis isi yang benar tanpa tanda, git add file-nya, lalu git commit. git merge --abort membatalkan merge kalau belum siap.