Cách giải quyết xung đột trong Git (xử lý conflict Git)

Cách giải quyết xung đột trong Git như thế nào? Đối với một lập trình viên thì conflict code hay conflict git là những vấn đề không thể tránh khỏi. Vậy thì cách giải quyết hay xử lý conflict git là gì? Cùng Comdy tìm hiểu trong bài viết này nhé.

Conflict code là gì?

Conflict code là gì
Conflict code là một thuật ngữ trong quản lý phiên bản để chỉ mã nguồn bị xung đột giữa các phiên bản khác nhau của cùng một tệp tin trong hệ thống quản lý phiên bản.

Conflict code là một thuật ngữ trong quản lý phiên bản để chỉ mã nguồn bị xung đột giữa các phiên bản khác nhau của cùng một tệp tin trong hệ thống quản lý phiên bản.

Mã xung đột xảy ra khi hai hoặc nhiều người phát triển thay đổi cùng một dòng hoặc khu vực mã nguồn mà không có thông tin hay xác định rõ ràng về cách họ nên được hợp nhất.

Khi hệ thống quản lý phiên bản phát hiện ra sự xung đột, nó thường tạo ra mã nguồn mới chứa các dấu hiệu của sự xung đột, và người phát triển sau đó phải giải quyết xung đột bằng cách hợp nhất hoặc chọn các thay đổi phù hợp từ các phiên bản khác nhau.

Git conflict là gì?

Git conflict là xung đột xảy ra khi hai hay nhiều người thay đổi trên cùng 1 tệp. Các xung đột có thể xuất hiện ở kho lưu trữ cục bộ của thành viên hay là kho lưu trữ từ xa Github.

Tổng quan về xử lý conflict trong Git

Tổng quan về xử lý conflict trong Git
Xử lý conflict git thường vẫn được xem là một nơi bí ẩn và tăm tối

