Giải quyết xung đột merge trong Git: Hướng dẫn thực chiến từ A-Z

Giải quyết xung đột merge trong Git: Hướng dẫn thực chiến từ A-Z

Xung đột merge là gì?

Xung đột merge xảy ra khi bạn merge hai branch khác nhau mà cả hai đều thay đổi cùng một phần code. Git không biết phải giữ phiên bản nào nên dừng lại và chờ bạn quyết định.

Tôi gặp tình huống này thường xuyên khi làm việc theo nhóm. Một lần, cả hai cùng sửa hàm login trong file auth.js. Kết quả là xung đột ngay lập tức. Lúc đó tôi hoảng loạn, nhưng sau khi hiểu cơ chế, mọi thứ trở nên đơn giản hơn.

So sánh các cách tiếp cận xung đột merge

1. Merge thủ công (Manual merge)

Cách thức: Mở file xung đột, chỉnh sửa trực tiếp rồi commit lại.

Ưu điểm:

  • Bạn kiểm soát hoàn toàn code cuối cùng
  • Cơ hội để hiểu cả hai phiên bản
  • Thích hợp với xung đột phức tạp

Nhược điểm:

  • Tốn thời gian, dễ mắc lỗi nếu có nhiều file
  • Cần hiểu rõ logic code của cả hai branch

2. Rebase thay vì merge

Cách thức: Dùng git rebase để áp dụng commits theo tuần tự thay vì tạo merge commit. Nếu bạn muốn hiểu thêm về kỹ thuật này, hãy xem gộp nhiều commit bằng Git rebase.

Ưu điểm:

  • Lịch sử commit sạch hơn, tuyến tính hơn
  • Dễ track thay đổi nào ở đâu

Nhược điểm:

  • Nguy hiểm nếu push lên branch shared (có thể phá lịch sử)
  • Xung đột vẫn xuất hiện, chỉ cách khác để giải quyết

3. Merge strategy (ours/theirs)

Cách thức: Tự động chọn một phiên bản mà không chỉnh sửa gì. Điều này cũng liên quan đến các lệnh merge branch khác nhau trong Git.

Ưu điểm:

  • Nhanh chóng, không cần edit thủ công
  • Tốt khi bạn chắc chắn nên giữ phiên bản nào

Nhược điểm:

  • Mất một phiên bản code hoàn toàn — có thể mất thay đổi quan trọng
  • Không phù hợp với xung đột phức tạp

4. Merge tools (GUI)

Cách thức: Sử dụng công cụ hỗ trợ như VS Code, GitKraken, P4Merge.

Ưu điểm:

  • Giao diện trực quan, so sánh hai phiên bản cạnh nhau dễ dàng
  • Giải quyết nhanh, ít lỗi hơn

Nhược điểm:

  • Cần cài đặt công cụ thêm

Chọn phương pháp phù hợp

Từ kinh nghiệm thực tế:

  • Xung đột nhỏ (1-2 dòng): Merge thủ công hoặc editor đơn giản là đủ
  • Xung đột ở nhiều file: Dùng GUI tool để nhìn rõ hơn
  • Làm việc solo hoặc feature branch riêng: Rebase là lựa chọn tốt
  • Làm việc nhóm trên main/develop: Merge thường là an toàn nhất

Tôi thường dùng merge thủ công + VS Code built-in resolver. Nó cho phép nhìn rõ “Current Change” (code của bạn) và “Incoming Change” (code từ branch kia) trước khi chọn.

Hướng dẫn từng bước giải quyết xung đột

Bước 1: Nhận biết xung đột

Chạy merge sẽ thấy thông báo như này:

git merge feature/new-login
Auto-merging auth.js
CONFLICT (content): Merge conflict in auth.js
Automatic merge failed; fix conflicts and then commit the result.

Bước 2: Kiểm tra file xung đột

git status

Output sẽ liệt kê những file cần giải quyết:

On branch main
You have unmerged paths.
  (fix conflicts and run "git commit")
Unmerged paths:
  (use "git add ..." to mark resolution)
    both modified: auth.js

Bước 3: Xác định xung đột trong file

