Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Lập Trình

Cách Giải quyết Git Merge Conflicts (Xung đột Hợp nhất)

Trong hầu hết các trường hợp, Git có thể giải quyết sự khác biệt giữa các nhánh và hợp nhất chúng. Điều này là vì các lập trình viên thường làm thay đổi trên các dòng hoặc file khác nhau. Có một số trường hợp Git không thể hợp nhất kho lưu trữ (repository). Những tình huống này được gọi là merge conflicts (xung đột hợp nhất).

Trong hướng dẫn này, chúng ta sẽ nói về việc hợp nhất (merging) là gì, merge conflicts là gì, và cách bạn có thể giải quyết git merge conflict. Hãy bắt đầu!

Merge Conflict là gì?

Merge conflict là nơi Git không thể hợp nhất hai nhánh mà không cần sự giúp đỡ của bạn.

Hợp nhất (Merges) là tính năng nền tảng của các hệ thống kiểm soát phiên bản như Git. Chúng cho phép lập trình viên duy trì nhiều dòng phát triển riêng biệt trong một kho lưu trữ. Điều này có nghĩa là một lập trình viên có thể làm việc sửa lỗi trên một nhánh mà không phải thay đổi bản sao chính của dự án.

Merge conflicts nảy sinh trong hai tình huống:

  • Hai nhánh đã thay đổi cùng một dòng mã.
  • Một nhánh đã xóa một file đã được thay đổi trên nhánh khác.

Khi merge conflict nảy sinh, một lỗi sẽ được trình bày trong Git. Điều này cho bạn biết Git không thể thành công hợp nhất các nhánh.

Cách Giải quyết Xung đột File Bị Xóa

Các nhánh Git độc lập với nhau. Điều này có nghĩa là một lập trình viên có thể xóa một file trên nhánh này mà không có thay đổi đó ảnh hưởng đến nhánh kia.

Merge conflicts có thể xảy ra nếu một thay đổi được làm cho một file trên nhánh này, và file đó bị xóa trên nhánh kia. Điều này là vì Git không biết nên xóa file hay thay đổi nó.

Giả sử chúng ta có hai nhánh: dev và master. Trên nhánh dev, chúng ta đã xóa file README.md. Trên nhánh master, chúng ta đã thêm văn bản mới.

Chúng ta có thể hợp nhất các nhánh này bằng lệnh git merge:

git merge dev

Điều này sẽ hợp nhất nhánh "dev" vào nhánh hiện tại của chúng ta, là master. Mã của chúng ta trả về merge conflict:

Auto-merging README.md CONFLICT (content): Merge conflict in README.md Automatic merge failed; fix conflicts and then commit the result.

Để giải quyết xung đột này, chúng ta cần quyết định: chúng ta muốn giữ file, hay thay đổi nó? Nếu bạn muốn giữ file, dùng lệnh git add và thêm nó trở lại kho lưu trữ:

git add README.md

Ngược lại, dùng lệnh git rm để xóa nó khỏi kho lưu trữ của bạn:

git rm README.md

Lệnh rm sẽ xóa file khỏi kho lưu trữ cục bộ của bạn. Trước khi dùng lệnh rm, hãy kiểm tra kỹ để chắc chắn bạn muốn xóa file.

Một khi bạn đã chọn cách xử lý file xung đột, bạn có thể tạo commit với thay đổi của mình và hợp nhất nhánh:

git add README.md
git commit -m "feat: Add README.md to repository"
git merge dev

Lệnh git add đưa thay đổi vào khu vực chuẩn bị (staging). Lệnh git commit tạo commit mới. Lệnh git merge hợp nhất nhánh dev và master của chúng ta. Các nhánh bây giờ có thể hợp nhất vì chúng ta đã giải quyết merge conflict.

Cách Giải quyết Xung đột Thay đổi File

Lập trình viên đôi khi làm thay đổi cho cùng một file trên hai nhánh khác nhau. Git không thể phân biệt thay đổi nào nên giữ khi hai nhánh được hợp nhất.

Trong trường hợp này, merge conflict sẽ nảy sinh. Giả sử chúng ta có kho lưu trữ với hai nhánh: master và dev. Chúng ta đã làm thay đổi cho file README.md trên cả hai nhánh. Điều này gây ra merge conflict:

Auto-merging README.md CONFLICT (content): Merge conflict in README.md Automatic merge failed; fix conflicts and then commit the result.

Bước đầu tiên là xác định nguyên nhân gốc rễ của merge conflict. Bạn có thể làm điều này bằng lệnh git status:

On branch master
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: README.md

Chúng ta có thể thấy từ thông báo này rằng file README.md đã được sửa đổi trên cả hai nhánh. Bây giờ, chúng ta phải giải quyết merge conflict của mình. Hãy mở file README.md bằng trình soạn thảo văn bản:

This is a README.md file. This is in a repository called merge-conflicts.
<<<<<<< HEAD
This file is on the main branch.
=======
This file is on the dev branch.
>>>>>>> dev

Git đã chỉnh sửa file để cho chúng ta biết merge conflict tồn tại và thêm các dấu hiệu xung đột (conflict markers). Git dùng ký tự dấu nhỏ hơn, dấu lớn hơn và dấu bằng để biểu thị merge conflict.

Dấu nhỏ hơn (<) đại diện cho thay đổi được làm cho nhánh hiện tại. Dấu lớn hơn (>) cho bạn biết thay đổi được làm cho nhánh bạn thử hợp nhất vào nhánh hiện tại. Dấu bằng (=) tách biệt sự khác biệt.

Trong trường hợp này:

  • "This file is on the main branch." nằm trên nhánh master của chúng ta (hoặc HEAD).
  • "This file is on the dev branch." nằm trên nhánh dev của chúng ta.

Để giải quyết xung đột công cụ hợp nhất này, tất cả những gì bạn cần làm là xóa văn bản bạn không muốn. Giả sử chúng ta muốn mã của mình nói: "This file is on a branch." Chúng ta có thể làm sửa đổi này như sau:

This is a README.md file. This is in a repository called merge-conflicts.
This file is on a branch.

Một khi chúng ta đã làm các thay đổi này, chúng ta sẵn sàng để hợp nhất cuối cùng. Hãy đưa thay đổi vào khu vực chuẩn bị (stage), commit chúng vào kho lưu trữ, và hợp nhất nhánh dev và master của chúng ta:

git add .
git commit -m "feat: Resolve merge conflict."
git merge dev

Bây giờ chúng ta đã giải quyết merge conflict, mã của chúng ta thành công hợp nhất.

Kết luận

Merge conflicts nảy sinh khi bạn làm thay đổi cho cùng một dòng văn bản trên hai nhánh hoặc khi bạn thay đổi file trên nhánh này và xóa file đó trên nhánh kia.

Trong hướng dẫn này, chúng ta đã thảo luận cách giải quyết merge conflicts trong cả hai trường hợp. Bây giờ bạn đã sẵn sàng bắt đầu xử lý merge conflicts như một chuyên gia Git.