Merge Conflicts — Git

Merge conflict terjadi ketika dua branch mengubah baris yang sama pada file yang sama. Git tidak bisa memutuskan versi mana yang benar. Tanda conflict: >…

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-a dan fitur-b sama-sama dibuat dari main, dan keduanya mengubah baris <h1> di index.html. Kamu merge fitur-a dulu, lalu fitur-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.

Membaca tanda conflict

Git menulis dua versinya ke dalam file, dipisah tanda khusus:

<<<<<<< HEAD
<h1>Promo Ramadan</h1>
=======
<h1>Promo Lebaran</h1>
>>>>>>> fitur-b

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

  1. Tulis isi yang benar: versimu, versi mereka, atau gabungan keduanya. Hapus ketiga tandanya.
  2. git add index.html menandai file itu sudah beres.
  3. git commit menyelesaikan 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

⚠️ Jebakan yang sering ketemu

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.

Yang akan kamu pelajari