Mở auth.js, bạn sẽ thấy:

function login(email, password) {
<<<<<<< HEAD // Code từ branch hiện tại (main) const user = findUserByEmail(email); if (user && user.password === hashPassword(password)) { return user; } ======= // Code từ branch muốn merge (feature/new-login) const user = await validateUser(email, password); if (user) { return user; } >>>>>>> feature/new-login
  return null;
}

Phần giữa <<<<<<< HEAD======= là code của bạn.

Phần giữa =======>>>>>>> là code từ branch incoming.

Bước 4: Giữ code nào?

Dùng VS Code: Nhấn “Accept Current Change”, “Accept Incoming Change”, “Accept Both Changes”, hoặc “Compare Changes”.

Chỉnh sửa thủ công: Xóa các dấu <<<, ===, >>> và giữ code muốn:

function login(email, password) {
  // Tổng hợp cả hai phiên bản
  const user = await validateUser(email, password);
  return user || null;
}

Bước 5: Đánh dấu đã giải quyết

git add auth.js

Bước 6: Hoàn thành merge

git commit -m "Merge feature/new-login: resolve conflict in auth.js"

Git sẽ tạo merge commit tự động. Bạn có thể chỉnh sửa thông điệp nếu cần.

Mẹo thực chiến

Mẹo 1: Xử lý xung đột khi rebase

Nếu rebase gặp xung đột, sau khi fix chạy:

git rebase --continue

Muốn hủy rebase:

git rebase --abort

Mẹo 2: Xem lịch sử branch trước merge

git log --oneline --graph --all

Giúp hiểu rõ cây branch và thay đổi ở đâu. Nếu bạn làm việc với các định nghĩa cơ bản của Git, có thể tham khảo một số định nghĩa thường gặp khi sử dụng Git.

Mẹo 3: Xem preview merge trước commit

git merge --no-commit --no-ff feature/new-login

Cách này cho phép kiểm tra merge trước khi commit. Không hài lòng thì:

git merge --abort

Mẹo 4: Dùng –force-with-lease thay vì –force

Tôi từng force push nhầm và mất code của đồng nghiệp. Từ đó tôi dùng:

git push --force-with-lease

Nó an toàn hơn vì từ chối push nếu branch remote có commits mà local không biết.

Mẹo 5: Tránh xung đột không cần thiết với .gitignore

Thêm các file không nên track để tránh conflict:

node_modules/
.env
dist/
*.log

Làm sao để giảm xung đột trong nhóm

  • Chia nhỏ feature: Không làm feature quá lớn, merge thường xuyên
  • Communicate với team: Báo hiệu khi sửa file nào
  • Code review trước merge: Pull request giúp catch issue sớm. Bạn có thể tìm hiểu thêm về sử dụng GitHub và GitHub Desktop để quản lý PR hiệu quả hơn
  • Consistent code style: Dùng Prettier hoặc ESLint
  • Rebase feature branch thường xuyên: Giữ cập nhật với main để xung đột nhỏ hơn

Những lỗi thường gặp

Lỗi 1: Nhầm lẫn HEAD và incoming branch

HEAD là branch bạn đang ở (thường là main). Incoming là branch bạn merge vào. Nhầm lẫn sẽ khiến code không đúng ý muốn.

Lỗi 2: Commit merge mà quên resolve hết xung đột

Luôn chạy git status trước commit để chắc hết xung đột đã resolve. Để hiểu rõ hơn các lệnh Git cơ bản, bạn có thể xem tổng hợp lệnh GIT thường dùng.

Lỗi 3: Merge vào branch sai

Chạy git branch để confirm bạn ở branch đúng trước merge.

Kết luận

Xung đột merge là phần bình thường của Git workflow. Vài lần xử lý, bạn sẽ làm tự động. Chìa khóa là hiểu Git làm gì, dùng tool phù hợp (VS Code merge resolver tuyệt vời), và luôn verify code sau khi resolve.

Đừng sợ xung đột. Hãy xem nó như cơ hội để hiểu sâu codebase và communicate tốt hơn với team. Theo thời gian, bạn sẽ biết cách tổ chức code để giảm xung đột từ đầu.