
Git là gì: hệ thống quản lý phiên bản mã nguồn phổ biến nhất
Git là hệ thống quản lý phiên bản phân tán, miễn phí và mã nguồn mở, do Linus Torvalds bắt đầu phát triển tháng 4 năm 2005 để quản lý mã nguồn nhân Linux. Mỗi lần bạn lưu một thay đổi, Git ghi lại một ảnh chụp toàn bộ kho mã kèm thông tin tác giả, thời điểm và nội dung khác biệt. Nhờ đó bạn có thể xem lại toàn bộ lịch sử phát triển, so sánh hai phiên bản bất kỳ, hay quay về một trạng thái cũ mà không sợ mất dữ liệu.

Điểm khác biệt cốt lõi của Git so với các hệ thống cũ như Subversion là tính phân tán. Mỗi lần bạn git clone một kho, bạn nhận về một bản sao đầy đủ của kho đó cùng toàn bộ lịch sử commit. Máy chủ chỉ là một bản sao nữa trong nhiều bản sao, chứ không phải nơi duy nhất chứa dữ liệu. Nếu máy chủ hỏng, bất kỳ máy nào còn lại đều có thể dựng lại. Theo khảo sát Stack Overflow năm 2022, 96% lập trình viên chuyên nghiệp dùng Git.
Ba vùng làm việc cốt lõi của Git
Hiểu Git bắt đầu từ mô hình ba vùng. Mọi lệnh bạn gõ đều chỉ là di chuyển nội dung giữa ba nơi này:
- Working directory — thư mục bạn đang làm việc, nơi bạn sửa file và thấy kết quả ngay lập tức.
- Staging area — vùng chờ, nơi bạn chọn những thay đổi nào sẽ nằm trong commit tới. Tính năng này cho phép gom nhiều thay đổi nhỏ thành một commit có ý nghĩa.
- Repository — nơi Git lưu lịch sử vĩnh viễn, mã hoá bằng hàm băm SHA-1. Không thể sửa nội dung đã commit mà không làm thay đổi mã băm.
Lệnh git add đưa nội dung từ working directory sang staging. Lệnh git commit ghi staging area thành một commit mới, và commit đó trở thành con trực tiếp của HEAD — thường là đỉnh nhánh hiện tại — đồng thời nhánh đó được cập nhật trỏ về commit mới. Lệnh git status cho bạn thấy ba vùng đang lệch nhau ở đâu: file nào đã staged, file nào sửa mà chưa staged, file nào chưa được Git theo dõi.

