Merge và Rebase ???

brian
5 min readApr 8, 2018

--

Chào mọi người !!! Cũng một thời gian khá lâu rồi mình mới ngồi để viết cái gì đó… Thật sự là do bận đủ các thứ trên đời (đúng hơn là do lười :3 ). Sau một hồi đấu tranh suy nghĩ thì mình bắt đầu mở Medium lên và type.

Chủ đề hôm nay mình muốn nói đến thì là một vấn đề khá quan trọng cho giới developer, nhưng mà nó chả liên quan gì tới iOS :)) Chắc hẳn từ lúc ngồi mòn đít ở trên ghế trường đại học, cho tới lúc đi làm trải qua biết bao nhiêu khó khăn gian khổ thì ai cũng sẽ biết tới source control và biết nó là một công cụ hữu ích thế nào, cụ thể ở đây là Git, rồi những thần chú đi cùng để làm việc với source control đó (commit, add, push, bla bla…) Và bài viết này mình sẽ nói về hai câu thần chú không thể thiếu trong quá trình tầm sư học đạo, có thể dẫn tới hậu quả cực kì nghiêm trọng, bị chửi lên bờ xuống ruộng, bị đày sống kiếp khổ sai, và tệ hơn là bị trục xuất khỏi môn phái (mà không phải là do đẹp trai :v) nếu không hiểu một cách rõ ràng. Và đó là MERGE REBASE.

Thiệt ra là lúc nãy trên đường đi làm về mình mới sực nhớ là bữa giờ sử dụng Git không nhiều, toàn commit code trên một cái feature branch rồi lại pull request, rồi abc xyz,…:v Mình nghĩ lại, hình như mình quên mất rebase là gì :))) ?? Rebasemerge thì khác gì nhau??? Lúc nào nên sài cái nào ??? WTFFF ????? Thật ra vấn đề này trước mình có research, đọc rồi, hiểu rồi, mà thời gian sau chả sài nên cũng quên mất tiêu. Nay quyết định take note lại để lần sau đọc cho dễ (nói chứ cũng cay thật :v)

Trước hết, nói đến chức năng của cả rebase và merge, thì chúng có chức năng khá tương đồng nhau là để tích hợp các thay đổi từ các branches vào một base branch (ở đây có thể hiểu là master). Nói là nói vậy, nhưng mà cách tổ chức và hoạt động của hai cái hoàn toàn khác nhau. Mình sẽ đi lượt qua từng cái.

MERGE

Khi sử dụng merge để tích hợp 2 nhánh với nhau. Câu lệnh merge sẽ lấy snapshot mới nhất của mỗi branch rồi combine với nhau để tạo ra một merge commit. Merge commit sẽ có parents là từ 2 nhánh khác nhau. Vậy đơn giản, mỗi khi merge một feature branch về master branch thì nó sẽ tạo ra một merge commit và bỏ vào master branch, việc làm này khá đơn giản. Nhưng thử tượng tưởng, nếu chúng ta có hàng chục feature branches, thì lúc merge vào master branch phải tạo ra hàng chục merge commit và mỗi commit đó sẽ có parents là 1 feature branch và master branch. Việc này dẫn tới cây trên git của bạn sẽ cực kì rối, khó nhìn và đau mắt :)) Dưới đây là một ví dụ:

Nhưng mà cách này lại giúp chúng ta trace được là những changes trên master đến từ branch nào để giúp cho việc tìm kiếm và sửa lỗi (nếu có) được dễ dàng hơn.

REBASE

Trái ngược với cách đau mắt ở trên, khi sử dụng rebase chúng ta lại có được một cái history dễ nhìn hơn, thẳng hàng, đẹp đẽ hơn. Vậy thì cách hoạt động của rebase khác gì merge???… Khi chúng ta sử dụng rebase, thì lúc cần tích hợp và nhánh master, nó sẽ đem tất cả các changes từ nhánh feature hay nói cách khác copy tất cả các changes từ nhánh feature đặt lên đầu của master. Cách này có vẻ khá nặng nề, thay vì lấy tất cả các changes từ commit mới nhất của nhánh feature thì nó lại đi chạy từ đâu đến cuối => rewrite. Có thể hiểu là nó sẽ lấy tất cả các commit từ lúc chúng ta tách nhánh feature từ master, rồi đem từng commit đó đặt lên lần lượt lên master theo đúng thứ tự, do đó nên trên cây của master chúng ta có thể thấy được tất cả từng commit trên feature branch thay vì 1 merge commit duy nhất so với cách merge.

So sánh merge và rebase

MERGE HAY REBASE ??

Best practice khuyên là:

  • Rebase origin/branch vào branch (pull)
  • Merge feature branch vào master (hoặc một shared branch nào đó)

Nếu là người không rành và có kinh nghiệm làm việc với rebase thì merge sẽ là cách làm an toàn hơn, nó sẽ không phá mất cái history của repo, cho nên với cách merge cho một shared branch thì việc nhiều người làm chung trên một branch sẽ không xảy ra sự cố, mặc dù history sẽ khá nhập nhằng. Nếu sử dụng rebase không đúng cách nó có thể gây nguy hiểm, nếu người khác sử dụng chung branch đó mà không rebase khi pull, điều này có thể gây ra mất commit của người đó. Còn việc lựa chọn sử dụng merge hay rebase nó phụ thuộc vào git flow của project đó, nhưng người bên đội SA hoặc PM sẽ quyết định nên sử dụng cái nào. Như vậy tóm lại

  • Rebase: nếu muốn một history rõ ràng dễ nhìn, hay còn gọi là linear history, và tránh được trường có thêm các merge commit
  • Merge: nếu muốn lưu vết cũng như bảo toàn được history của repo (vd: xem được commit này là từ branch nào,…)và tránh trường hợp rewrite lại tất cả các changes.

Reference:

Merging vs Rebasing — Atlassian

When to merge, when to rebase

Merge or Rebase — Atlassian

Mình xin cảm ơn các bạn đã dành thời gian để đọc hết những dòng mình viết ra. Hẹn mọi người vào bài viết sau. Nếu có bất cứ sai sót gì trong bài thì mọi người hãy comment để cho mình biết và chỉnh sửa nhé ❤

--

--

brian

a software engineer who does software engineering