Giải quyết xung đột:
Git thực hiện hợp nhất tự động hầu như mỗi khi bạn hợp nhất, rebase, cherry-pick, và ngay cả khi bạn pull một nhánh từ xa. Trong quá trình hợp nhất đó, Git phải quyết định ở mỗi bước xem thay đổi tệp mới có mâu thuẫn với bất kỳ thay đổi trước đó hay không.
Hầu hết các xung đột xảy ra khi các nhà phát triển thực hiện song song các thay đổi đối với cùng một phần của cùng một tệp hoặc nếu một nhà phát triển này xóa tệp mà một nhà phát triển khác đã sửa đổi. Trong những trường hợp này, Git cần sự phản hồi của bạn vì nó không thể tự động xác định điều gì là chính xác.
Khi các thay đổi nằm trên các dòng khác nhau hoặc thậm chí trong các tệp khác nhau, Git sẽ điều hướng qua các snapshot được áp dụng và kết thúc quá trình hợp nhất mà không có xung đột. Tuy nhiên, bạn nên luôn để ý các lỗi mà Git không thể phát hiện. Ví dụ: có thể xảy ra trường hợp sau khi hợp nhất thành công, project của bạn không biên dịch nữa. Với việc khắc phục sự cố và kiểm tra lịch sử commit, bạn có thể phát hiện ra rằng do một nhà phát triển nào đó đã thay đổi nguyên mẫu hàm, trong khi một nhà phát triển khác đang sử dụng hàm theo cách cũ.
Trong trường hợp có xung đột hợp nhất, Git sẽ chèn các điểm đánh dấu xung đột đặc biệt trong các tệp bị ảnh hưởng và tiếp tục quá trình hợp nhất. Kết quả cuối cùng sau đó chỉ ra rằng hợp nhất tự động đã không thành công và cam kết cuối cùng chưa được thực hiện. Nếu chạy lệnh $ git status, bạn có thể thấy rằng các tệp có xung đột vẫn chưa được dàn dựng mà thay vào đó được đánh dấu chưa hợp nhất và đang chờ bạn can thiệp xử lý. Sử dụng tùy chọn --merge với lệnh git log sẽ tạo ra một nhật ký với danh sách các cam kết xung đột giữa các nhánh hợp nhất.
$ 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 ..." to mark resolution)
both modified: my_network.py no changes added to commit (use "git add" and/or "git commit -a")
Nếu bạn mở các tệp đó bằng trình soạn thảo văn bản, bạn có thể thấy rằng mỗi phần có vấn đề được đánh dấu bằng các dấu xung đột. Trong tình huống đơn giản và phổ biến nhất, những điểm đánh dấu đó tách code thành hai phần. Mỗi phần bao gồm văn bản từ snapshot có liên quan. Cái trên là từ HEAD của bạn, chi nhánh hiện tại, trong khi cái dưới là từ nhánh hợp nhất. Git thực hiện hợp nhất ba chiều bắt đầu từ phần ban đầu chung. Do đó, đôi khi, bạn có thể xem nhiều hơn hai phần, với thêm điểm đánh dấu được sử dụng.
Hợp nhất các điểm đánh dấu:
<<<<<<<
Changes made on the current branch.
|||||||
The common ancestor version.
=======
Changes made on the merging branch.
>>>>>>>
Để giải quyết xung đột, bạn phải quyết định và thay đổi tệp về trạng thái mong muốn của nó. Có một số cách để làm điều này. Bạn có thể chỉ cần sử dụng một trình chỉnh sửa, tìm kiếm các điểm đánh dấu xung đột và thực hiện tất cả các sửa đổi cần thiết. Ngoài ra, nếu bạn biết rằng một phiên bản của tệp hoàn chỉnh tốt hơn, bạn có thể chỉ cần chọn một trong các phiên bản, được gọi là "ours" (HEAD) hoặc "theirs" (feature branch).
$git checkout --ours my_network.py
Sau khi giải quyết tất cả các xung đột, bạn cũng phải tạo các tệp chưa hợp nhất bằng lệnh $ git add và hoàn tất việc hợp nhất bằng lệnh $ git commit. Nếu bạn không hài lòng với kết quả hợp nhất hoặc bạn không có thời gian để giải quyết xung đột, bạn có thể hủy hợp nhất bất cứ lúc nào bằng lệnh git merge --abort hoặc đặt lại các tệp xung đột về lần commit cuối cùng.
Việc giải quyết xung đột có thể mất khá nhiều thời gian hoặc cần thêm sự hợp nhất với người làm chung của bạn. Nó có thể xảy ra rằng bạn sẽ phải yêu cầu người đó không commit với nhánh phát triển chính trong khi bạn đang giải quyết các xung đột hợp nhất. Bạn nên tránh sự phức tạp này không nên chậm trễ. Bằng cách đó, bạn có thể giải quyết các xung đột mà không bị áp lực về thời gian và lặp lại việc hợp nhất nhiều lần. Khi mọi thứ hoạt động như bình thường, bạn chỉ cần chuyển sang nhánh phát triển chính và thực hiện hợp nhất “fast-forward”.
Git thực hiện hợp nhất tự động hầu như mỗi khi bạn hợp nhất, rebase, cherry-pick, và ngay cả khi bạn pull một nhánh từ xa. Trong quá trình hợp nhất đó, Git phải quyết định ở mỗi bước xem thay đổi tệp mới có mâu thuẫn với bất kỳ thay đổi trước đó hay không.
Hầu hết các xung đột xảy ra khi các nhà phát triển thực hiện song song các thay đổi đối với cùng một phần của cùng một tệp hoặc nếu một nhà phát triển này xóa tệp mà một nhà phát triển khác đã sửa đổi. Trong những trường hợp này, Git cần sự phản hồi của bạn vì nó không thể tự động xác định điều gì là chính xác.
Khi các thay đổi nằm trên các dòng khác nhau hoặc thậm chí trong các tệp khác nhau, Git sẽ điều hướng qua các snapshot được áp dụng và kết thúc quá trình hợp nhất mà không có xung đột. Tuy nhiên, bạn nên luôn để ý các lỗi mà Git không thể phát hiện. Ví dụ: có thể xảy ra trường hợp sau khi hợp nhất thành công, project của bạn không biên dịch nữa. Với việc khắc phục sự cố và kiểm tra lịch sử commit, bạn có thể phát hiện ra rằng do một nhà phát triển nào đó đã thay đổi nguyên mẫu hàm, trong khi một nhà phát triển khác đang sử dụng hàm theo cách cũ.
Trong trường hợp có xung đột hợp nhất, Git sẽ chèn các điểm đánh dấu xung đột đặc biệt trong các tệp bị ảnh hưởng và tiếp tục quá trình hợp nhất. Kết quả cuối cùng sau đó chỉ ra rằng hợp nhất tự động đã không thành công và cam kết cuối cùng chưa được thực hiện. Nếu chạy lệnh $ git status, bạn có thể thấy rằng các tệp có xung đột vẫn chưa được dàn dựng mà thay vào đó được đánh dấu chưa hợp nhất và đang chờ bạn can thiệp xử lý. Sử dụng tùy chọn --merge với lệnh git log sẽ tạo ra một nhật ký với danh sách các cam kết xung đột giữa các nhánh hợp nhất.
$ 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 ..." to mark resolution)
both modified: my_network.py no changes added to commit (use "git add" and/or "git commit -a")
Nếu bạn mở các tệp đó bằng trình soạn thảo văn bản, bạn có thể thấy rằng mỗi phần có vấn đề được đánh dấu bằng các dấu xung đột. Trong tình huống đơn giản và phổ biến nhất, những điểm đánh dấu đó tách code thành hai phần. Mỗi phần bao gồm văn bản từ snapshot có liên quan. Cái trên là từ HEAD của bạn, chi nhánh hiện tại, trong khi cái dưới là từ nhánh hợp nhất. Git thực hiện hợp nhất ba chiều bắt đầu từ phần ban đầu chung. Do đó, đôi khi, bạn có thể xem nhiều hơn hai phần, với thêm điểm đánh dấu được sử dụng.
Hợp nhất các điểm đánh dấu:
<<<<<<<
Changes made on the current branch.
|||||||
The common ancestor version.
=======
Changes made on the merging branch.
>>>>>>>
Để giải quyết xung đột, bạn phải quyết định và thay đổi tệp về trạng thái mong muốn của nó. Có một số cách để làm điều này. Bạn có thể chỉ cần sử dụng một trình chỉnh sửa, tìm kiếm các điểm đánh dấu xung đột và thực hiện tất cả các sửa đổi cần thiết. Ngoài ra, nếu bạn biết rằng một phiên bản của tệp hoàn chỉnh tốt hơn, bạn có thể chỉ cần chọn một trong các phiên bản, được gọi là "ours" (HEAD) hoặc "theirs" (feature branch).
$git checkout --ours my_network.py
Sau khi giải quyết tất cả các xung đột, bạn cũng phải tạo các tệp chưa hợp nhất bằng lệnh $ git add và hoàn tất việc hợp nhất bằng lệnh $ git commit. Nếu bạn không hài lòng với kết quả hợp nhất hoặc bạn không có thời gian để giải quyết xung đột, bạn có thể hủy hợp nhất bất cứ lúc nào bằng lệnh git merge --abort hoặc đặt lại các tệp xung đột về lần commit cuối cùng.
Việc giải quyết xung đột có thể mất khá nhiều thời gian hoặc cần thêm sự hợp nhất với người làm chung của bạn. Nó có thể xảy ra rằng bạn sẽ phải yêu cầu người đó không commit với nhánh phát triển chính trong khi bạn đang giải quyết các xung đột hợp nhất. Bạn nên tránh sự phức tạp này không nên chậm trễ. Bằng cách đó, bạn có thể giải quyết các xung đột mà không bị áp lực về thời gian và lặp lại việc hợp nhất nhiều lần. Khi mọi thứ hoạt động như bình thường, bạn chỉ cần chuyển sang nhánh phát triển chính và thực hiện hợp nhất “fast-forward”.