Trong bài viết này, chúng ta sẽ tìm hiểu về conflict khi merge trong Git và các loại merge conflict mà bạn có thể gặp phải.

1. Merge Conflict trong Git là gì?

Trong Git, Conflict xảy ra khi bạn hoặc bất kỳ thành viên trong nhóm của bạn thực hiện các thay đổi xung đột trên cùng một tệp từ hai nhánh khác nhau.

Conflict cũng có thể xảy ra ngay cả khi bạn không làm việc với các thành viên khác trong nhóm. Nếu bạn đã thay đổi cùng một tệp từ các nhánh khác nhau và các thay đổi này xung đột.

Trong nhiều trường hợp, Git tự động xử lý việc hợp nhất cho bạn. Nhưng nếu có các thay đổi bạn thực hiện conflict trên cùng một tệp, bạn phải tự mình giải quyết chúng.

Ví dụ:

  • Bạn làm việc trong nhánh main và bạn thay đổi dòng 1 của tệp mytext.txt, ví dụ: “Hi world”.

  • Bạn chuyển sang nhánh new-feature và bạn thay đổi cùng dòng của tệp mytext.txt, ví dụ: “Hello earth”.

  • Nếu bạn cố gắng merge nhánh new-feature vào main, Git sẽ không thể tự động quyết định chấp nhận thay đổi nào giữa “Hi world” và “Hello earth”. Vì vậy, Git sẽ báo lỗi merge conflict và yêu cầu bạn giải quyết xung đột này.

2. Phải làm gì khi xảy ra conflict

Khi những xung đột này xảy ra và bạn cố gắng giải quyết chúng, Git sẽ tự động chú thích các dòng xung đột cho bạn bằng ký hiệu nhỏ hơn ( <), dấu bằng ( =) và lớn hơn ký hiệu ( >) như thế này:

Mọi thứ nằm giữa dấu nhỏ hơn ( <) và dấu bằng ( =) là sự thay đổi trong nhánh hiện tại (nhánh bạn đang sáp nhập vào). Mọi thứ nằm giữa các dấu bằng ( =) và lớn hơn ( >) là sự thay đổi sắp tới từ nhánh mà bạn muốn hợp nhất sang nhánh khác.

Bạn có quyền xóa các chú thích đó và quyết định cách bạn muốn các dòng xung đột – bạn có thể chấp nhận một trong các thay đổi hoặc cả hai thay đổi đó.

Vì vậy, thay vì xem xung đột hợp nhất như một trở ngại, bạn có thể chỉ xem chúng như một số chú thích bạn cần xóa và những điều bạn cần chấp nhận hoặc từ chối.

<<<<<<< 
=======
>>>>>>> 

3. Các loại conflict

3.1. Content Merge Conflict

Content Merge Conflict xảy ra khi Git không thể tự động hợp nhất các thay đổi từ hai nhánh khác nhau do xung đột trong nội dung của các tệp. Điều này thường xảy ra khi hai nhánh đã sửa đổi cùng một phần của một tệp, và các sửa đổi này không thể tự động kết hợp với nhau do chúng xung đột hoặc không tương thích. Khi xảy ra Content Merge Conflict, Git không thể tự động quyết định cách hợp nhất các thay đổi và yêu cầu sự can thiệp thủ công từ người dùng để giải quyết xung đột.

Ví dụ: bạn thực hiện thay đổi display: flex ở dòng 2 trong một nhánh và thay đổi khác text-align: center thành cùng dòng 2 trong cùng một tệp ở nhánh khác.

Khi conflict này xảy ra, Git sẽ dừng quá trình merge và nhắc bạn điều chỉnh lại code trước khi tiếp tục.

3.2. Structural Merge Conflict

Structural Merge Conflict xảy ra khi Git không thể tự động hợp nhất các thay đổi từ hai nhánh khác nhau do xung đột trong cấu trúc của các tệp, thay vì xung đột trong nội dung cụ thể của các dòng mã. Điều này thường xảy ra khi hai nhánh đã thêm hoặc xóa các phần của cùng một tệp, hoặc khi thay đổi cấu trúc tệp (ví dụ: thêm hoặc xóa các thư mục, thay đổi tên tệp) mà không thể tự động hợp nhất.

4. Cách xử lý merge conflict

Giải quyết conflict trong Git là quá trình thực hiện để hòa giải các thay đổi xung đột giữa các nhánh khác nhau và kết hợp chúng thành một phiên bản hợp nhất. Dưới đây là các bước cụ thể để giải quyết xung đột mà bạn có thể tham khảo:

Giả sử bạn đang làm việc trên nhánh "main" và bạn cũng đã tạo một nhánh mới là "new-feature" để thêm một tính năng mới vào dự án của bạn. Trong quá trình làm việc, bạn và một thành viên khác trong nhóm đã sửa đổi cùng một dòng trong tệp "mytext.txt" trên hai nhánh khác nhau, gây ra một xung đột hợp nhất.

