Merge git là gì

  • Git merge được dùng khi ta muốn gộp hai branch lại với nhau, thao tác này thường dùng để merge branch khác vào branch master trước khi push lên remote repository, hoặc merge hai branch thành một để giải quyết chung một task.
$ git merge <branch_name>

hoặc

$ git merge <branch-name> <merged-branch-name>

Ví dụ tình huống sử dụng “git merge”

Hãy hình dung chuyện sẽ xảy ra khi chúng ta bắt đầu làm việc trên một tính năng mới, trên feature branch, sau đó team khác commit code mới lên master branch.

Cái commit mới trong master liên quan đến feature chúng ta đang làm. Để lấy commit mới này từ master và đưa về feature branch đang làm, chúng ta có 2 lựa chọn: merge hoặc rebase

Lựa chọn merge

git checkout feature git merge master //hoặc viết bằng một dòng luôn git merge master feature

Kết quả là nó sẽ tạo ra một merge commit mới trên feature branch, Chúng ta có một cấu trúc như sau

Nói một cách khác, feature branch sẽ có thêm một stage cần commit. Nếu master bị thay đổi thường xuyên, liên tục, cái history của feature branch có thể sẽ rất lộn xộn, mặc dù có thể xử lý bằng git log, tuy nhiên các bạn developer khác sẽ rất khó mà hiểu được history của project

Lựa chọn rebase

Một lựa chọn khác với merge, là dùng rebase
(Vấn đề này không liên quan đến git merge, nhưng được nói thêm ở đây để hiểu thêm về lệnh git rebase)

git checkout feature git rebase master

Nó sẽ đưa toàn bộ feature branch lên trên cùng của master.

Lợi ích của dùng rebase là chúng ta có history của project sạch sẽ hơn. Sẽ không có những merge commit dư thừa như trong lệnh merge. Nhưng trong tình huống này thì đừng bao giờ dùng rebase nhé, xem tiếp để biết lý do..

Đừng bao giờ chọn “git rebase” cho tình huống này

Hãy thử đoán xem chuyện gì xảy ra nếu chúng ta rebase master vào feature branch

Lệnh rebase sẽ đưa toàn bộ commit của master xuống feature. Vấn đề là cái này chỉ nằm trên local repository của chúng ta. Tất cả những dev khác sẽ tiếp tục làm việc trên master gốc. Git lúc này sẽ hiểu history master của chúng ta không phụ thuộc vào những người khác.

Cách duy nhất để sync lại 2 master branch là merge chúng lại. Bạn đã thấy sự rắc rối chưa?

Cân nhắc trước khi lựa chọn rebase

Trước khi chạy lệnh git rebase, luôn hỏi chính mình “Có đứa nào đang làm việc trên branch này?” Nếu câu trả lời là có, rút tay khỏi bàn phím và nghĩ đến giải pháp an toàn hơn như git revert

Bài viết được sự cho phép của tác giả Lưu Bình An

Merge và Rebase là 2 công cụ để trộn 2 branch trong Git, mục đích sử dụng cho những tính huống khác nhau.

Một tình huống phổ biến khi sử dụng merge

  • Tạo nhánh my-new-feature từ nhánh master
  • Commit nhánh my-new-feature với một số thay đổi
  • Tạo Pull Request: my-new-feature vào master

  10 Vấn đề về Git thường gặp và Giải pháp

  Sự khác biệt giữa ‘git merge’ và ‘git rebase’ là gì?

Sau khi my-new-feature được merge vào master, chúng ta sẽ có

Đó là trường hợp lý tưởng rất ít khi xảy ra, 99.999999% là my-new-feature có vài điểm cần bổ sung sau khi review code, bug chẳng hạn, sai chính tả chẳng hạn.

  • Chúng ta bổ sung 2 commit C6 và C7 vào nhánh my-new-feature
  • Trong lúc đó, master cũng có thêm 2 commit C8C9 được merge vào bởi 2 bạn đồng nghiệp
  • Cuối cùng PR của chúng ta cũng được merge

Cái history lúc này (vẫn ok chứ không vấn đề gì)

Tuy nhiên, cũng là một tính huống rất hay gặp luôn, chúng ta ôm nhánh my-new-feature gần một tuần mà chưa xong, và chúng ta muốn có C8C9 đã được merge, và một cách chủ quan duy ý chí, dân dev chúng ta muốn có một cái history thật sạch đẹp, theo kiểu từng commit C4, C5, C6, C7,… là từng công việc rất cụ thể và độc lập, chúng ta không muốn gom hết một lượt đến cuối sprint rồi commit toàn bộ file là điều khiến người review code vô cùng mệt não.

Rebase giúp được gì ở tình huống này?

Năm 2016 Github giới thiệu một cách merge PR mới: Rebase and merge (Gitlab sẽ là Rebase front door). Nó cho phép chúng ta thực hiện một thao tác rebase trên commit PR rồi mới thực hiện việc merge. 2 thao tác này hoàn toàn độc lập và luôn đúng theo thứ tự rebase trước, merge sau, chứ ko có ngược lại.

Tương tự như nút Rebase and merge, nếu dùng command

git checkout my-new-feature git rebase master git checkout master git merge my-new-feature --ff

Bằng cách đó, history lúc này là một đường thẳng tắp

Rebase không phải để thay thế merge, rebase dùng để thực hiện trên nhánh feature – private branch của chúng ta, merge thực hiện trên master – share branch với đồng nghiệp

Việc rebase -> merge như thế sẽ tránh mất đi những commit C4, C5, C6, C7 trên history của nhánh master, như khi chỉ dùng một lệnh merge. Chúng ta bê nguyên cái history của nhánh my-new-feature lên luôn.

Vấn đề thứ 2, làm sao để sync nhánh my-new-feature với master (có C8, C9)?

/* lấy những thay đổi mới */ git fetch /* checkout nhánh chúng ta muốn sync với master */ git checkout my-new-feature /* thực hiện sync với master */ git rebase origin/master

Giữ nhánh my-new-feature cập nhập với những thay đổi mới nhất ở nhánh master để tránh quá nhiều conflict xảy ra khi tạo PR

Nút Rebase and merge không được yêu thích lắm, vì nó tạo quá nhiều conflict, nên chúng ta vẫn thường ưu ái merge hơn.

Để có một history thẳng hàng, đầy đủ tốn khá nhiều mồ hôi chứ không dễ như ăn bánh.

Video liên quan

Chủ đề