Tìm hiểu về Git
January 7, 2022Đối với mọi lập trình viên, Git là người bạn đồng hành không thể thiếu của mỗi chúng ta khi xây dựng và phát triển sản phẩm. Vậy Git là gì? Những kiến thức nào về Git các kỹ sư cần phải biết?
Git là gì?
Khi viết code, sẽ có rất nhiều lúc bạn muốn, hoặc cần phải quay lại đoạn code mình đã viết tại một thời điểm trước đây. Một cách đơn giản, ta hoàn toàn có thể dùng tính năng undo/redo của trình biên soạn (editor) mình đang dùng. Tuy nhiên, editor có thể sẽ không lưu lại lịch sử sau khi đóng, và bạn cũng có thể nhấn nhầm sang một phím khác thay vì nhấn redo, và thế là lịch sử trạng thái được editor lưu lại đã bị ghi đè khiến bạn không thể redo được nữa.
Ngoài ra, khi nhiều người cùng làm việc trong một dự án, các thành viên cần tìm ra cách chia sẻ các thay đổi của mình để đảm bảo rằng tất cả mọi người đang làm việc trên cùng một phiên bản của dự án. Trước đây, lập trình viên thường chia sẻ các thay đổi code bằng cách xuất ra file patch và gửi cho nhau qua email. Khi nhận được một bản patch, các thành viên sẽ áp dụng nó vào trong phiên bản code hiện tại của mình trên máy cá nhân.
Mỗi file patch chỉ biết đến hai trạng thái của dự án, là trước và sau khi được trích xuất ra. Như vậy, khi có nhiều file patch, ta cần phải biết thứ tự của chúng để có thể xây dựng lại chính xác một phiên bản của dự án tại bất kì thời điểm nào. Ngoài ra, vì file patch cũng chỉ là file thông thường được lưu trong ổ cứng, nên ta cần một cách để sao lưu lại chúng. Khi có nhiều người cùng làm việc trên một file, ta cần thêm một cơ chế đồng bộ các file patch với nhau, vì rất có thể sẽ có những thay đổi chồng chéo lên nhau.
Git (https://git-scm.com/) là một hệ thống quản lý phiên bản phân tán (distributed version control system), được viết bởi Linus Torvalds (người tạo ra và phát triển chính của Linux kernel) vào năm 2005. Mục đích ban đầu của Git là để hỗ trợ việc phát triển Linux kernel. Ngoài Git còn có các hệ thống khác như Subversion và Mercurial.
Git hỗ trợ các lập trình viên bằng cách lưu lại toàn bộ các thay đổi với dự án, được chia nhỏ thành các commit. Mỗi commit là một đơn vị thay đổi, tương tự như một file patch. Tại mỗi commit, ta có một phiên bản của dự án. Bằng việc lưu lại toàn bộ thay đổi trong một hệ thống riêng biệt, ta hoàn toàn có thể quay lại bất cứ phiên bản nào tại thời điểm mà commit được tạo ra. Ngoài ra, Git cũng hỗ trợ làm việc nhóm thông qua tính phân tán (distributed).
Khi làm việc với một dự án, ta sẽ tạo ra một Git repository (kho chứa), thường được gọi tắt là repo. Đây là nơi chứa toàn bộ các thông tin cần thiết để quản lý dự án, ví dụ như các thay đổi đã được nhắc đến ở trên.
Khi làm việc với một dự án được quản lý bởi Git, mỗi lập trình viên sẽ có một bản sao của Git repo trên máy cá nhân, và được đồng bộ với nhau thông qua một repo được lưu trữ trên máy chủ riêng biệt (remote repository). Thay vì chia sẻ các bản patch, lập trình viên sẽ tạo ra các commit, và gửi các commit này lên remote repository. Các lập trình viên khác có thể đồng bộ repo trên máy cá nhân với remote repo để thấy được các commit này, và thêm vào phiên bản của dự án hiện tại trên máy của mình nếu muốn.
Những tác dụng của Git
– Quản lý code và lịch sử thay đổi: Hãy tưởng tượng nếu bạn phát triển một tính năng mới và tạo ra một đống bug. Lúc này bạn hối hận và muốn quay đầu. Nếu không có hệ thống này, bạn sẽ phải quay lại từ đầu để dò bug và chỉnh lại cho đúng. Git sẽ giúp bạn hoàn thành những công đoạn đó chỉ với một vài dòng lệnh.
– Tiết kiệm thời gian: Ngoài tính năng giúp lập trình viên chỉnh sửa thay đổi dễ dàng, hệ thống này còn đóng vai trò quan trọng trong phát triển tính năng mới. Khi phát triển tính năng mới, bạn có thể copy mã nguồn gốc để làm backup lỡ tính năng không được như mong muốn. Tuy nhiên, nếu bạn muốn phát triển thêm 2-3 tính năng nữa thì việc này chắc chắn sẽ rất mất thời gian. Do đó lúc này bạn sẽ cần đến Git để tối giản hoá quá trình này.
– Giúp làm việc nhóm hiệu quả hơn: Một dự án sẽ bao gồm nhiều người đến từ nhiều bộ phận khác nhau. Do đó, việc dẫm lên chân nhau khi thực hiện dự án là hoàn toàn có thể xảy ra. Hệ thống này sẽ đóng vai trò quản lý hệ thống và giúp giảm thiểu mâu thuẫn giữa các bộ phận.
Sử dụng Git như thế nào?
Khi bắt đầu sử dụng Git cho một dự án, ta cần khởi tạo một Git repository trên máy cá nhân, bắt đầu với câu lệnh git init. Sau khi được khởi tạo, mọi thay đổi sẽ được Git theo dõi và quản lý. Trong trường hợp bắt đầu làm việc với một dự án đã và đang sử dụng Git, và đã có một remote repository, ta có thể tạo ra một bản sao trên máy cá nhân bằng câu lệnh git clone.
Sau khi thiết lập môi trường làm việc, ta có thể bắt đầu thao tác với Git như sơ đồ bên dưới. Local repository chính là bản sao của Git repo trên máy cá nhân, được đồng bộ với những local repo khác thông qua remote repo. Cũng trên máy cá nhân, ta còn có hai môi trường nữa là thư mục làm việc (working directory) và khu vực chờ (staging area).
Tất cả các thao tác thêm/sửa/xoá để thay đổi code sẽ được thực hiện trên thư mục làm việc. Khi muốn lưu lại những thay đổi này, ta sẽ dùng câu lệnh git add để thêm chúng từ thư mục làm việc sang khu vực chờ. Sau đó sử dụng câu lệnh git commit để lưu từ khu vực chờ vào local repository.
Tuy nhiên lúc này, những thay đổi mới chỉ đang ở local repository, tức là những lập trình viên khác không biết đến sự tồn tại của chúng. Để đưa những thay đổi này lên remote repository, ta dùng lệnh git push. Và ngược lại, dùng lệnh git pull để cập nhật những thay đổi mới nhất của người khác từ remote repository về máy cá nhân.
Một tính năng rất quan trọng khi làm việc nhóm với Git là tách nhánh (branching). Tất cả Git repository đều có một nhánh mặc định là master, nơi các commit sẽ được lưu lại ở thời điểm ban đầu. Khả năng tách nhánh của Git giúp cho các thành viên của dự án có thể làm việc độc lập vì nếu mỗi người có một nhánh riêng, các thay đổi khi được push lên remote repository sẽ không gây ra xung đột. Ta có thể kiểm tra xem nhánh hiện tại đang làm việc là gì với câu lệnh git branch, và tạo một nhánh mới với câu lệnh git checkout.
Sau khi đã tạo ra một nhánh mới, ta có thể bắt đầu commit những thay đổi lên nhánh này. Khi hoàn thành phần việc của mình trên nhánh cá nhân, ta cần tích hợp các thành phần lại với nhau thông qua việc hợp nhất các nhánh với câu lệnh git merge. Các thay đổi sau khi đã được hợp nhất lại sẽ được các thành viên pull về local repository của mình. Trong hình minh hoạ bên trên, ta có thể thấy các merge commit như Merge branch ‘release/v1.1.0’ into develop, hoặc Merge branch ‘release/v1.1.0’.
Các nguyên tắc khi làm việc với Git
Có một số nguyên tắc nhất định giúp cải thiện hiệu suất và nâng cao khả năng làm việc nhóm khi sử dụng Git để quản lý phiên bản cho dự án.
– Tách nhánh mới để làm việc. Như đã nói ở trên, việc tách nhánh mới giúp các thành viên có thể làm việc độc lập với nhau. Ngoài ra, bằng cách làm việc trên một nhánh riêng biệt, ta có thể đảm bảo rằng code trên nhánh mặc định (master) luôn là code ổn định và có thể được đưa lên môi trường production.
– Viết commit message rõ ràng, dễ hiểu. Mỗi commit đều có một message, là nơi để lập trình viên tóm tắt những thay đổi được lưu lại trong commit này. Commit message rõ ràng và tường minh giúp cho các thành viên khác có thể dễ hình dung về những thay đổi hơn khi nhìn vào git log hoặc git tree. Conventional Commits là một quy ước viết commit message thường được dùng.
– Mỗi commit chỉ nên có một trách nhiệm duy nhất. Nguyên tắc Single Responsibility (S trong SOLID) là một nguyên tắc cơ bản trong thiết kế phần mềm. Tạo Git commit là một trong nhiều tính huống khác ta có thể áp dụng nguyên tắc này. Mỗi commit chỉ nên lưu lại những thay đổi nhỏ, có liên quan trực tiếp đến nhau. Thay vì tạo ra một commit với rất nhiều thay đổi (hàng trăm dòng code và hàng chục file được thay đổi), ta nên chia ra thành nhiều commit nhỏ. Điều này giúp dễ quan sát các thay đổi, và việc quay lại một trạng thái trước đây cũng dễ dàng hơn vì lịch sử đã được chia nhỏ.
– Tránh commit những thay đổi không cần thiết, hoặc không nên được lưu lại. Giả sử rằng trong dự án của bạn cần lưu lại những cấu hình cho việc kết nối vào cơ sở dữ liệu, hoặc là khoá bí mật dùng trong việc mã hoá thông tin,… Những thông tin này tuyệt đối không được lưu lại với Git, vì một khi bạn đưa những thông tin này lên một remote repository công khai, bất cứ ai cũng có thể xem được và truy cập vào cơ sở dữ liệu của bạn,… Ngoài ra, còn những thông tin khác như các thành phần phụ thuộc của dự án cũng không nên được lưu lại, ví dụ như npm_modules khi làm việc với JavaScript, hoặc venv khi làm việc với Python.
Các tính năng khác của Git
– hooks. Hooks là một tính năng rất mạnh mẽ của Git. Với tính năng này, ta có thể thêm các hành động tuỳ chỉnh vào từng giai đoạn làm việc với Git, ví dụ như trước và sau khi commit/push,… Thường dùng nhất là pre-commit hook, được chạy trước mỗi commit. Thậm chí còn có một framework chuyên để quản lý chúng. Pre-commit hooks thường được sử dụng để format code theo một chuẩn chung (black/prettier), chạy các chương trình phân tích tĩnh (static analysis) như mypy, eslint,… để giảm thiểu lỗi.
– annotate/blame. Khi sử dụng câu lệnh này, với mỗi dòng trong một file, ta có thể biết được người gần nhất sửa dòng này là ai, và sửa vào lúc nào. Các kỹ sư ở Got It rất hay dùng để blame nhau, đúng như tên gọi của câu lệnh, ví dụ như: Chỗ này chú J, chú K viết khó đọc thế, chỗ này ai viết mà tinh tế thế, hoá ra là anh M.
– cherry pick. Khi dùng câu lệnh git merge để hợp nhất hai nhánh lại làm một, ta sẽ mang tất cả commit của nhánh tính năng vào nhánh chính. Tuy nhiên, không phải lúc nào ta cũng muốn làm vậy, chẳng hạn như khi cần deploy và test trước một số thay đổi chọn lọc từ nhánh tính năng. Đây là lúc ta sử dụng đến câu lệnh cherry-pick để copy thay đổi từ những commit cần thiết sang một nhánh khác. Đơn vị nhỏ nhất có thể cherry pick là một commit, nên nếu commit quá lớn thì ta sẽ không thể chọn ra những thay đổi cần thiết.
– Ngoài các tính năng kể trên, bạn đọc có thể tham khảo thêm các tính năng khác như submodule, stash, rebase, status, diff,…
Trên đây chỉ là những hướng dẫn rất cơ bản về Git. Bạn đọc muốn tìm hiểu sâu hơn có thể tham khảo tại những liên kết sau:
– Giới thiệu tổng quan về các tính năng của Git: https://git-scm.com/about.
– Tài liệu trên trang web chính thức của Git: https://git-scm.com/doc.
– Hướng dẫn sử dụng Git: https://www.atlassian.com/git/tutorials.
– Khoá học về Git trên Codecademy: https://www.codecademy.com/learn/learn-git.
– Git cheatsheet: https://ndpsoftware.com/git-cheatsheet.html.
Ngoài ra mình có một bài viết khác về các câu lệnh git command hữu dụng nhé
[…] lẽ mọi người đều nghe rất quen thuộc và bài viết trước mình đã đề cập tổng quan về git và những command line hữu dụng cho git, nhưng không phải ai cũng nhớ hết câu […]
[…] 8, 2022 0 By Nam Vu [General Development Skills] – Git + https://blog.ntechdevelopers.com/tim-hieu-ve-git/ + https://blog.ntechdevelopers.com/git-useful-commands/ […]