B1: Đầu tiên, hãy thử hợp nhất nhánh "new-feature" vào nhánh "main" bằng cách chạy lệnh:

git checkout main

git merge new-feature

  • Git sẽ phát hiện ra xung đột hợp nhất và thông báo cho bạn biết. Tệp mà xảy ra xung đột sẽ hiển thị trong trạng thái "Unmerged paths".

  • Mở tệp "mytext.txt" bằng trình soạn thảo văn bản, bạn sẽ thấy các dòng được đánh dấu với dòng đầu tiên của mỗi bản sửa đổi và dòng xung đột sẽ được hiển thị giữa các dòng đó.

  • Giải quyết xung đột bằng cách chọn dòng bạn muốn giữ lại hoặc chỉnh sửa. Ví dụ:

<<<<<<< HEAD

Hello world

=======

Hi there

>>>>>>> new-feature

Trong ví dụ này, bạn có thể chọn giữ lại "Hello world" từ nhánh "main" hoặc sửa đổi thành "Hi there" từ nhánh "new-feature", hoặc thậm chí kết hợp cả hai.

B2: Sử dụng các lệnh Git cần thiết để giải quyết xung đột:

Sử dụng các lệnh Git như git add, git commit, và git merge để giải quyết xung đột. Bằng cách thêm các tệp đã giải quyết vào chỉ mục và tạo commit mới, bạn có thể hoàn thành quá trình giải quyết xung đột.

Sau khi giải quyết tất cả các xung đột trong tệp, lưu tệp và thêm tệp vào chỉ mục sử dụng lệnh:

git add mytext.txt

Tiếp theo, hoàn thành quá trình hợp nhất bằng cách chạy lệnh:

git merge --continue

B3: Kiểm tra và thử nghiệm lại sau khi giải quyết xung đột:

Cuối cùng, sau khi giải quyết xung đột, hãy kiểm tra và thử nghiệm lại dự án của bạn để đảm bảo rằng mọi thứ hoạt động như mong đợi và không có vấn đề gì liên quan đến xung đột. Điều này giúp đảm bảo rằng bạn đã giải quyết xung đột một cách chính xác và hiệu quả.

Nếu không có xung đột nào còn lại, Git sẽ hoàn thành quá trình hợp nhất và bạn có thể tiếp tục làm việc trên nhánh "main" đã được hợp nhất.

5. Một số chiến lược giải quyết conflict phổ biến

Dưới đây là một số chiến lược phổ biến để giải quyết xung đột trong Git:

  • Giữ lại thay đổi từ một nhánh và loại bỏ thay đổi từ nhánh khác: Trong một số trường hợp, bạn có thể quyết định giữ lại tất cả hoặc một phần của thay đổi từ một nhánh và loại bỏ thay đổi từ nhánh khác.

  • Kết hợp thay đổi từ cả hai nhánh: Trong trường hợp này, bạn có thể kết hợp các thay đổi từ cả hai nhánh để tạo ra một phiên bản mới chứa cả hai sự thay đổi.

  • Sửa đổi lại thay đổi để tạo ra một phiên bản mới và hợp nhất: Bạn có thể quyết định sửa đổi lại một số thay đổi để tạo ra một phiên bản mới, kết hợp cả hai sự thay đổi từ hai nhánh.

  • Sử dụng Git mergetool: Git cung cấp các công cụ mergetool để giúp bạn giải quyết xung đột một cách trực quan. Các công cụ này giúp hiển thị xung đột một cách dễ hiểu hơn và cung cấp các công cụ để giải quyết xung đột một cách hiệu quả.

Ví dụ: bạn đang cố gắng hợp nhất hai nhánh "feature-1" và "feature-2" vào nhánh "main". Trong quá trình hợp nhất, bạn gặp xung đột trong tệp "mytext.txt".

  • Nếu xung đột chỉ xảy ra trên một số dòng cụ thể, bạn có thể quyết định giữ lại thay đổi từ "feature-1" trên những dòng đó và loại bỏ thay đổi từ "feature-2".

  • Trong trường hợp cả hai nhánh đều đưa ra thay đổi quan trọng, bạn có thể quyết định kết hợp chúng bằng cách chọn một số thay đổi từ "feature-1" và một số từ "feature-2".

  • Hoặc bạn có thể quyết định sửa đổi lại một số thay đổi để tạo ra một phiên bản mới và hợp nhất.

Lời kết

Trong quá trình phát triển phần mềm, conflict hay còn gọi là xung đột là điều không thể tránh khỏi. Tuy nhiên, với các chiến lược giải quyết xung đột phù hợp, chúng ta có thể đối mặt và giải quyết chúng một cách hiệu quả. Việc hiểu cách xử lý xung đột, sử dụng các công cụ và kỹ thuật phù hợp là chìa khóa để duy trì tính nhất quán và tiến triển của dự án. Nếu bạn thấy bài viết hữu ích, đừng quên chia sẻ cho bạn bè cùng biết nhé!

 VietnamWorks inTECH