Pull request hay gọi tắt viết tắt là PR là gì ?
Thuật ngữ này đã quá thân thuộc với những người dân làm dev như tất cả chúng ta khi mà tất cả chúng ta sử dụng nó gần như hằng ngày hằng giờ thậm chí là là vài phút một lần cũng đều có thể nghe những câu đại loại như “Anh êiiiii, review giúp em cái pull request XXX điiiiiii”. Tuy nhiên dù là dùng quá thường xuyên như vậy nhưng bạn có thật sự hiểu hết về nó, mục tiêu tạo PR, tạo PR ra sao cho thật xịn hay review PR ra sao là nhanh và đúng cách nhất. Hôm nay, qua nội dung bài viết này mình xin được san sẻ một số sự hiểu của mình về PR mà mình từng có thông qua những trải nghiệm thực tế trong dự án mình từng làm. Mọi người sau lúc đọc xong nội dung bài viết này hãy cùng san sẻ những kinh nghiệm với PR với mình và nhé. Mở màn thôi nào!
Pull request hay PR là khái niệm không liên quan đến logic source code và thường được quan tâm sau hết khi dev đã hoàn thành việc code và sẵn sàng chuyển tiếp sang bước để mọi người review, tuy nhiên “Last but not least” – đây gần như thể bước cuối cùng quan trọng không kém để lấy source code của mỗi dev tất cả chúng ta đến gần với team với khách hàng vì với những dự án có khách hàng trực tiếp review source code thì dù logic và code của bạn có xịn đến mấy nhưng bạn không gởi PR đúng chuẩn đã được define theo rule thì khách hàng cũng sẽ sẵn sàng reject ngay không cho merge vào source code chung đâu nhé nhé
Vì sao mình lại dùng câu “đưa source code của mỗi dev tất cả chúng ta đến gần với team với khách hàng” ?
Vì thực tế khi chúng ta thao tác làm việc trong team có nhiều người, mỗi một chức năng bạn hoàn thành code và cần được team review, bạn không thể gọi mọi người đến máy tính của bạn và ngồi đấy review từng dòng code cho bạn đâu nhỉ. Bạn cũng không thể gởi từng file source code cho tất cả những người review để họ tải về về máy và review được – quá tốn thời kì và thật sự không chuyên nghiệp. Và tất nhiên khi khách hàng (đang ở một nơi nào đấy rất rất xa bạn) muốn tham gia review code của bạn thì chuyện này càng khó khăn hơn. Đó là lúc cần dùng đến Pull request.
Pull request được tạo ra để lấy những file source code của bạn lên 1 host chung nơi mọi người dân có quyền truy cập sẽ truy cập vào và cùng review, để lại comment trên những file source code đó. Lúc này thời kì review và địa điểm review source code không còn là một vấn đề – đó cũng đây chính là mục tiêu tạo ra pull request!
Sẵn sàng chuẩn bị PR hay nói xác thực hơn là chuẩn bị sẵn sàng branch để thực hiện pull request. Việc chuẩn bị sẵn sàng một branch tốt hỗ trợ cho mọi thứ trở thành dễ dàng hơn. Nếu như khách hàng lỡ có quên tạo branch mới mà update source trên branch cần merge thì hãy yên tâm, Git có sẵn chức năng để giúp đỡ bạn chuyển những thay đổi này sang branch mới, đó là stash. Nếu như khách hàng chưa chắc chắn gì về stash thì có thể xem tại đây
Vậy ra sao là một branch tốt?
Thứ nhất, vững chắc là naming. Tên branch phải thể hiện mục tiêu của việc update. Cái tên nói lên tất cả, nó sẽ hỗ trợ cho reviewer có thể nắm bắt nhanh chóng bạn đang làm gì. Thông thường mình sẽ tạo tên format sau:
<typevàgt;_vàlt;issue idvàgt;_vàlt;tên issuevàgt;
Trong số đó:
- Type: thể hiện mục tiêu của branch. Type có thể là Feature, Fix, Refactor, Test…
- issue id (hoặc task id, story id…) đã được define trên git hay trên các trình quản lý project như redmine, trello… Chỉ nên biết issue id là có thể xác định được những yêu cầu, từ đó có thể nắm được cần review cái gì
- tên issue: mô tả ngắn gọn mục tiêu của issue. Vì nhìn vào issue ID không thể biết ngay bạn đang làm gì nhưng chỉ có nhìn thêm tên issue hẳn ai cũng nắm được cơ bản công việc của bạn
Ví dụ như Fix_B223_ CSV_Download_Wrong_Date: nhìn vào cũng đoán được đây là branch để fix bug 223 về lỗi file csv tải về nhầm ngày.
Nếu như khách hàng có lỡ đặt tên branch sai cách thì đừng lo việc thay tên branch rất dễ dàng với 2 command sau:
# nếu ở tại branch muốn thay tên git branch -m newName # nếu đang ở branch khác git branch -m oldName newName
Thứ hai, đảm nói rằng branch của bạn phải update dựa trên lastest source của branch cần merge. Việc này sẽ giúp tránh những conflict không cấp thiết. Thỉnh thoảng task bạn đang làm mất đi vài ngày mới hoàn thành thì trong khoảng tầm thời kì đó có tới hàng chục nghìn commit đã được merge. Bạn có đảm nói rằng sẽ không còn có ai conflict với bạn không. Chính vì thế việc phát triển source code dựa trên lastest source là điều cấp thiết. Để làm được điều này, bạn cần phải thiết phải rebase source code thường xuyên. Không nhất thiết phải rebase mỗi lúc có một commit mới nhưng bạn phải chắn chắc mình không được để lỡ quá nhiều commit. Mặc dù việc này khá là phiền toái nhưng lợi ích của nó sẽ mang lại lơn hơn nhiều:
- phát hiện conflict và resolve nó ngay tức thời. Việc này giúp tiết kiệm ngân sách khá nhiều thời kì vì chỉ resolve dựa trên số ít commit.
- tăng tính khả dụng của source code, code của bạn cũng có thể hoạt động ngay tức thời khi được merge
Và để rebase source code, rất đơn giản, tuân theo các bước phía dưới nhé
- commit source code ở branch của bạn
- vận chuyển sang branch chính bằng git checkout <branchvàgt;, fetch (git fetch) và pull lastest source về (git pull)
- vận chuyển về branch của bạn
- thực hiện lệnh sau git rebase <branch-originvàgt;
- Resolve conflict nếu có
Thứ ba, đó cũng là bước cuối cùng của việc chuẩn bị sẵn sàng PR, đó đây chính là squash commit. Việc bạn push commit lên branch của bạn là điều khôn cùng thường nhật, như mình cứ mỗi lần code xong cái gì mình lại push lên branch, việc này tránh bị mất code nếu như có sự cố gì xẩy ra. Tuy nhiên khi thực hiện xong, nhìn lại branch, thì hàng tá commit như vậy có thể khiến mọi thứ trở thành rối tung lên. Vì khi merge vào branch chính thì nó sẽ merge từng commit của bạn. Càng nhiều commit thì khả năng phát sinh conflict giữa các commit càng cao. Sau lúc merge, nhìn vào graph trên Git thì ôi thôi cái đống gì thế này.
Chẳng hạn bạn thích cái nào hơn khi xem history trên branch develop
1256556316… Merge pull request #423 from jrandom/add-slideshows 7hgf8978g9… Added new slideshow feature, JIRA # 848394839 85493g2458… Fixed slideshow display issue in ie gh354354gh… wip, done for the week 789fdfffdf… minor alignment issue 56556316ad… Merge pull request #324 from ahacker/fix-android-display 787g8fgf78… hotfix for #5849564648 f56556316e… Merge pull request #28 from somwhere/select-lang-popup 9080gf6567… implemented feature # 65896859 gh34839843… minor fix (typo) for 3rd test
hay
1256556316… Merge pull request #423 from jrandom/add-slideshows 7hgf8978g9… Added new slideshow feature 56556316ad… Merge pull request #324 from ahacker/fix-android-display 787g8fgf78… Hotfix for android display issue f56556316e… Merge pull request #28 from somwhere/select-lang-popup 9080gf6567… Implemented pop-up to select language
hay
1256556316… Merge pull request #423 from jrandom/add-slideshows 56556316ad… Merge pull request #324 from ahacker/fix-android-display f56556316e… Merge pull request #28 from somwhere/select-lang-popup
Việc squash commit từ nhiều commit thành ít commit hơn hoặc thành 1 commit không những giúp graph trở thành đẹp hơn mà còn tồn tại thể giúp phát hiện lỗi dễ dành hơn bởi vì càng ít commit càng dễ xác định được đâu là nguyên nhân gây lỗi. Về phong thái squash commit, bạn cũng có thể tham khảo tại đây.
Sau lúc chuẩn bị sẵn sàng branch cần merge thì tiếp theo tất cả chúng ta sẽ tạo một PR. Thời đoạn chuẩn bị sẵn sàng cũng là thời đoạn tốn nhiều công sức của con người nhất và vất vả nhất. Và một khi chuẩn bị sẵn sàng tốt các thời đoạn tiếp theo sẽ đơn giản hơn rất nhiều. Như tạo PR, bạn chỉ có lưu ý đến những vấn đề sau.
Commit message
Khi tạo PR, trước tiên bạn cần phải check lại các commit của mình. Như khâu chuẩn bị sẵn sàng đã đề cập ở trên, thì lúc này bạn chỉ có một commit duy nhất sau lúc squash các commit. Lúc này, bạn muốn thể hiện sự thay đổi trong source code ở commit đấy thì chỉ có thể thông qua commit message. Mặc dù tên branch thể hiện được mục tiêu của việc thay đổi nhưng việc làm thế nào để đạt được mục tiêu thì nó phải cần đến commit message. Điều này hỗ trợ cho reviewer hoàn toàn hình dung được bạn thực hiện thay đổi ra sao thông qua các thông tin được viết trong commit message. Khi tạo pull request, những thông tin ở commit message cũng sẽ tự động hóa fill vào phần description nên bạn không cần tốn thời kì để viết thêm thông tin bởi vì như vậy là quá đủ.
Để viết commit message một cách rõ ràng thì bạn nên tham khảo tại đây
Review các thay đổi trên source
Mặc dù đã review ở bước chuẩn bị sẵn sàng nhưng khi tạo pull request, bạn cũng cần phải xem những thay đổi của mình với source ngày nay. Hãy xem lại một cách kĩ lưỡng vì có thể các bạn sẽ nhận ra những lỗi mà trước đó mình lại bỏ qua.
Add reviewer
Và tiến độ cuối cùng trước lúc tạo pull request đó là xác định reviewer. Việc thêm họ vào pull request hỗ trợ cho reviewer nhanh chóng nhận được những thông tin liên quan đến pull request. Tuy nhiên hãy nhờ rằng share PR cho những dev khác để họ có thể nắm được những thay đổi nhằm tránh các conflict phát sinh và họ hoàn toàn có thể trở thành reviewer hỗ trợ cho PR của bạn trở thành tốt hơn.
Cuộc đời dev đâu phải lúc nào thì cũng căm mặt code rồi tạo PR. Đôi lúc tất cả chúng ta cũng phải review vài cái PR để trở thành xịn xò. Vậy review PR là review cái gì? Và review ra sao cho đúng?
Trước hết chắc chắng là review code rồi. Nhìn chung thì so với updated source code, mình thường lưu ý những điểm sau:
- Coding convenstion, đảm bảo việc naming, format phải đúng với quy định đã đề ra từ trước.
- Kiểm tra trong code có còn xót các xử lý dư thừa như comment pseudo code, debugger hay là những khối lệnh bị comment out
- Check một số vấn đề về clean code: code xử lý trùng lặp, logic phức tạp, xử lý exception ko tốt… dựa trên các principle như SOLID, DRY, KISS…
- Đặc biệt quan trọng cần lưu ý đến unit test. Với mình thì mọi dòng code cần phải được test. Điều đó giúp bản thân dev có tránh nhiệm hơn với chất lượng sản phẩm và dịch vụ code của mình.
Thứ hai, đó là có đúng requiment hay là không. Code ngon mà chạy ko đúng thì hẳn là một chuyện gì đó rất xàm. Việc này yên cầu bạn có khả năng đọc code tốt, từ đó nắm được logic và thuật toán xử lý. Và tất nhiên là để đảm bảo nó có đúng hay là không thì bạn phải checkout branch đó về và thực hiện run test các kiểu trên local dựa trên requiment của khách hàng.
Cuối cùng là kiểm tra nó có tác động đến những phòng ban khác hay là không? Việc này yên cầu phải có sự review phối hợp của những bên liên quan và trên hết là khối hệ thống integration test để đảm bảo mọi thứ liên quan đến update trong PR sẽ vẫn hoạt động tốt.
Tuy nhiên, hiện nay thì reviewer hồ hết đều không có thời kì cho việc test. Thậm chí là việc review code và logic xử lý đã và đang lấy hết thời kì rồi. Nên việc tạo unit test và integration test hay automation test trở thành yêu cầu bắt buộc. Từ đó tất cả chúng ta có thế uỷ thác cho khối hệ thống CI build và run test để tiết kiệm ngân sách thời kì hơn trong khâu review PR. Tất cả chúng ta chỉ có dành thời kì cho việc review code và các testcase của unit test, integration test…
Yeah, sau tất cả đây chính là complete PR. Và việc này tưởng chừng đơn giản như thực tế lại không hề đơn giản chút nào. Trước hết bạn cần phải phải resolve toàn bộ comment của reviewer để PR được approve merge. Việc update vững chắc sẽ tạo ra những commit mới và cần phải được review. Vì thế tất cả chúng ta cũng nên thực hiện toàn bộ cái thao tác đề cập ở trên để đảm bảo PR của bạn luôn trong trạng thái sẳn sàng hoạt động và tất nhiên là hoạt động tốt là đằng khác. Cho tới lúc tất cả comment đều được xử lý ổn thỏa thì lúc này là lúc mà bạn quyết định phương pháp merge branch của bạn để hoàn thành PR. Đây là điều rất khó. Nó yên cầu bạn phải nắm rõ sự khác nhau giữa những phương pháp merge PR. Tuy tất cả đều là merge nhưng thực chất merge là khác nhau và việc hiển thị trên graph cũng khác nhau. Ai trong tất cả chúng ta cũng đều thích một graph đẹp và dễ dàng quản lí, nên việc lựa chọn lựa cách nào để merge sao cho phù hợp là vấn đề lớn.
Về những phương pháp merge PR các bạn tham khảo tại đây
Sau lúc merge PR thì lúc này branch của bạn đã được xóa. Tuy nhiên trên local vẫn còn nên hãy lưu ý là xóa cả nó luôn nhé. Nếu cẩn thận bạn cũng có thể tạo bản backup trước lúc xóa tuy nhiên thì việc backup hoàn toàn thừ thải. Mặc dù branch của bạn đã được xóa tuy nhiên nó vẫn được lưu thành một commit trên branch chính và bạn hoàn toàn có thể revert những thay đổi trong commit đó nếu có lỗi xẩy ra và có thể thực hiện cherry pick những commit quan trọng trong quá trình sửa lỗi sau đó.
Và điều cuối cùng mình muốn nói là dù cho bạn đã hoàn thành PR của mình, branch của bạn đã được xóa thì không có tức là bạn hết trách nhiệm với nó. Hãy test sau lúc merge và thậm chí là cả khi lên product. Luôn lưu ý đến những bug phát sinh sau khi chúng ta merge source vì rất có thể nó liên quan đến PR của bạn. PR xong nhưng bạn thì chưa xong. Nhớ điều này nhé.
Thật sự so với một số bạn cũng có thể nghĩ “pull request ấy mà, chỉ là hình thức thôi, quan trọng là logic là code xịn”. Tuy nhiên, với bản thân mình, mình nghĩ khi thao tác làm việc cùng team thì việc hỗ trợ cho công việc của nhau hoàn thành trôi chảy mới là thứ quan trọng nhất. Việc tạo ra 1 pull request “xịn” sẽ góp phần hỗ trợ cho việc thao tác làm việc với team trở thành nhanh chóng và mượt mà hơn đấy.
Trên đây là những hiểu biết thực tế của mình về pull request, còn các bạn thì sao, các bạn có những kinh nghiệm và tip gì khi thao tác làm việc với pull request không, hãy comment cho mình học tập thêm nhé!
https://help.github.com/en/articles/about-pull-requests