Commit, nhánh và mô hình phân nhánh
Commit là đơn vị thay đổi nhỏ nhất trong Git. Mỗi commit có mã băm, trỏ tới một hoặc nhiều commit cha, và giữ nguyên thông tin tác giả cùng thời điểm. Nhánh (branch) chỉ đơn giản là một con trỏ trỏ tới một commit nào đó. Tạo nhánh gần như tức thì vì Git không sao chép toàn bộ lịch sử.
Lệnh git branch liệt kê các nhánh hiện có, đánh dấu nhánh đang dùng bằng dấu sao và làm nổi bật. Còn git checkout chuyển HEAD sang nhánh hoặc commit khác, đồng thời cập nhật staging area và working directory cho khớp. Khi HEAD trỏ thẳng vào một commit thay vì một nhánh, trạng thái đó gọi là detached HEAD — thường gặp khi bạn muốn xem thử một commit cũ rồi quay lại.
| Lệnh | Tác dụng | Khi nào dùng |
|---|---|---|
git switch -c ten-nhanh |
Tạo nhánh mới và chuyển sang | Bắt đầu một tính năng mới, tách khỏi nhánh chính |
git merge ten-nhanh |
Gộp lịch sử nhánh vào nhánh hiện tại, tạo commit có hai cha | Đưa thay đổi hoàn tất về nhánh chính |
git rebase ten-nhanh |
Cấy lại chuỗi commit lên điểm bắt đầu khác | Giữ lịch sử tuyến tính trước khi mở pull request |
git cherry-pick ma-hash |
Chép riêng một hoặc nhiều commit | Chuyển một bản sửa lỗi sang nhánh khác |
git tag -a v1.0 -m "phat hanh" |
Tạo thẻ được chú thích tại một commit | Đánh dấu mốc phát hành |
Khác biệt then chốt giữa merge và rebase nằm ở lịch sử. merge tạo một commit mới có hai cha, giữ nguyên cả hai nhánh và ghi nhận rằng đã có sự hội tụ. rebase thì cấy từng commit của nhánh bạn lên đỉnh nhánh đích, tạo ra một mã băm mới cho mỗi commit và một đường lịch sử thẳng. Vì vậy quy tắc thực hành phổ biến là: dùng rebase trên nhánh cá nhân trước khi chia sẻ, dùng merge khi gộp nhánh chính.
Quy trình làm việc hằng ngày
- Khởi tạo kho mới bằng
git init, lệnh này tạo thư mục.gitchứa các object, tham chiếurefs/heads,refs/tagscùng các file mẫu. Nhánh đầu tiên được tạo ra ở trạng thái chưa có commit nào. - Đặt danh tính một lần bằng
git config --global user.namevàuser.email. Thông tin này được ghi vĩnh viễn vào mọi commit bạn tạo, nên đặt sai thì sửa cũng khó. - Sao chép kho có sẵn bằng
git clone. Lệnh này tạo remote-tracking branch cho từng nhánh, hiển thị quagit branch --remotes, và checkout nhánh khởi đầu. - Làm việc, thêm file bằng
git add, ghi lịch sử bằnggit commit. - Đồng bộ:
git fetchchỉ tải object và cập nhật remote-tracking branch mà không gộp.git pullchạyfetchrồimerge(hoặcrebasenếu thêm--rebase).git pushđẩy object cục bộ lên remote.

Xử lý xung đột khi merge
Xung đột phát sinh khi hai bên cùng sửa một dòng giống nhau mà Git không biết nên chọn bản nào. Cả git merge và git rebase đều dừng lại để bạn giải quyết thủ công. Bạn mở file, sửa dấu <<<<<<<, =======, >>>>>>> thành nội dung đúng, lưu lại, chạy git add cho file đó, rồi git merge --continue hoặc git rebase --continue. Nếu đổi ý thì git merge --abort hay git rebase --abort đưa mọi thứ về trạng thái trước khi bắt đầu.
Lỗi phổ biến nhất không phải lỗi Git mà là lỗi con người: commit quá nhiều thứ không liên quan vào cùng một lần. Lịch sử đọc được là tài sản lớn nhất của Git, và nó chỉ đọc được khi mỗi commit có một ý nghĩa rõ ràng.
Những lỗi thường gặp
- Commit nhầm vào nhánh chính. Với Git, nhánh chính luôn có thể bị đặt lại: lưu SHA của commit sai bằng
git reflog, sau đógit reset --hard ma-hashđể quay lại. - Push bị từ chối không phải vì bạn sai. Khi remote đã có commit mà máy bạn chưa có, dùng
git pull --rebaserồi push lại thay vì cố--force. - Thêm nhầm file bí mật. File đã commit vẫn nằm trong lịch sử dù bạn xóa ở commit sau. Dùng
.gitignoretừ đầu, và nếu lỡ thì phải xoay khoá bí mật chứ không chỉ xóa file. - Không cấu hình tên và email. Git sẽ báo lỗi khi commit. Sửa bằng
git config --globalrồi dùngamendcho các commit đã tạo sai. - Nhầm
git reset --hardvớigit reset --soft. Bản--hardxóa luôn thay đổi chưa commit trong working directory. Chỉ dùng khi bạn chắc chắn muốn mất.
Git phát hành theo giấy phép GNU GPL phiên bản 2, là một dự án thành viên của Software Freedom Conservancy, và mã nguồn được duy trì tại kernel.org. Toàn bộ tài liệu tham chiếu lệnh nằm ở git-scm.com/docs, còn cuốn sách Pro Git của Scott Chacon và Ben Straub được phát hành miễn phí trực tuyến tại git-scm.com/book. Lịch sử ra đời được ghi lại chi tiết trong bài Wikipedia về Git, và trang chủ dự án là git-scm.com.
