Nội dung chính
Trong lĩnh vực phát triển phần mềm ngày nay, làm việc nhóm (teamwork) giữa các lập trình viên đóng một vai trò vô cùng quan trọng. Tuy nhiên, việc nhiều người cùng tham gia vào một mã nguồn sẽ dẫn đến những khó khăn trong việc quản lý phiên bản và hợp nhất mã nguồn. Chính vì vậy, Git – một công cụ quản lý mã nguồn hiệu quả, đã trở thành một thành phần không thể thiếu trong các dự án phát triển phần mềm. Bài viết sau đây sẽ giúp các beginner hiểu rõ về bản chất Git là gì.
Đọc bài viết sau đây để hiểu rõ:
- Chi tiết Git là gì và các khái niệm, thuật ngữ Git cơ bản cần biết
- Cơ chế hoạt động của Git
- Cách cài đặt Git chi tiết
Hệ thống quản lý phiên bản (Version Control System – VCS)
Trước khi tìm hiểu về Git, chúng ta cần hiểu rõ VCS là gì và chức năng chính của nó. Hệ thống quản lý phiên bản (VCS) là một hệ thống lưu giữ các phiên bản của mã nguồn sản phẩm phần mềm. Khi các lập trình viên trong nhóm có những thay đổi trong mã nguồn, thông tin đó sẽ được lưu lại một cách minh bạch bao gồm người thay đổi, thời gian thay đổi, và nội dung thay đổi.
Chính vì vậy, VCS có thể giúp các lập trình viên có một cái nhìn thống nhất và tổng quan về dự án đang làm, có thể dễ dàng truy xuất thông tin thay đổi hoặc lấy lại phiên bản mã nguồn trong quá khứ.
Phân loại hệ thống quản lý phiên bản
Hệ thống quản lý phiên bản cục bộ (Local version control system)
Là dạng quản lý phiên bản ngay trên máy tính cá nhân của người dùng. Trong loại này, mỗi khi có sự thay đổi, hệ thống sẽ tạo ra một bản sao cục bộ. Nó cho phép người dùng quay lại phiên bản cũ, tuy nhiên không hỗ trợ cho làm việc nhóm và cộng tác từ xa.
Một ví dụ điển hình cho loại này đó là Revision Control System (RCS), được phát hành vào năm 1982 bởi Walter F. Tichy.
Hệ thống quản lý phiên bản tập trung (Centralized version control system)
Là hệ thống gồm một máy chủ chứa toàn bộ dữ liệu phiên bản khác nhau của dự án, và mọi người trong team có thể sử dụng để chia sẻ và truy xuất dữ liệu của nhau.
Một hệ thống nổi bật và phổ biến thuộc loại này là Apache Subversion (SVN), được tạo ra bởi CollabNet Inc. vào năm 2000 và hiện là một dự án cấp cao của Apache, được xây dựng và sử dụng bởi cộng đồng các cộng tác viên trên toàn thế giới.
Hệ thống quản lý phiên bản phân tán (Distributed Version Control Systems)
Trong hệ thống này, khi một client truy xuất dữ liệu từ máy chủ, nó không chỉ lấy về dữ liệu ở phiên bản mới nhất, mà nó còn tải về cả kho chứa của hệ thống, hay còn gọi là repository. Trong trường hợp máy chủ từ xa có trục trặc, thì những client đã tải về trước đó vẫn còn kho lưu trữ, và có thể sử dụng để khôi phục dữ liệu của mã nguồn.
Git chính là một trong các hệ thống quản lý phiên bản phân tán.
Git là gì?
Git là một hệ thống quản lý phiên bản phân tán (Distributed Version Control Systems) được sử dụng một cách rộng rãi trong lĩnh vực phát triển phần mềm. Git thường được sử dụng kết hợp với các dịch vụ lưu trữ mã nguồn từ xa như Github, Gitlab hay Bitbucket để hỗ trợ cộng tác từ xa, nâng cao chất lượng làm việc nhóm trong dự án.
Lịch sử hình thành của Git
Git được phát triển bởi Linus Torvalds vào năm 2005, là phần mềm mã nguồn mở được phân phối theo giấy phép công cộng GPL2. Ban đầu dành cho việc phát triển nhân Linux, nhưng hiện nay, Git đã trở thành một trong các phần mềm quản lý mã nguồn phổ biến nhất.
Chức năng chính của Git
Git đóng một vai trò quan trọng trong xuyên suốt quá trình làm việc của các lập trình viên, những chức năng nổi bật của Git phải kể đến:
- Theo dõi lịch sử thay đổi của mã nguồn: Với khả năng lưu trữ một cách chi tiết các thông tin về những thay đổi xảy ra đối với mã nguồn, Git giúp các lập trình viên trong dự án có thể truy xuất lại lịch sử thay đổi, phát hiện các nguyên nhân khi hệ thống gặp lỗi.
- Hợp nhất thay đổi từ nhiều nguồn: Với các tính năng như phân nhánh và gộp nhánh (merge, rebase), Git giúp cho việc hợp nhất các thay đổi của các lập trình viên được diễn ra một cách thuận tiện và tiết kiệm thời gian hơn.
- Lưu trữ và chia sẻ mã nguồn: Git hỗ trợ kết nối với các kho lưu trữ mã nguồn từ xa như Github, Gitlab, Bitbucket. Điều này giúp bảo vệ mã nguồn an toàn và thuận tiện cho việc chia sẻ giữa các thành viên trong nhóm hoặc chia sẻ ra cộng đồng.
- So sánh sự thay đổi trong phiên bản: Với cấu trúc đặc biệt bao gồm Staging Area (khu vực trung gian) kết hợp với lệnh “git diff”, Git giúp lập trình viên có thể chọn lọc những thay đổi cần thiết trước khi thực hiện lưu trữ chúng vào kho lưu trữ.
Tại sao chúng ta nên sử dụng git?
Git đang ngày càng trở nên phổ biến và có vai trò quan trọng trong phát triển phần mềm bởi vì những lợi ích mà nó mang lại. Việc sử dụng Git trong dự án sẽ giúp bạn dễ dàng theo dõi và quản lý các phiên bản của mã nguồn. Từ đó có thể kịp thời truy vết và phát hiện lỗi trong quá trình làm việc. Tính năng phân nhánh của Git sẽ giúp bạn có thể phát triển, thử nghiệm các tính năng mới mà không làm ảnh hưởng đến phiên bản đang hoạt động ổn định của phần mềm.
Với bản chất của một hệ thống quản lý phiên bản phân tán, Git giúp việc cộng tác giữa các thành viên trở nên dễ dàng hơn. Bên cạnh đó, Git cũng đảm bảo cho việc lưu trữ và phục hồi mã nguồn.
Các thuật ngữ cơ bản trong Git
Repository trong Git
Repository là nơi lưu trữ tất cả những thông tin của mã nguồn, bao gồm các tập tin của phiên bản hiện tại, lịch sử thay đổi và các thông tin liên quan khác trong mã nguồn. Lịch sử thay đổi của các tập tin được quản lý bằng các ảnh chụp gọi là commit.
Nói nôm na thì Repository chính là thư mục chứa mã nguồn mà ở đó đã có khởi tạo git (sử dụng “git init”) và git đang theo dõi, quản lý các tập tin bên trong đó.
Có hai loại Repository chính trong Git:
- Local Repository: Là kho lưu trữ trên máy tính cá nhân của lập trình viên. Nó bao gồm tất cả các tập tin và thư mục trong mã nguồn. Kho lưu trữ này được sử dụng để thực hiện các thay đổi tại cục bộ và xem lại lịch sử mà không cần kết nối internet.
- Remote Repository: Là kho lưu trữ trên máy chủ từ xa, được đặt ở bất kỳ đâu. Kho lưu trữ này được xem là nơi hợp nhất các thay đổi trong mã nguồn từ các thành viên, cũng như là phương tiện để lưu trữ và chia sẻ thông tin mã nguồn một cách an toàn. Các đại diện cung cấp dịch vụ này bao gồm Github, Gitlab, Bitbucket, Perforce,…
Làm việc với Commit, Branch
Commit
Khi cần lưu lại các thay đổi vào Repository, người dùng cần thực hiện việc tạo ra một commit. Mỗi commit trong Git là đại diện cho một phiên bản của mã nguồn, nó bao gồm các thông tin sau:
- Danh sách các thay đổi trên các tập tin, gọi là “snapshot”
- Thông tin của người tạo ra commit và thời gian tạo
- Mô tả của commit
Ngoài ra, mỗi commit sẽ được gắn liền với một mã băm duy nhất dài 40 ký tự gọi là SHA-1. Đây được xem như là mã định danh của commit đó và sẽ không có hai SHA-1 nào trùng nhau trong một mã nguồn.
Branch
Branch (hay còn gọi là Nhánh) trong Git là một tập hợp các commit, nó như là một phiên bản lớn trong mã nguồn. Trong một repository, người dùng có thể tạo ra nhiều nhánh để thuận tiện trong việc quản lý các phiên bản.
Mặc định khi khởi tạo Git, Repository sẽ có một nhánh ban đầu tên là “main” (ở các phiên bản Git cũ, nó có tên là master). Khi người dùng thực hiện commit, nó sẽ được gán cho nhánh mà người dùng đang làm việc. Ngoài ra, khi một nhánh khác được tạo ra, nó sẽ kế thừa tất cả các commit có trong nhánh ban đầu, đây gọi là phân nhánh.
Ví dụ, một repository có nhánh “main” với ba commit là A, B, C. Người dùng tiến hành tách một nhánh mới là “develop”. Nhánh này cũng sẽ có ba commit ban đầu là A, B, C. Tiếp theo người dùng chuyển sang làm việc trên nhánh develop, và thực hiện tạo ra commit D. Thì lúc này, nhánh develop sẽ có bốn commit, tuy nhiên nhánh “main” vẫn sẽ giữ nguyên là ba commit A, B, C.
Các thuật ngữ quan trọng khác trong git
Branch | Mỗi nhánh lưu trữ một dòng lịch sử commit riêng trong kho lưu trữ, có thể tách thành nhiều nhánh và hợp nhất nhánh |
Checkout | Lệnh dùng để chuyển đổi giữa các nhánh hoặc các phiên bản cụ thể có trong repository |
HEAD | Đại diện cho commit mới nhất trong nhánh làm việc hiện tại. Khi có một commit mới được tạo ra, HEAD sẽ trở thành commit đó. |
Merge | Kết hợp các thay đổi từ nhánh này vào một nhánh khác bằng cách hợp nhất lịch sử commit, thường sẽ tạo ra một commit mới với nội dung kết hợp trong nhánh được merge |
Rebase | Khác với Merge, tuy nhiên Rebase sẽ sắp xếp lại các commit từ hai nhánh theo hướng tuyến tính để hợp nhất 2 nhánh, và không tạo ra commit Merge |
Conflict | Là xung đột giữa các thay đổi trên cùng một tập tin khi tiến hành hợp nhất các nhánh |
Origin | Tên mặc định được Git sử dụng để chỉ remote repository đã kết nối với repository cục bộ. Nó chứa thông tin địa chỉ của kho lưu trữ từ xa |
Clone | Là quá trình sao chép toàn bộ nội dung repository từ kho lưu trữ từ xa về máy cục bộ |
Push | Cập nhật các commit mới từ kho lưu trữ cục bộ đến kho lưu trữ từ xa |
Fetch | Lấy các commit thay đổi từ kho lưu trữ từ xa nhưng không tiến hành hợp nhất với nhánh đang làm việc |
Pull | Là sự kết hợp giữa fetch và merge đối với nhánh đang làm việc |
Tag | Đánh dấu một phiên bản cụ thể của dự án, có thể sử dụng Checkout để chuyển đến phiên bản này. Thường được sử dụng để phát hành các phiên bản chính thức của phần mềm |
Git config | Thiết lập các cấu hình cho Git như thông tin người dùng, trình soạn thảo mặc định,… |
Cherry-pick | Sao chép một commit từ nhánh khác mà không cần phải gộp nhánh |
Fork | Tạo ra một bản sao repository độc lập từ một nguồn khác |
.gitignore | Dùng để liệt kê các file muốn không Git theo dõi và Git sẽ bỏ qua mọi thay đổi trong các file đó |
Git flow | Là quy trình làm việc (workflow) trong Git, được thiết kế để giúp quản lý các dự án có vòng đời phát triển dài và phức tạp. |
Nguyên lý hoạt động của git
Cách git quản lý các phiên bản
Sự khác biệt chính giữa Git với các VCS khác đó chính là cách Git “nghĩ” về dữ liệu của nó. Về mặt khái niệm, hầu hết các hệ thống VCS khác lưu trữ thông tin dưới dạng danh sách các thay đổi dựa trên tập tin. Chúng coi thông tin lưu trữ là một tập hợp các tập tin và các thay đổi được thực hiện đối với từng tập tin theo thời gian.
Đối với Git, dữ liệu được quản lý bằng các phiên bản “ảnh chụp” nhanh (snapshot). Mỗi khi có một Commit được lưu vào kho lưu trữ, Git sẽ chụp ảnh tất cả các tập tin trong mã nguồn trông như thế nào tại thời điểm đó và lưu trữ tham chiếu đến ảnh chụp nhanh đó.
Trong một phiên bản nếu có tập tin nào không thay đổi, Git sẽ không lưu trữ lại mà chỉ lưu trữ liên kết đến tập tin giống hệt trước đó mà nó đã lưu trữ trong Repository. Điều này giúp Git tối ưu hóa việc lưu trữ và quản lý.
Cấu trúc 2 cây
Đối với các hệ thống VCS thông thường, chúng sẽ hoạt động dựa trên hai khu vực riêng biệt bao gồm:
- Working Space: Khu vực làm việc, nơi mà lập trình viên thực hiện các thay đổi.
- Repository: Nơi lưu trữ mã nguồn và các phiên bản.
Đây gọi là cấu trúc 2 cây. Về quy trình hoạt động, người dùng chỉ có thể chỉnh sửa các tập tin được nằm trong Working Space, mà không thể trực tiếp lấy và chỉnh sửa tất cả các tập tin được lưu trữ trong Repository.
Để có thể truy cập và chỉnh sửa những tập tin khác có trong Repository, người dùng cần thực hiện hành động Check-out (lấy các tập tin từ Repository đưa vào Working Space). Sau khi chỉnh sửa, người dùng cần thực hiện Commit (cam kết) để lưu tập tin đã thay đổi vào lại Repository.
Nhược điểm của cấu trúc này là có thể gây khó khăn trong việc quản lý mã nguồn đối với các dự án lớn, có nhiều tập tin và cần thay đổi giữa các phiên bản một cách thường xuyên. Một đại diện nổi bật về việc sử dụng cấu trúc 2 cây này chính là Subversion (SVN).
Cấu trúc 3 cây
Để khắc phục các bất cập của cấu trúc 2 cây, Git đã sử dụng một cấu trúc đặc biệt hơn, được gọi là cấu trúc 3 cây. Về bản chất, Git vẫn giữ hai thành phần chính là Repository và WorkingSpace, tuy nhiên Git đã bổ sung một thành phần trung gian gọi là Staging (hay còn gọi là Index).
Khi người dùng muốn lưu trữ những thay đổi trên tập tin, đầu tiên cần phải đưa những thay đổi này vào Staging bằng lệnh Add, sau đó sẽ thực hiện một lệnh Commit để chính thức lưu chúng vào Repository.
Vì vậy, Staging được xem là nơi mà người dùng có thể xem xét lại toàn bộ các thay đổi của mình trước khi lưu trữ vào Repository và có thể kiểm soát được những thông tin nào sẽ được lưu trữ trong một phiên bản.
Lấy ví dụ, bạn đang thực hiện chỉnh sửa trên tập tin A, sếp gửi yêu cầu bạn hãy bổ sung thêm nội dung ở tập tin B.
Lúc này, trong trường hợp các VCS có cấu trúc 2 cây, nếu bạn thực hiện Commit để lưu trữ thay đổi vào Repository, thì cả hai thay đổi trên tập tin A và tập tin B đều sẽ được lưu lại thành một phiên bản.
Thoạt nhìn sẽ thấy điều này rất bình thường, tuy nhiên nếu xét trong một hệ thống lớn với rất nhiều phiên bản, thì đây có thể sẽ là một quả bom nổ chậm khi có lỗi xảy ra và cần điều tra lại lịch sử thay đổi.
Thay vào đó, khi sử dụng Git, bạn có thể đưa thay đổi của tập tin A vào Staging, và thực hiện commit lần 1. Sau đó tiếp tục đưa thay đổi từ tập tin B vào Staging và thực hiện commit lần 2. Điều này giúp tách biệt hai phiên bản không liên quan đến nhau, và dễ dàng cho việc truy vết lịch sử thay đổi trong mã nguồn.
Hướng dẫn cách cài đặt và cấu hình Git
Đối với hệ điều hành MacOS, Git có thể được cài đặt bằng terminal với lệnh:
brew install git
Truy cập https://brew.sh/ nếu bạn chưa cài đặt homebrew.
- Đối với hệ điều hành Windows, người dùng truy cập đường dẫn sau để tải xuống phiên bản Gi: https://git-scm.com/downloads/win
- Đối với hệ điều hành Linux, sử dụng apt để cài đặt Git với lệnh:
sudo apt-get install git
Sau khi cài đặt, bạn có thể kiểm tra thông tin Git bằng lệnh:
git --version
Để cài đặt thông tin người dùng (thông tin này sẽ được sử dụng làm thông tin tác giả cả các commit):
git config --global user.name "Your Name" git config --global user.email "youremail@example.com"
Kiểm tra cấu hình hiện tại:
git config --list
Các câu hỏi thường gặp về Git là gì
Các kho lưu trữ từ xa (remote repository) phổ biến hiện nay?
Sau đây là một số kho lưu trữ từ xa phổ biến mà các lập trình viên ưa chuộng:
- GitHub (https://github.com):
- Nằm trong top các nền tảng được lập trình viên sử dụng nhiều nhất. Github hỗ trợ lưu trữ mã nguồn ở dạng công khai và riêng tư, có thể phù hợp với các dự án mã nguồn mở hoặc những dự án riêng của doanh nghiệp.
- Kết hợp với Github Actions để cung cấp tính năng CI/CD
- Tính năng Pull Request của Github là điểm nổi bật, giúp thuận tiện trong việc cộng tác giữa các thành viên
- GitLab (https://gitlab.com):
- Là nền tảng tích hợp quản lý mã nguồn từ xa và cả DevOps
- Thích hợp để quản lý mã ở quy mô lớn
- Có tích hợp sẵn CI/CD trong hệ thống
- BitBucket (https://bitbucket.org):
- Một công cụ được cung cấp bởi Atlassian, hỗ trợ Git và Mercurial
- Có thể tích hợp vào các công cụ quản lý dự án như Trello, Jira
- Tích hợp CI/CD thông qua Pipelines
Các lưu ý cần biết khi làm việc với Git?
Để làm việc với Git một cách thuận lợi và có hiệu quả, bạn cần trang bị cho mình những kiến thức từ cơ bản đến nâng cao về Git. Điều này cũng giúp bạn tránh được những sai lầm có thể gây ảnh hưởng đến dự án.
Dưới đây là một số lưu ý bạn cần nắm khi làm việc với Git:
- Đảm bảo đã thiết lập user name và email đúng để xác định người dùng trong các commit
- Sử dụng .gitignore để loại bỏ những file chứa nội dung nhạy cảm không được phép lưu trữ vào repository như nội dung biến môi trường, khóa bí mật,…
- Khi có xung đột (Conflict) xảy ra, cần trao đổi kỹ càng với người cộng tác để lựa chọn nội dung merge chính xác
- Tránh sử dụng push –force khi làm việc trên các nhánh có nhiều người cộng tác
- Tạo commit thường xuyên để tránh có sự cố dẫn đến mất code
- Đặt lời nhắn rõ ràng khi tạo commit để thuận tiện cho việc theo dõi lịch sử và quản lý commit
- Tránh gộp chung quá nhiều file thay đổi với nhiều mục đích khác nhau trên cùng một commit. Điều này sẽ dẫn đến khó khăn khi cần thực hiện revert một nội dung trong đó
- Cập nhật nội dung nhánh từ remote repository thường xuyên trước khi thực hiện push để tránh xung đột
Một số lệnh cơ bản trong Git là gì?
git clone | Sao chép một repository hiện có từ kho lưu trữ từ xa về cục bộ |
git init | Khởi tạo một kho lưu trữ cục bộ |
git branch | Tạo một nhánh làm việc mới |
git checkout | Chuyển trạng thái làm việc sang một nhánh khác hoặc một phiên bản khác |
git status | Kiểm tra các thay đổi đã xảy ra trong khu vực làm việc hiện tại |
git add | Thêm 1 file thay đổi vào khu vực Staging để chuẩn bị thực hiện commit |
git commit | Thực hiện lệnh commit để lưu trữ các thay đổi vào repository |
git push | Đẩy các thay đổi đã được commit ở kho lưu trữ cục bộ lên kho lưu trữ từ xa |
git fetch | Lấy các commit thay đổi từ kho lưu trữ từ xa nhưng không tiến hành hợp nhất với nhánh đang làm việc |
git merge | Kết hợp các thay đổi từ nhánh này vào một nhánh khác bằng cách hợp nhất lịch sử commit |
git pull | Sự kết hợp giữa fetch và merge đối với nhánh đang làm việc |
git revert | Tạo ra một commit với nội dung trái ngược với commit trước đó, mục đích để hoàn tác các thay đổi đã được commit |
git reset | Phá vỡ commit đã lưu, đưa các file đã thay đổi từ repository về khu vực làm việc |
Có những phần mềm quản lý mã nguồn và tương tác với hệ thống quản lý phiên bản Git nào?
Hiện nay, có rất nhiều phần mềm hỗ trợ thao tác và làm việc với Git, nổi bật trong số đó phải kể đến:
- SourceTree (sourcetreeapp.com):
- Một ứng dụng GUI miễn phí giúp tương tác với Git và Mercurial.
- Hiển thị giao diện trực quan lịch sử commit và nhánh trong repository, hỗ trợ thực hiện các thao tác commit, merge, pull, push,.. một cách dễ dàng.
- Có thể kết nối trực tiếp với Github, GitLab, BitBucket,…
- GitKraken (gitkraken.com):
- Cung cấp giao diện thao tác với git.
- Tích hợp với các dịch vụ như Github, GitLab, BitBucket
- Hỗ trợ việc thực hiện Merge, Rebase và xử lý conflict.
- VS Code (Visual Studio Code):
- Trình soạn thảo code miễn phí có tích hợp Git với các thao tác như pull, push, commit
- Có giao diện trực quan để đối chiếu sự thay đổi giữa các phiên bản ngay trên trình soạn thảo
- Có thể kết hợp với các Extension như GitLens, GitHistory để nâng cao các tính năng.
Tổng kết Git là gì
Trong thời đại công nghệ thông tin ngày nay, Git đã trở thành một trợ thủ vô cùng đắc lực trong các dự án phát triển phần mềm, đóng vai trò giúp các lập trình viên quản lý mã nguồn hiệu quả và cộng tác dễ dàng hơn.
ITviec hy vọng bài viết trên đã giúp bạn có một cái nhìn tổng quan về Git và các khái niệm cơ bản như commit, branch, repository. Đây sẽ là tiền để để bạn có thể bắt đầu khám phá sâu hơn về các tính năng mạnh mẽ của hệ thống quản lý phiên bản này và áp dụng Git vào các dự án của bản thân.