Điều mà mọi nhà phát triển đều ghét phải nhìn thấy khi merge code đó là: xung đột ( Không có cách nào để tự động giải quyết các xung đột hợp nhất khi làm việc với Git (hoặc các hệ thống kiểm soát phiên bản khác).

Nhưng khi nói chuyện với các nhà phát triển, tôi thường nghe rằng có cảm giác lo lắng hoặc khó chịu xung quanh chủ đề xung đột khi merge code này.

Xử lý conflict git thường vẫn là một nơi bí ẩn, tăm tối: một tình huống mà mọi thứ đang bị phá vỡ một cách tồi tệ và không rõ làm cách nào để thoát ra khỏi nó (mà không làm cho mọi thứ trở nên tồi tệ hơn).

Mặc dù đúng là xung đột hợp nhất (merge conflict) là một phần không thể tránh khỏi trong cuộc sống của một nhà phát triển, nhưng sự khó chịu trong những tình huống này là hoàn toàn tùy chọn.

Mục đích của tôi với bài viết này là mang lại sự rõ ràng cho chủ đề này: làm thế nào và khi nào các xung đột thường xảy ra, chúng ta sẽ thực sự làm gì để giải quyết chúng.

Khi bạn hiểu đúng những điều này, bạn sẽ có thể giải quyết các xung đột hợp nhất một cách thoải mái và tự tin hơn nhiều.

Resolve conflict là gì?

Resolve conflict hay fix conflict git là quá trình giải quyết sự xung đột giữa các phiên bản khác nhau của cùng một tài nguyên trong quản lý phiên bản (version control), đặc biệt là khi sử dụng hệ thống quản lý phiên bản như Git hoặc SVN.

Sự xung đột xảy ra khi hai hoặc nhiều người phát triển đã thực hiện các thay đổi đồng thời trên cùng một dự án. Khi cố gắng hợp nhất (merge) hoặc commit các thay đổi, hệ thống quản lý phiên bản có thể phát hiện ra sự xung đột và yêu cầu người phát triển giải quyết nó.

Quá trình giải quyết mã xung đột (fix conflict git) đòi hỏi sự chăm chỉ và cẩn thận từ phía người phát triển để đảm bảo tính nhất quán và chất lượng của mã nguồn trong dự án.

Xung đột trong Git xảy ra như thế nào và khi nào?

Xung đột trong Git xảy ra như thế nào và khi nào
Xung đột trong Git xảy ra như thế nào và khi nào?

Cái tên đã nói lên điều đó: “xung đột hợp nhất” có thể xảy ra trong quá trình tích hợp các commit từ một nguồn khác.

Tuy nhiên, hãy nhớ rằng “tích hợp” không chỉ giới hạn ở “hợp nhất các nhánh”. Nó cũng có thể xảy ra khi phục hồi hoặc phục hồi tương tác, khi thực hiện một cherry-pick hoặc pull, hoặc thậm chí khi áp dụng lại một Stash.

Tất cả các hành động này thực hiện một số loại tích hợp – và đó là khi xung đột hợp nhất có thể xảy ra.

Nhưng tất nhiên, những hành động này không dẫn đến xung đột hợp nhất mọi lúc. Tốt nhất, bạn chỉ nên thấy mình hiếm khi rơi vào những tình huống này. Nhưng chính xác thì xung đột xảy ra khi nào?

Trên thực tế, khả năng hợp nhất của Git là một trong những lợi thế lớn nhất của nó: việc hợp nhất các nhánh hoạt động dễ dàng hầu như mọi lúc, bởi vì Git thường có thể tự tìm ra và giải quyết mọi thứ.

Nhưng có những tình huống xảy ra những thay đổi trái ngược nhau – và nơi công nghệ không thể quyết định điều gì là đúng hay sai. Những tình huống này chỉ cần một quyết định từ con người.

Điều cổ điển thực sự là khi cùng một dòng mã được thay đổi trong hai lần commit, trên hai nhánh khác nhau. Git không có cách nào để biết bạn thích thay đổi nào!

Làm sao để biết khi nào xung đột trong Git xảy ra?

Đầu tiên, Git sẽ cho bạn biết ngay lập tức khi xảy ra tình huống này, chẳng hạn như khi merge hoặc rebase không thành công do xung đột:

$ git merge develop
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
CONFLICT (modify/delete): error.html deleted in HEAD and modified in develop. Version develop of error.html left in tree.
Automatic merge failed; fix conflicts and then commit the result.

Như bạn có thể thấy từ ví dụ trên, khi tôi cố gắng thực hiện hợp nhất, tôi đã tạo ra xung đột hợp nhất – và Git thông báo vấn đề rất rõ ràng và kịp thời:

  • Đã xảy ra xung đột trong tệp “index.html”.
  • Một xung đột khác trong tệp “error.html” đã xảy ra.
  • Và cuối cùng, do xung đột, hoạt động hợp nhất không thành công.

Đây là những tình huống mà chúng ta phải đào sâu vào mã và xem những gì phải làm.

Trong trường hợp không chắc rằng bạn đã bỏ qua những thông báo cảnh báo này khi xung đột xảy ra, Git cũng sẽ thông báo cho bạn bất cứ khi nào bạn chạy git status:

$ 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/rm <file>..." as appropriate to mark resolution)
	deleted by us:   error.html
	both modified:   index.html

Nói cách khác: đừng lo lắng về việc không nhận thấy xung đột hợp nhất. Git đảm bảo rằng bạn không thể bỏ qua chúng.

Cách hoàn tác xung đột trong Git và bắt đầu lại như thế nào?

Cách hoàn tác xung đột trong Git
Có thể bắt đầu lại và trở về trạng thái trong sạch trước khi xung đột trong Git xảy ra

Xung đột hợp nhất đi kèm với một không khí khẩn trương nhất định. Và đúng như vậy: bạn sẽ phải giải quyết chúng trước khi bạn có thể tiếp tục công việc của mình.

Nhưng mặc dù bỏ qua chúng không phải là một lựa chọn, “giải quyết xung đột hợp nhất” không nhất thiết có nghĩa là bạn phải giải quyết chúng. Bạn cũng có thể hoàn tác chúng!

Điều này có thể đáng để lặp lại: bạn luôn có tùy chọn để hoàn tác xung đột hợp nhất và quay lại trạng thái trước đó. Điều này đúng ngay cả khi bạn đã bắt đầu giải quyết các tệp xung đột và thấy mình đang đi vào ngõ cụt.

Trong những tình huống này, bạn nên nhớ rằng bạn luôn có thể bắt đầu lại và trở về trạng thái trong sạch trước khi xung đột xảy ra.

Với mục đích này, hầu hết các lệnh đi kèm với một tùy chọn –abort, ví dụ git merge –abort và git rebase –abort:

$ git merge --abort
$ git status
On branch main
nothing to commit, working tree clean

Điều này sẽ cung cấp cho bạn sự tự tin rằng bạn thực sự không thể lộn xộn. Bạn luôn có thể hủy bỏ, trở lại trạng thái sạch sẽ và bắt đầu lại.

Xung đột thực sự trông như thế nào trong Git?

Bây giờ, hãy xem xung đột thực sự trông như thế nào dưới code. Điều này sẽ làm sáng tỏ những người gây ra lỗi nhỏ đó, đồng thời, giúp bạn mất đi sự tôn trọng đối với họ và tự tin vào bản thân.

Git đủ tốt để đánh dấu khu vực có vấn đề trong tệp, bao quanh nó bằng <<<<<<< HEAD và >>>>>>> [other/branch/name]. Nội dung xuất phát sau điểm đánh dấu đầu tiên bắt nguồn từ nhánh làm việc hiện tại của chúng ta. Cuối cùng, một dòng với các ký tự ======= phân tách hai thay đổi trái ngược nhau.

Hướng dẫn cách giải quyết xung đột trong Git

Cách giải quyết xung đột trong Git
Cách giải quyết xung đột trong Git sẽ giúp tệp trông chính xác như chúng ta muốn sau khi hoàn thành

Công việc của chúng ta với tư cách là nhà phát triển bây giờ là làm sạch những dòng này: sau khi chúng ta hoàn thành, tệp phải trông chính xác như chúng ta muốn.

Có thể cần phải nói chuyện với đồng đội đã viết các thay đổi “khác” và quyết định mã nào thực sự chính xác. Có thể là của chúng ta, có thể là của họ – hoặc có thể là sự pha trộn giữa hai thứ.

Quá trình này – dọn dẹp tệp và đảm bảo rằng nó chứa những gì chúng ta thực sự muốn – không liên quan đến bất kỳ phép thuật nào. Bạn có thể thực hiện việc này đơn giản bằng cách mở trình soạn thảo văn bản hoặc IDE và bắt đầu thực hiện các thay đổi của mình.

Sau khi dọn dẹp tệp – theo cách thủ công hoặc trong Git GUI hoặc Công cụ hợp nhất – chúng ta phải commit điều này giống như bất kỳ thay đổi nào khác:

  • Bằng cách sử dụng lệnh git add <filename> trên tệp bị xung đột (trước đó), chúng ta thông báo cho Git rằng xung đột đã được giải quyết.
  • Khi tất cả các xung đột đã được giải quyết và được thêm vào vùng tổ chức, bạn cần hoàn thành việc giải quyết bằng cách tạo một commit thường xuyên.

Có thể giảm thiểu xung đột bằng cách các thành viên trong nhóm tránh làm việc trên cùng một branch. Thay vào đó mỗi người nên có branch riêng cho từng tính năng của hệ thống.

Merge Git là gì?

Trong hệ thống quản lý phiên bản Git, merge là quá trình kết hợp các thay đổi từ hai hoặc nhiều nhánh khác nhau thành một nhánh duy nhất. Thực hiện merge giúp cập nhật lịch sử và mã nguồn của một nhánh để bao gồm các thay đổi từ một nhánh khác.

Cụ thể, quá trình merge trong Git có thể được thực hiện theo một số cách, nhưng thường là sử dụng các lệnh như git merge hoặc git pull:

  • git merge: Lệnh này được sử dụng để kết hợp các thay đổi từ một nhánh vào nhánh hiện tại. Ví dụ, để merge từ nhánh feature-branch vào main
  • git pull: Lệnh git pull có thể thực hiện merge cùng với việc lấy các thay đổi từ một nhánh xa (remote branch). Điều này giúp cập nhật nhánh hiện tại với các thay đổi mới nhất từ nhánh xa.

Git cherry pick là gì?

Git cherry pick là gì
Git cherry pick là một lệnh được sử dụng để chọn lựa (pick) một hoặc nhiều commit từ một nhánh và áp dụng chúng lên một nhánh khác

Cherry pick git là gì? Git cherry pick là một lệnh được sử dụng để chọn lựa (pick) một hoặc nhiều commit từ một nhánh và áp dụng chúng lên một nhánh khác. Quá trình này cho phép bạn chọn lựa những thay đổi cụ thể từ một chuỗi commit và áp dụng chúng lên một nhánh khác mà không cần merge toàn bộ nhánh.

Cú pháp:

git cherry-pick <commit-hash>

Rebase trong Git là gì?

Rebase git là gì? Rebase trong git là phương thức để điều chỉnh và sắp xếp lại lịch sử commit trong một nhánh. Quá trình rebase thường được sử dụng để làm cho lịch sử commit trở nên gọn gàng và dễ đọc hơn, đặc biệt là khi làm việc với nhánh feature hoặc topic.

Khi bạn thực hiện rebase, bạn đang thay đổi lịch sử commit bằng cách chọn một commit cũ và áp dụng lại các thay đổi của commit đó lên trên đỉnh của một nhánh khác hoặc commit khác. Quá trình này giúp tạo ra một lịch sử commit tuyến tính hơn, mà không tạo ra các merge commit thừa.

Cú pháp:

git checkout feature-branch
git rebase target-branch

Git merge abort là gì?

Khi bạn thực hiện một quá trình merge và xảy ra sự cố hoặc bạn muốn hủy bỏ quá trình merge đang diễn ra, bạn có thể sử dụng lệnh git merge –abort để hủy bỏ (abort) quá trình merge và đưa nhánh trở lại trạng thái trước khi bắt đầu merge. Đó gọi là git merge abort.

Cú pháp:

git merge –abort

Kết lại

Trên đây là toàn bộ chia sẻ của Comdy về xung đột trong Git và cách giải quyết. Hi vọng những thông tin, kiến thức trong bài viết này là bổ ích, ý nghĩa với mọi người. Xin cám ơn!

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *