Git là một hệ thống quản lý phiên bản thiết yếu trong quá trình phát triển phần mềm hiện đại. Nó cho phép các cá nhân và đội nhóm theo dõi sự thay đổi của mã nguồn, quay lại các phiên bản cũ hơn và cộng tác một cách hiệu quả. Hướng dẫn này sẽ trình bày các lệnh và khái niệm cơ bản nhất bạn cần cho công việc hàng ngày, được giải thích một cách đơn giản, dễ hiểu kèm theo các ví dụ mã lệnh thực tế.
1. Khởi Tạo Một Git Repository
Bước đầu tiên trong bất kỳ dự án nào sử dụng Git là tạo ra một kho chứa, hay còn gọi là repository. Có hai phương pháp chính để làm điều này: khởi tạo một repository mới ngay trong một dự án đã có sẵn, hoặc sao chép (clone) một repository đã tồn tại ở nơi khác. Dù bạn chọn cách nào, kết quả cuối cùng đều là một repository Git đầy đủ chức năng trên máy tính của bạn, sẵn sàng để làm việc.

Khởi tạo Repository trong một Thư mục có sẵn (git init)
Lệnh git init được dùng để biến một thư mục cục bộ chưa được quản lý phiên bản thành một Git repository. Để thực hiện, bạn chỉ cần di chuyển vào thư mục gốc của dự án trong terminal và chạy lệnh:
$ git init
Sau khi chạy lệnh, một thư mục con ẩn tên là .git sẽ được tạo ra. Thư mục này chứa toàn bộ “bộ xương” của repository. Tại thời điểm này, chưa có tệp nào trong dự án của bạn được theo dõi. Để bắt đầu theo dõi các tệp hiện có và tạo commit đầu tiên, bạn sử dụng lệnh git add để chỉ định các tệp cần theo dõi, theo sau là git commit:
$ git add *.c
$ git add LICENSE
$ git commit -m 'Initial project version'
Sao chép một Repository có sẵn (git clone)
Để tạo một bản sao của một Git repository đã tồn tại ở một nơi khác (remote), bạn sử dụng lệnh git clone. Điểm khác biệt chính giữa clone của Git và checkout của các hệ thống khác (như Subversion) là Git nhận về một bản sao đầy đủ của gần như toàn bộ dữ liệu, bao gồm toàn bộ lịch sử của dự án. Cú pháp lệnh chính là:
$ git clone <url>
Ví dụ, để sao chép thư viện libgit2, bạn có thể chạy lệnh:
$ git clone https://github.com/libgit2/libgit2
Lệnh này tạo ra một thư mục libgit2 chứa toàn bộ repository. Nếu bạn muốn sao chép vào một thư mục có tên khác, chỉ cần thêm tên thư mục mong muốn làm tham số cuối cùng:
$ git clone https://github.com/libgit2/libgit2 mylibgit
Git hỗ trợ nhiều giao thức truyền tải khác nhau, bao gồm https://, git://, và SSH (user@server:path/to/repo.git).
Với repository đã sẵn sàng, chúng ta sẽ đi vào trọng tâm của Git: quy trình ghi nhận thay đổi hàng ngày.
2. Ghi Nhận Thay Đổi vào Repository

Quy trình làm việc cốt lõi trong Git xoay quanh vòng đời của các tệp. Repository cục bộ của bạn bao gồm ba “cây” chính: Working Directory (thư mục làm việc chứa các tệp thực tế), Index (hoạt động như một khu vực chuẩn bị, còn gọi là Staging Area), và HEAD (trỏ đến commit cuối cùng). Hiểu rõ cách các tệp di chuyển qua ba khu vực này—từ nơi bạn chỉnh sửa (Working Directory), đến nơi bạn chọn lọc thay đổi (Staging Area), và cuối cùng là nơi lưu trữ lịch sử (HEAD)—là chìa khóa để làm chủ Git.
Kiểm tra Trạng thái của Files (git status)
Lệnh git status là công cụ chính để xác định trạng thái hiện tại của các tệp trong dự án. Nếu bạn chạy lệnh này trong một thư mục làm việc “sạch”, kết quả sẽ cho thấy không có thay đổi nào. Tuy nhiên, khi bạn thêm một tệp mới (ví dụ: README.md) mà Git chưa từng biết đến, git status sẽ liệt kê nó dưới mục “Untracked files”.

git status cho bạn biết chính xác: bạn đang ở nhánh nào, những thay đổi đã được staged, chưa được staged và những tệp mới nào chưa được theo dõi (untracked).
Theo dõi Files Mới và Staging Thay Đổi (git add)
git add là một lệnh đa năng, được dùng để bắt đầu theo dõi các tệp mới và để đưa các tệp đã được sửa đổi vào Staging Area, chuẩn bị cho lần commit tiếp theo. Để theo dõi tệp README mới, bạn chạy lệnh:
$ git add README.md
Sau đó, git status sẽ cho thấy tệp này giờ đã nằm trong mục “Changes to be committed”. Khi bạn sửa một tệp đã được theo dõi (ví dụ CONTRIBUTING.md), bạn cũng cần dùng git add để “stage” những thay đổi đó. Git sẽ đưa phiên bản chính xác của tệp tại thời điểm bạn chạy git add vào Staging Area. Điều này rất quan trọng: nếu bạn tiếp tục sửa đổi một tệp sau khi đã add nó, bạn phải chạy lại git add để cập nhật phiên bản mới nhất vào Staging Area. Nếu không, tệp đó sẽ xuất hiện ở cả hai trạng thái: staged (phiên bản cũ) và unstaged (thay đổi mới nhất).


Cam kết Thay đổi (git commit)
Lệnh git commit sẽ lấy toàn bộ ảnh chụp (snapshot) của Staging Area và lưu nó vĩnh viễn vào lịch sử của dự án. Có hai cách commit phổ biến: chạy git commit sẽ mở một trình soạn thảo văn bản để bạn nhập thông điệp commit, hoặc sử dụng cờ -m để cung cấp thông điệp ngay trên dòng lệnh.

Bạn cũng có thể sử dụng tùy chọn -a như một lối tắt. Lệnh này sẽ tự động stage tất cả các tệp đã được theo dõi và commit chúng, giúp bạn bỏ qua bước git add.
$ git commit -a -m 'Add new benchmarks'
Bỏ qua Files (.gitignore)
Để ngăn Git theo dõi các tệp được tạo tự động (như file log, các tệp build), bạn có thể tạo một tệp tên là .gitignore.
Đây là một ví dụ về nội dung của một tệp .gitignore thực tế:
# Bỏ qua tất cả các file .a
*.a
# Nhưng theo dõi file lib.a, dù các file .a khác đã bị bỏ qua ở trên
!lib.a
# Chỉ bỏ qua file TODO ở thư mục gốc, không phải ở các thư mục con
/TODO
# Bỏ qua tất cả các file trong bất kỳ thư mục nào tên là build
build/
# Bỏ qua doc/notes.txt, nhưng không bỏ qua doc/server/arch.txt
doc/*.txt
# Bỏ qua tất cả file .pdf trong thư mục doc/ và các thư mục con của nó
doc/**/*.pdf
Các quy tắc chính cho các mẫu trong .gitignore:
- Các dòng trống hoặc bắt đầu bằng
#được coi là chú thích và bị bỏ qua. - Dấu
*là một ký tự đại diện (glob pattern) khớp với 0 hoặc nhiều ký tự. - Bắt đầu bằng
/để chỉ định một đường dẫn từ thư mục gốc, tránh áp dụng đệ quy. - Kết thúc bằng
/để chỉ định một thư mục. - Bắt đầu bằng
!để phủ định một mẫu (tức là không bỏ qua tệp khớp với mẫu đó).
Quản lý Files: Di chuyển và Xóa
Để xóa một tệp, lệnh git rm sẽ xóa nó khỏi danh sách các tệp được theo dõi (Staging Area) và đồng thời xóa nó khỏi thư mục làm việc của bạn.
$ git rm PROJECTS.md
Nếu bạn muốn ngừng theo dõi một tệp nhưng vẫn giữ nó trong thư mục làm việc (ví dụ: một file cấu hình nhạy cảm đã lỡ commit), hãy sử dụng git rm --cached <file>.
Git không theo dõi việc đổi tên tệp một cách tường minh, nhưng nó đủ thông minh để phát hiện ra. Lệnh git mv là một tiện ích, tương đương với việc bạn chạy một chuỗi ba lệnh: mv file_from file_to, theo sau là git rm file_from và git add file_to.
$ git mv file_from file_to
Khi đã thành thạo việc tạo và lưu lại các thay đổi, bước hợp lý tiếp theo là học cách xem lại lịch sử mà chúng ta đã cẩn thận ghi lại.
3. Xem Lịch Sử Commit
Việc xem lại lịch sử của một dự án là vô cùng quan trọng để hiểu những thay đổi nào đã được thực hiện, khi nào và bởi ai. Công cụ chính và mạnh mẽ nhất của Git cho mục đích này là lệnh git log.
Lệnh git log Cơ bản
Khi được chạy mà không có tham số, git log sẽ liệt kê các commit theo thứ tự thời gian đảo ngược, với commit mới nhất ở trên cùng. Mỗi commit sẽ hiển thị mã băm SHA-1, tác giả, ngày tháng và thông điệp commit.
Một ví dụ về output của git log:

Tùy chỉnh Định dạng Output
git log cung cấp nhiều tùy chọn để định dạng output. Dưới đây là một số tùy chọn hữu ích nhất:
- Xem thay đổi chi tiết (
-por--patch): Tùy chọn này hiển thị sự khác biệt (diff) được giới thiệu trong mỗi commit. Bạn có thể kết hợp với-<n>để giới hạn số lượng commit, ví dụgit log -p -2để xem 2 commit gần nhất. - Xem thống kê tóm tắt (
--stat): Tùy chọn này hiển thị một bản tóm tắt thống kê cho mỗi commit, bao gồm danh sách các tệp đã thay đổi, số dòng được thêm và xóa. - Định dạng ngắn gọn (
--pretty=oneline): In mỗi commit trên một dòng duy nhất, rất hữu ích khi xem một lượng lớn commit. - Định dạng tùy chỉnh (
--pretty=format): Cho phép bạn tự định nghĩa định dạng output. Ví dụ, định dạng sau sẽ hiển thị mã băm viết tắt, tên tác giả, ngày tháng tương đối và tiêu đề commit. Mã%arsẽ hiển thị thời gian tương đối tính từ lúc commit (ví dụ: ‘2 hours ago’, ‘3 days ago’).
Giới hạn Output của Log
Bạn có thể lọc output của git log để chỉ hiển thị một tập hợp con các commit:
- Theo số lượng:
-<n>hiển thịncommit gần nhất. Ví dụ:-2. - Theo thời gian:
--sincevà--untilcho phép lọc theo khoảng thời gian. Ví dụ:--since=2.weeks. - Theo tác giả:
--authorlọc các commit của một tác giả cụ thể. - Theo nội dung commit:
--greptìm kiếm các commit có thông điệp chứa một chuỗi ký tự nhất định. - Theo đường dẫn file:
-- <path/to/file>chỉ hiển thị các commit đã làm thay đổi một tệp hoặc thư mục cụ thể.
Việc xem lại lịch sử thường đi đôi với nhu cầu sửa chữa những sai sót hoặc hoàn tác các thay đổi không mong muốn. Hãy cùng khám phá các công cụ mạnh mẽ của Git cho mục đích này.
4. Hoàn Tác Sai Lầm
Mắc lỗi là một phần không thể tránh khỏi trong quá trình phát triển. Git cung cấp một mạng lưới an toàn mạnh mẽ với các khả năng “undo”. Phần này sẽ đề cập đến các tình huống phổ biến như sửa đổi commit gần nhất, bỏ staging một tệp, và hủy bỏ các thay đổi cục bộ.
Sửa Commit Gần Nhất (--amend)
git commit --amend được sử dụng khi bạn muốn sửa thông điệp commit gần nhất hoặc thêm các tệp đã quên vào commit đó mà không cần tạo một commit mới. Lệnh này không “sửa” commit cũ, mà nó thay thế hoàn toàn commit đó bằng một commit mới.
Ví dụ về quy trình thêm một tệp đã quên:
$ git commit -m 'Initial commit'
$ git add forgotten_file
$ git commit --amend
Cảnh báo: Chỉ nên sử dụng amend trên các commit chưa được đẩy (push) lên một remote repository để tránh gây rối cho lịch sử của các thành viên khác trong nhóm.
Bỏ Staging một File (reset và restore)
Trong trường hợp bạn vô tình add một tệp vào Staging Area mà không muốn đưa nó vào commit tiếp theo, lệnh git status sẽ chỉ cho bạn cách để “unstage” tệp đó. Trong các phiên bản Git cũ hơn, lệnh được sử dụng là git reset:
$ git reset HEAD CONTRIBUTING.md
Trong các phiên bản Git mới hơn (2.23.0+), lệnh git restore được khuyến nghị cho mục đích này:
$ git restore --staged CONTRIBUTING.md
Cả hai lệnh này chỉ tác động đến Staging Area; các thay đổi trong thư mục làm việc của bạn vẫn được giữ nguyên.
Hủy bỏ Thay đổi ở Thư mục làm việc (checkout và restore)
Khi bạn nhận ra mình muốn hủy bỏ hoàn toàn các thay đổi đã thực hiện trên một tệp và đưa nó trở lại phiên bản của lần commit gần nhất, git status cũng sẽ hướng dẫn bạn cách thực hiện. Trong các phiên bản Git cũ, lệnh được sử dụng là git checkout:
$ git checkout -- CONTRIBUTING.md
Các phiên bản Git mới hơn sử dụng git restore cho thao tác này:
$ git restore CONTRIBUTING.md
Quan trọng: Đây là một lệnh nguy hiểm. Bất kỳ thay đổi cục bộ nào bạn đã thực hiện trên tệp đó sẽ bị mất vĩnh viễn. Hãy chắc chắn rằng bạn thực sự không cần những thay đổi đó trước khi chạy lệnh này.
Sau khi làm chủ các thao tác trên repository cục bộ, đã đến lúc chúng ta tìm hiểu cách cộng tác với những người khác thông qua các remote repository.
5. Làm Việc Nhóm với Remotes
Remote repository là các phiên bản của dự án của bạn được lưu trữ trên Internet hoặc trên một mạng nội bộ. Chúng là nền tảng cho việc cộng tác trong Git. Phần này sẽ hướng dẫn cách quản lý các remote này để chia sẻ công việc với đội nhóm.

Quản lý Remotes
Để xem các remote đã được cấu hình, bạn dùng git remote. Mặc định, bạn sẽ thấy origin. Sử dụng git remote -v để xem cả URL của chúng.
$ git remote -v

Để thêm một remote repository mới với một tên viết tắt, sử dụng git remote add:
$ git remote add pb https://github.com/paulboone/ticgit
Bạn cũng có thể đổi tên một remote bằng git remote rename pb paul và xóa nó bằng git remote remove paul.
Đồng bộ hóa với Remotes
Lệnh git fetch <remote> tải xuống tất cả dữ liệu từ remote mà bạn chưa có, nhưng nó không tự động hợp nhất (merge) vào nhánh làm việc hiện tại của bạn.
Ngược lại, git pull là một sự kết hợp giữa fetch và merge. Nó tự động lấy dữ liệu từ remote và hợp nhất nhánh remote tương ứng vào nhánh cục bộ hiện tại của bạn.
Khi bạn muốn chia sẻ các commit cục bộ của mình, bạn sử dụng lệnh git push <remote> <branch>. Để push thành công, bạn cần có quyền ghi vào remote, và không ai khác được push các thay đổi xung đột lên trước bạn.
$ git push origin master
Ngoài quy trình đẩy/kéo dữ liệu liên tục, đôi khi bạn cần đánh dấu những cột mốc quan trọng trong lịch sử dự án, chẳng hạn như một phiên bản phát hành chính thức.
6. Đánh Dấu Cột Mốc với Tags
Tagging là cơ chế của Git để đánh dấu các điểm cụ thể trong lịch sử là quan trọng. Thông thường, nó được sử dụng để đánh dấu các phiên bản phát hành (ví dụ: v1.0). Phần này sẽ hướng dẫn cách tạo, liệt kê và chia sẻ các tag.
Các loại Tags
Git hỗ trợ hai loại tag chính:
- Lightweight Tags: Đây chỉ là một con trỏ đơn giản đến một commit cụ thể, giống như một nhánh không thay đổi.
- Annotated Tags: Đây là các đối tượng đầy đủ trong cơ sở dữ liệu của Git. Chúng chứa thông tin người tạo tag, ngày tháng, thông điệp tag, và có thể được ký điện tử. Annotated tags thường được khuyến nghị sử dụng vì chứa nhiều thông tin hơn.
Các lệnh Tagging cơ bản
Để liệt kê tất cả các tag hiện có, bạn chỉ cần chạy git tag. Để tạo một Annotated Tag, sử dụng cờ -a để tạo tag và -m để thêm thông điệp.
$ git tag -a v1.4 -m "my version 1.4"
Để tạo một Lightweight Tag, chỉ cần cung cấp tên tag mà không có các tùy chọn -a, -s, hoặc -m.
$ git tag v1.4-lw
Bạn có thể xem thông tin chi tiết của một tag bằng lệnh git show <tagname>. Nếu bạn muốn tag một commit trong quá khứ, hãy cung cấp mã băm (checksum) của commit đó ở cuối lệnh:
$ git tag -a v1.2 9fceb02
Mặc định, git push không gửi các tag lên remote. Bạn phải đẩy chúng một cách tường minh bằng cách sử dụng tùy chọn --tags.
$ git push origin --tags
Khi đã nắm vững các chức năng cốt lõi, hãy cùng khám phá một mẹo nhỏ nhưng cực kỳ hiệu quả để tối ưu hóa quy trình làm việc hàng ngày của bạn.
7. Tăng Tốc Độ với Git Aliases
Git Aliases là một tính năng đơn giản nhưng mạnh mẽ, cho phép bạn tạo ra các lệnh tắt cho những lệnh dài và thường xuyên sử dụng, giúp trải nghiệm Git trở nên đơn giản và nhanh chóng hơn.
Tạo Aliases
Các alias được thiết lập thông qua lệnh git config. Dưới đây là một số ví dụ phổ biến để tạo alias cho checkout, branch, commit, và status:
$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.ci commit
$ git config --global alias.st status
Sau khi thiết lập, ví dụ, git ci sẽ tương đương với việc gõ git commit. Kỹ thuật này không chỉ để rút ngắn lệnh mà còn có thể tạo ra các lệnh hoàn toàn mới mà bạn thấy hữu ích. Ví dụ, bạn có thể tạo lệnh unstage để dễ dàng bỏ staging một file:
$ git config --global alias.unstage 'reset HEAD --'
Hoặc một alias tiện dụng để xem nhanh commit gần nhất:
$ git config --global alias.last 'log -1 HEAD'
Việc sử dụng alias cho thấy sự linh hoạt của Git, cho phép bạn tùy chỉnh và tối ưu hóa quy trình làm việc theo đúng nhu cầu của mình.
Tổng kết
Qua hướng dẫn này, chúng ta đã đi qua các quy trình làm việc thiết yếu nhất của Git: từ việc khởi tạo repository (init, clone), chu trình làm việc hàng ngày (add, commit), xem lại lịch sử (log), sửa chữa sai lầm, cho đến việc cộng tác với người khác thông qua remotes.

Cách tốt nhất để thành thạo Git là thực hành. Hãy áp dụng những lệnh này vào dự án của bạn để xây dựng sự tự tin và thành thạo.
Link tham khảo: https://git-scm.com/book/en/v2












